This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: MAXSTRINGLEN applied to printf()?
Sorry...didn't want to spam a lot of code and output.
So, for example, I get a long output that contains this fragment:
... ,"localhost.localdomain"localhost.localdomain_2012-8-8-23-47-30.bz2", ...
...generated by the following probe (I've set string lengths to be 2048). The thing to notice is that any string concatenation I do should always involve the addition of a pair of quotes, so I should never be able to get an output that involves an odd number of quotes (as per above). So either I'm somehow getting intermingled output (I don't think I am...the rest of the output looks perfectly fine), or somehow a string is getting silently truncated somewhere (fyi, all the filenames it's listing are of the form localhost.localdomain_2012-8-8-23-47-30.bz2).
Any theories appreciated.
Thanks,
Nick
-----
probe syscall.getdents.return {
if ((execname() != "stap") && !is_fd_blacklisted(pid(), $fd)) {
printf("{ \"arglist\":")
arglist = "[ "
if ($return > 0) {
total_entries = 0
dirent = $dirent
total_bytes = 0
current_bytes = 0
while (total_bytes < $return) {
if (dirent == 0) {
break
}
nextarg = clean_string(user_string_warn(@cast(dirent, "struct linux_dirent")->d_name))
len = @cast(dirent, "struct linux_dirent")->d_reclen
formatlen = strlen(nextarg) + 2
dirent += len
total_bytes += len
total_entries += 1
if (total_entries < 256) {
if (current_bytes + formatlen > 2048) {
printf("%s", arglist)
arglist = ""
current_bytes = 0
}
arglist .= "\"".nextarg."\""
current_bytes += formatlen
if (total_bytes < $return) {
arglist .= ","
}
}
}
}
printf("%s],", arglist)
# arglist = substr(arglist, 0, strlen(arglist)-1)."]"
# outstr = "{ "
# outstr .= "\"arglist\": "
# outstr .= arglist.","
outstr .= "\"count\": "
outstr .= sprintf("%u", $count).","
outstr .= "\"execname\": \""
outstr .= clean_string(execname())."\","
outstr .= "\"fd\": "
outstr .= sprintf("%d", $fd).","
outstr .= "\"op\": \""
outstr .= clean_string("GETDENTS")."\","
outstr .= "\"pid\": "
outstr .= sprintf("%d", pid()).","
outstr .= "\"ppid\": "
outstr .= sprintf("%d", ppid()).","
outstr .= "\"return\": "
outstr .= sprintf("%d", $return).","
outstr .= "\"timestamp\": "
outstr .= sprintf("%d", gettimeofday_ms()).","
outstr .= "\"total_bytes\": "
outstr .= sprintf("%u", total_bytes).","
outstr .= "\"total_entries\": "
outstr .= sprintf("%u", total_entries).","
outstr .= "\"uid\": "
outstr .= sprintf("%d", uid())."}\n"
printf("%s", outstr)
}
}
-----
On Aug 9, 2012, at 12:56 PM, Josh Stone <jistone@redhat.com> wrote:
> On 08/08/2012 09:01 PM, halcyonic@gmail.com wrote:
>> If I try to printf() more than MAXSTRINGLEN characters without
>> outputting a newline, does that mean I'm exceeding the string length
>> limit? I.e., is just a normal string serving as the printf buffer,
>> and all the normal rules about strings apply to it? (I was trying to
>> get around the string length limits by issuing multiple printf()'s,
>> but that seems to be backfiring...)
>
> As long as you're not using intermediate strings, MAXSTRINGLEN should
> not limit you. There is a different limit STP_BUFFER_SIZE which is 8192
> bytes, but I believe even that is for each individual printf call.
>
> As before, examples of what you're trying and the result would be helpful.
>
>
> Josh