Re: ptrace help

2007-12-09 Thread Shachar Shemesh

Adam Morrison wrote:



Yes, that worked. What I don't understand, however, is why it worked. 
While the man page for PTRACE_SYSCALL mentions that "addr" is ignored 
(implying that "data" isn't), it does not actually tell me what the 
content of data is.



For PTRACE_CONT, the man page says ``if data is non-zero and not SIGSTOP,
it  is  interpreted  as  a  signal  to  be  delivered to the child''.
It goes on to say that PTRACE_SYSCALL ``restarts  the  stopped child as
for PTRACE_CONT''.  Same for PTRACE_SINGLESTEP.
sus
  

Well, I still claim this is not exactly the friendliest of documents.

It's being traced, it's just not stopped.  exec() is a special case, as
documented: ``all subsequent calls to exec() by this process will cause
a SIGTRAP to be sent to it''.
  
Hmm, so I don't actually have to send myself a signal. I can just call 
exec, and that is guaranteed to stop my process. Works for me. Thanks.

If you want to catch system calls made before the exec() (like anything
that printf() you added does), you need to explicitly stop the process.
  
I think I know what I do before the exec. I sortof have the source for 
that :-)


That is not the horrid part, though. The horrid part is that, sooner of 
later, I'm going to have to support recursive debugging (i.e. - running 
a debugger where I'm ptracing both debugger and debugee). I'm sure I'll 
fell like crying when that happens :-(


Shachar

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: ptrace help

2007-12-09 Thread Adam Morrison
On Sun, Dec 09, 2007 at 07:59:59AM +0200, Shachar Shemesh wrote:

> >You are leaving out the last two arguments of ptrace() in the parent,
> The man page says I'm allowed to do so in case the other arguments are 
> not used.

But they are.

> > so
> >they take garbage values, causing an unknown signal to be sent to the
> >child.  Try it with 
> >
> > ptrace(PTRACE_SYSCALL, ret, 0, 0);
> >  
> Yes, that worked. What I don't understand, however, is why it worked. 
> While the man page for PTRACE_SYSCALL mentions that "addr" is ignored 
> (implying that "data" isn't), it does not actually tell me what the 
> content of data is.

For PTRACE_CONT, the man page says ``if data is non-zero and not SIGSTOP,
it  is  interpreted  as  a  signal  to  be  delivered to the child''.
It goes on to say that PTRACE_SYSCALL ``restarts  the  stopped child as
for PTRACE_CONT''.  Same for PTRACE_SINGLESTEP.

> When I tried writing "5" into data (i.e. - SIGTRAP) the next "wait" 
> returns with "Process exited with signal 5". It seems to be that when 
> the data field is non-empty, the signal number I write there is actually 
> delivered to the debugged process, but that is not documented in the 
> manual, as far as I could see.

See above.

> >That's because ptrace(PTRACE_TRACEME) does not stop the process.  If you
> >want it stopped immediately after the ptrace() call, you need to do it
> >yourself; e.g. send yourself a STOP signal.
> >  
> Is it being traced in any other reliable point? I now understand that 
> the point it stops is when the first signal is being received, but I'm 
> not sure whether "exec" guarantees that such a signal actually happens, 
> or whether I should really send one myself.

It's being traced, it's just not stopped.  exec() is a special case, as
documented: ``all subsequent calls to exec() by this process will cause
a SIGTRAP to be sent to it''.

If you want to catch system calls made before the exec() (like anything
that printf() you added does), you need to explicitly stop the process.


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: ptrace help

2007-12-08 Thread Shachar Shemesh

Adam Morrison wrote:


First of all, thanks, I got it working. I still don't understand why 
it's working.



You are leaving out the last two arguments of ptrace() in the parent,
The man page says I'm allowed to do so in case the other arguments are 
not used.

 so
they take garbage values, causing an unknown signal to be sent to the
child.  Try it with 


ptrace(PTRACE_SYSCALL, ret, 0, 0);
  
Yes, that worked. What I don't understand, however, is why it worked. 
While the man page for PTRACE_SYSCALL mentions that "addr" is ignored 
(implying that "data" isn't), it does not actually tell me what the 
content of data is.


When I tried writing "5" into data (i.e. - SIGTRAP) the next "wait" 
returns with "Process exited with signal 5". It seems to be that when 
the data field is non-empty, the signal number I write there is actually 
delivered to the debugged process, but that is not documented in the 
manual, as far as I could see.
  
Also of interest is that when I added the "printf" after the TRACEME, 
that printf gets executed (output goes to the console) before the first 
wait at the parent. In other words, the program is not being traced 
immediately.



That's because ptrace(PTRACE_TRACEME) does not stop the process.  If you
want it stopped immediately after the ptrace() call, you need to do it
yourself; e.g. send yourself a STOP signal.
  
Is it being traced in any other reliable point? I now understand that 
the point it stops is when the first signal is being received, but I'm 
not sure whether "exec" guarantees that such a signal actually happens, 
or whether I should really send one myself.


In any case, thanks again. You allowed me to pass the initial hurdle.

Shachar

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: ptrace help

2007-12-08 Thread Adam Morrison
On Sat, Dec 08, 2007 at 11:50:17PM +0200, Shachar Shemesh wrote:

> In the parent I do:
> 
>pid_t ret=waitpid(first_child, &status, 0);
> 
>ptrace( PTRACE_DETACH, ret );
> 
>ret=waitpid(first_child, &status, 0);
> 
> 
> Instead of DETACH I already tried PTRACE_CONT and PTRACE_SYSCALL.
> 
> 
> What I expect to happen is that the child should run what I tell it to 
> (I tell it to run "echo hi"), and be caught with both waits. Instead, 
> the first wait catches a signal 5 (TRAP, as expected), but the second 
> wait hangs forever AND THE ECHO DOES NOT RUN!!

You are leaving out the last two arguments of ptrace() in the parent, so
they take garbage values, causing an unknown signal to be sent to the
child.  Try it with 

ptrace(PTRACE_SYSCALL, ret, 0, 0);

> Also of interest is that when I added the "printf" after the TRACEME, 
> that printf gets executed (output goes to the console) before the first 
> wait at the parent. In other words, the program is not being traced 
> immediately.

That's because ptrace(PTRACE_TRACEME) does not stop the process.  If you
want it stopped immediately after the ptrace() call, you need to do it
yourself; e.g. send yourself a STOP signal.


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: ptrace help

2007-12-08 Thread Omer Zak
On Sat, 2007-12-08 at 23:50 +0200, Shachar Shemesh wrote:
> Hi all,
> 
> 
> I need help trying to wrap my head around ptrace. I'm trying to create 
> the most basic of programs:
> 
> 
> in the child process (right after the fork) I do:

[... snipped ...]

Shachar,
You provided us with a description of the expected and actual behaviors.
However, it would be better if you provided us with the full source code
of a sample program involving ptrace, as written by you.

>From skimming man ptrace, it appears that the subprocess is stopped by
ptrace actions and needs to be restarted.  Overall the ptrace command
set seems to be designed around the metaphor of an human-controlled
debugger.

  --- Omer

-- 
One does not make peace with enemies.  One makes peace with former
enemies.
My own blog is at http://www.zak.co.il/tddpirate/

My opinions, as expressed in this E-mail message, are mine alone.
They do not represent the official policy of any organization with which
I may be affiliated in any way.
WARNING TO SPAMMERS:  at http://www.zak.co.il/spamwarning.html


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



ptrace help

2007-12-08 Thread Shachar Shemesh

Hi all,


I need help trying to wrap my head around ptrace. I'm trying to create 
the most basic of programs:



in the child process (right after the fork) I do:

   ptrace(PTRACE_TRACEME);

   printf("Being traced\n");

   execve(argv[opt_offset], argv+opt_offset, env);
   exit(1);

In the parent I do:

   pid_t ret=waitpid(first_child, &status, 0);

   ptrace( PTRACE_DETACH, ret );

   ret=waitpid(first_child, &status, 0);


Instead of DETACH I already tried PTRACE_CONT and PTRACE_SYSCALL.


What I expect to happen is that the child should run what I tell it to 
(I tell it to run "echo hi"), and be caught with both waits. Instead, 
the first wait catches a signal 5 (TRAP, as expected), but the second 
wait hangs forever AND THE ECHO DOES NOT RUN!!



Also of interest is that when I added the "printf" after the TRACEME, 
that printf gets executed (output goes to the console) before the first 
wait at the parent. In other words, the program is not being traced 
immediately.



I need help figuring out what the !*(#()@! is going on here.


Thanks,

Shachar


P.s.

Please do not send me to read strace's source code for reference. 
Strace's source code is so twisted I cannot understand how ANYONE can 
figure out what's going on there, and that's before mentioning the #ifdefs



Sh.


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]