G Bulmer
2008-Mar-09 15:15 UTC
[dtrace-discuss] Help: OS X - stringof(copyin()) showing odd results
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);
}
James Milne
2008-Mar-09 17:12 UTC
[dtrace-discuss] Help: OS X - stringof(copyin()) showing odd results
Dtrace, AFAIK, only supports C strings. What you can do in your probes is convert the string into a C string by temporarily allocating some memory, copying your Erlang string into that, passing it to the probe, then deleting the C string memory. Yes, it''s not exactly efficient, but then this only happens when you have your probe enabled (if you use the _ENABLED macros to check if your probe point is enabled). I do this for our interpreter and it works fine. -- Kind regards, James Milne FilmLight Ltd. On 9 Mar 2008, at 15:15, G Bulmer wrote:> 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 > dtrace-discuss at opensolaris.org