I'm adding probes to Erlang, and trying to print the chars passed
through.
The chars are not '\0' terminated. They are stored as an unsigned
char* and an int length.
the probe looks like this:
provider erlang {
...
probe dtrace(int Pid, unsigned char* binary_data, int
binary_data_size);
};
I use stringof(copyin(arg1, arg2)) as advised on page 348, Solaris
Dynamic Tracing Guide (January 2005).
It looks like the scratch buffer used by copyin() is not cleared;
dtrace printf gives remnants of a previous action's copyin() string.
I've tried adding a parameter to stringof() [e.g.
stringof(copyin(arg1,arg2), arg2) ] to only consume the valid bytes,
but I get an error from dtrace(1M) when the probe triggers:
dtrace: error on enabled probe ID 2 (ID 21468:
erlang21805:beam.smp:dtrace_1:dtrace): invalid address (0x3) in action
#4 at DIF offset 60
Can anyone help? What should I do? Do I need to use alloca() in every
action that I want to look at the characters, or have I missed
something about stringof()?
G Bulmer
Here's the gory detail ...
When I run the DTrace script, I get remnants of previous strings
appearing in the printf() output:
dtrace: script 'test1.d' matched 3 probes
CPU ID FUNCTION:NAME
0 21543 dtrace_1:dtrace erlang* dtrace:
pid=<0.31.0> (arg0=0x1f3) arg1='an_atom' (size:7)
0 21543 dtrace_1:dtrace erlang* dtrace:
pid=<0.31.0> (arg0=0x1f3) arg1='He' (size:2)
0 21543 dtrace_1:dtrace erlang* dtrace: pid=<0.31.0>
(arg0=0x1f3) arg1='an_atom' (size:7)
1 21543 dtrace_1:dtrace erlang* dtrace: pid=<0.31.0>
(arg0=0x1f3) arg1='another Binary' (size:14)
0 21543 dtrace_1:dtrace erlang* dtrace: pid=<0.31.0>
(arg0=0x1f3) arg1='He_atom' (size:2)
(blank lines deleted)
The last line prints 'He_atom', but there were only two bytes (size:2).
Here's the interactive Erlang session, you can see that the two
character binary (byte sequence) "He" is printed above in the dtrace
script, but it overwrites 'an_atom' to give 'He_atom', the (size:2) in
the dtrace output confirms that the correct byte count is received in
the dtrace action.
1> A = an_atom.
an_atom
2> C = <<"another Binary">>.
<<"another Binary">>
3> E = ''.
''
4> F = <<>>.
<<>>
5> erlang:dtrace(A).
an_atom
6> erlang:dtrace(C).
<<"another Binary">>
7> erlang:dtrace(E).
''
8> erlang:dtrace(F).
<<>>
9> erlang:dtrace(<<>>).
<<>>
10> erlang:dtrace(<<"He">>).
<<"He">>
Here's the dtrace script:
#define PID_NODE(ePid) ((ePid >> 19) & 0x1fff)
#define PID_LPID(ePid) ((ePid >> 4) & 0x7ffff)
#define PID_SER(ePid) ((ePid >>2) & 0x03)
erlang*:::dtrace
{
printf("erlang* dtrace:");
printf(" pid=<%d.%d.%d> (arg0=0x%x)", PID_NODE(arg0),
PID_LPID(arg0), PID_SER(arg0), arg0);
s = stringof(copyin(arg1, arg2));
printf(" arg1='%s' (size:%d)\n", s, arg2);
}
_______________________________________________
dtrace-discuss mailing list
[email protected]