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