libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libunwind] unwinding through dynamically modified code?


From: David Mosberger
Subject: Re: [libunwind] unwinding through dynamically modified code?
Date: Mon, 15 Mar 2004 11:58:13 -0800

>>>>> On Mon, 15 Mar 2004 13:21:56 -0600 (CST), Todd L Miller <address@hidden> 
>>>>> said:

  Todd>         Suppose I insert a jump in a remote process's code,
  Todd> and that the jump leads to code which (after doing state
  Todd> preservation) jumps to a second snippet of code that makes a
  Todd> function call.  Sometime during that function call, probably
  Todd> while one of it the calls it makes is executing, I'd like to
  Todd> use libunwind to walk the stack past the jump I inserted.

  Todd>         It should be possible to construct a unw_dyn_info
  Todd> structure with information appropriate for the state
  Todd> preservation.  If I read the libunwind-dynamic.h header
  Todd> correctly, I should even be able to construct a linked list of
  Todd> these structures with disjoint address ranges to cover the
  Todd> second (and additional) snippets.  However, it's not clear to
  Todd> me that this will work: how do I tell libunwind to use the
  Todd> unwind information the function into which I inserted the
  Todd> jump?

You'd need to generate the dynamic unwind info in the remote process.
In my opinion, that's really the only proper way of doing it, because
the process must be "self-contained" (e.g., suppose the process
crashes after the process was modified and dumps core).

The bad news is that there is no existing sample code to show how to
do this (you're very much on the cutting edge here...).  The basic
idea is:

 1) reserve some memory in the target's address space
 2) construct the dynamic unwind info in the target addres space (e.g.,
    using ptrace(POKE_DATA, ...)
 3) link the new info into the target's dynamic unwind info list

Step 3 basically needs to do the same thing as _U_dyn_register() in
dyn-register.c.  This is a straight-forward singly-linked list
insertion, along with incrementing a version number
(_U_dyn_info_list.generation).  The only tricky part is if the target
process itself was in the middle of executing _U_dyn_register().  I
don't have a good solution for that at the moment.  Hopefully, we may
either find a lock-free way of doing _U_dyn_register() and
_U_dyn_cancel() or find some other protocol which would make it easier
for remote and local modifications to the dynamic-unwind-info to be
done in a race-free manner.

In any case, I think step 3 would deserve explicit support from
libunwind.  Perhaps something along the lines of a
unw_remote_dyn_register() where you specify the remote address of the
unw_dyn_info_t that should be linked into the target's
dynamic-unwind-info list.

        --david


reply via email to

[Prev in Thread] Current Thread [Next in Thread]