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
> [email protected]
_______________________________________________
dtrace-discuss mailing list
[email protected]