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