> On Oct 23, 2014, at 6:11 AM, Nan Xiao via dtrace-discuss
> <[email protected]> wrote:
>
> I am using DTrace to debug a signal related 32-bit program on Solaris
> 10(64-bit).
>
> The source code of program is:
>
> #include <stdio.h>
> #include <signal.h>
>
> struct sigaction act;
> void handler(int a, siginfo_t *b, void *c)
> {
> }
> int main(void)
> {
> act.sa_flags = 1;
> act.sa_sigaction = handler;
> sigemptyset(&act.sa_mask);
> sigaction(SIGINT, &act, NULL);
> printf("The address is 0x%x, sizeof(struct sigaction)
> is %d\n", &act, sizeof(struct sigaction));
> return 0;
> }
>
> The DTrace script is :
>
> #!/usr/sbin/dtrace -Cs -32
>
> #include <signal.h>
>
> sigaction:entry
> /pid == $target/
> {
> this->sig = (struct sigaction *)copyin(arg1,
> sizeof(struct sigaction));
> printf("pid is %d: arg0 is %d, arg1 is 0x%x, sa_flags
> is %d, sa_sigaction is 0x%x\n",
> pid,
> arg0,
> arg1,
>
> (int)(this->sig->sa_flags),
>
> (int)(this->sig->sa_sigaction));
> printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
> *((char*)this->sig),
> *(((char*)this->sig) + 1), *(((char*)this->sig) + 2), *(((char*)this->sig) +
> 3),
> *(((char*)this->sig) +
> 4), *(((char*)this->sig) + 5), *(((char*)this->sig) + 6),
> *(((char*)this->sig) + 7));
> printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
> *(((char*)this->sig) +
> 8), *(((char*)this->sig) + 9), *(((char*)this->sig) + 10),
> *(((char*)this->sig) + 11),
> *(((char*)this->sig) +
> 12), *(((char*)this->sig) + 13), *(((char*)this->sig) + 14),
> *(((char*)this->sig) + 15));
> printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
> *(((char*)this->sig) +
> 16), *(((char*)this->sig) + 17), *(((char*)this->sig) + 18),
> *(((char*)this->sig) + 19),
> *(((char*)this->sig) +
> 20), *(((char*)this->sig) + 21), *(((char*)this->sig) + 22),
> *(((char*)this->sig) + 23));
> printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
> *(((char*)this->sig) +
> 24), *(((char*)this->sig) + 25), *(((char*)this->sig) + 26),
> *(((char*)this->sig) + 27),
> *(((char*)this->sig) +
> 28), *(((char*)this->sig) + 29), *(((char*)this->sig) + 30),
> *(((char*)this->sig) + 31));
> ustack();
> }
>
> The execute the command: "./trace.d -c ./a", and the output is:
> bash-3.2# ./trace.d -c ./a
> dtrace: script './trace.d' matched 6 probes
> The address is 0x8060ea0, sizeof(struct sigaction) is 32
> dtrace: pid 23721 has exited
> CPU ID FUNCTION:NAME
> 2 58241 sigaction:entry pid is 23721: arg0 is 2,
> arg1 is 0x8047760, sa_flags is 1, sa_sigaction is 0xffbffeff
> 0x1 0x0 0x0 0x0 0x4 0xe9 0xed 0xfe
> 0xff 0xfe 0xbf 0xff 0xff 0xff 0x0 0x0
> 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
> 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
>
> libc.so.1`__sigaction+0x15
> a`main+0x51
> a`_start+0x80
>
> The C program output the address of act is 0x8060ea0, but DTrace
> outputs the address of act is 0x8047760. Furthermore, the data in 0x8047760
> isn't same as C program has set.
>
> Could anyone give any help or clues on this issue? Thanks very much in
> advance!
>
The reason the addresses do not line up is because the probes (you
have 6 probes that match, I just have 2) are at the syscall/kernel
level and by that point the sigaction structure has been copied.
rpz@oi2:~/tmp$ sudo dtrace -ln '::sigaction:entry'
ID PROVIDER MODULE FUNCTION NAME
12148 syscall sigaction entry
33973 fbt genunix sigaction entry
Here is the libc side of sigaction copying the sigaction struct:
https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/threads/sigaction.c#L383
Then it is copied again in the syscall:
https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/syscall/sigaction.c#L63
If you want to trace the libc sigaction then you need to use the pid
provider (http://dtrace.org/guide/chapter30.html). In fact, this
entire DTrace script can be greatly simplified to the following:
#!/usr/sbin/dtrace -s
pid$target::sigaction:entry
{
this->act = ((struct sigaction *)copyin(arg1, sizeof(struct
sigaction)));
printf("act addr: 0x%p, flags: %d, sigaction: 0x%p\n",
arg1,
this->act->sa_flags,
this->act->_funcptr._sigaction);
trace(*this->act);
print(*this->act);
}
The 'trace' function does what you were doing by hand, printing out
the bytes of the data structure. I added the 'print' function for fun
to show how awesome it is, it has knowledge of the types and prints
them out in a human friendly way. Since you are on Solaris I'm pretty
sure you don't have the print function but hopefully you have trace.
I ran my example on Illumos/OI 151a8.
rpz@oi2:~/tmp$ sudo ./contents.d -c './test'
dtrace: script './contents.d' matched 1 probe
The address is 0x4114c0, sizeof(struct sigaction) is 32
dtrace: pid 4317 has exited
CPU ID FUNCTION:NAME
7 74205 sigaction:entry act addr: 0x4114c0, flags: 1,
sigaction: 0x400f98
0 1 2 3 4 5 6 7 8 9 a b c d e f
0123456789abcdef
0: 01 00 00 00 00 00 00 00 98 0f 40 00 00 00 00 00
..........@.....
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
................
struct sigaction {
int sa_flags = 0x1
union _funcptr = {
int (*)() _handler = 0x400f98
int (*)() _sigaction = 0x400f98
}
sigset_t sa_mask = {
unsigned [4] __sigbits = [ 0, 0, 0, 0 ]
}
}
-Z
-------------------------------------------
dtrace-discuss
Archives: https://www.listbox.com/member/archive/184261/=now
RSS Feed: https://www.listbox.com/member/archive/rss/184261/25769126-e243886f
Modify Your Subscription:
https://www.listbox.com/member/?member_id=25769126&id_secret=25769126-8d47a7b2
Powered by Listbox: http://www.listbox.com