On 02/05/17 09:52 AM, Roman Tsisyk wrote:
> Hi!
> 
> My application uses lightweight user-space threads (fibers a.k.a coroutines). 
> Each fiber has its own stack and a saved frame pointer to the last executed 
> function, retrieved from `__builtin_frame_address(0)`. I want to create 
> backtraces for all fibers using saved frame pointers. 
> 
> Currently this feature is implemented using libbfd[1], which is non-portable 
> and just terrible. I want to switch to libunwind, but I don't understand how 
> to wrap unw_create_addr_space()/unw_init_remote() for my case. Could you 
> please provide some examples?

Since you're in the same process, this isn't actually remote
unwinding.  Unlike frame chain unwinders, libunwind needs most of the
register context also.

A couple ways to do this:

1) If your fibers are stored in getcontext() format, you can just initialize 
the context using that (per man unw_getcontext):

getcontext(&yourfibercontext);

unw_context_t c;

memcpy(&c, yourfibercontext, sizeof(unw_context_t));

2) You can just call unw_getcontext(&c) before you switch fiber contexts.

3) You *can* play with remote if you want.  You probably only need to change 
access_reg if you are storing the registers in a different format:

unw_accessors_t* acc = unw_get_accessors(unw_local_addr_space);
unw_accessors_t nacc;
memcpy(&nacc, acc, sizeof(unw_accessors_t));
nacc.access_reg = access_reg;

as = unw_create_addr_space(&nacc, 0);
ret = unw_init_remote (&c, as, &c);

This should *mostly* work.  I think.  Some of the accessors assume
things about the last unw_init_remote arg which you may have to play
with, but I think those are mostly access_reg and access_fpreg, which
you would want to implement yourself anyway.

Hope this helps.



_______________________________________________
Libunwind-devel mailing list
Libunwind-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/libunwind-devel

Reply via email to