UNW_INIT_LOCAL(3libunwind)

✨ UNW_INIT_LOCAL ✨

okay bestie, welcome to unw_init_local from the 3libunwind programming library manual πŸ’– this is the one that gets your cursor ready for local unwinding, and honestly? it's giving main character energy for your whole backtrace journey πŸ¦‹


🌸 NAME 🌸

unw_init_local β€” initialize cursor for local unwinding ✨


πŸŽ€ SYNOPSIS πŸŽ€

#include <libunwind.h>

int unw_init_local(unw_cursor_t *c, unw_context_t *ctxt);
int unw_init_local2(unw_cursor_t *c, unw_context_t *ctxt, int flag);

πŸ’… DESCRIPTION πŸ’…

so the way that unw_init_local() works is: it initializes the unwind cursor that c points to, using the machine state sitting in the context structure that ctxt points to. periodt. so basically, the machine state at ctxt is what tells libunwind which stack frame is the initial one, i.e. where the unwinding actually starts πŸ‘‘

and that machine state? it's expected to be the one you got from calling unw_getcontext(). lowkey important detail here: the instruction pointer may point to the instruction after the last instruction of a function, and libunwind will back-up the instruction pointer before it begins a walk up the call stack. so it handles that for you, no stress 🫢

⚠️ also the machine state must remain valid for the entire duration that the cursor c is in use. no letting it wander off, bestie, that's a vibe check fail 😭

okay so here's the thing about scope: unw_init_local() can be used only for unwinding in the address space of the current process β€” that's what we mean by local unwinding πŸ’– for literally all other cases, you have to use unw_init_remote() instead. but!! the tea is that unwind performance may be better when you use unw_init_local() πŸ”₯ and also, unw_init_local() is available even when UNW_LOCAL_ONLY has been defined before including <libunwind.h>, whereas unw_init_remote() is not. so yeah, that's a whole thing πŸ‘‘

and if you already know the unw_context_t is a signal frame β€” like from the third argument in a sigaction handler on linux β€” then you should use unw_init_local2() instead, for correct initialization on some platforms, passing the UNW_INIT_SIGNAL_FRAME flag. slay πŸŽ€


⭐ RETURN VALUE ⭐

on successful completion, unw_init_local() returns 0 ✨ otherwise the negative value of one of the error codes below gets returned. so a negative number = not the vibe, check the list πŸ‘‡


🌈 THREAD AND SIGNAL SAFETY 🌈

unw_init_local() is thread safe as well as safe to use from a signal handler. iconic behaviour, honestly πŸ’œ


πŸ’€ ERRORS πŸ’€

  • UNW_EINVAL β€” unw_init_local() was called in a version of libunwind which supports remote unwinding only (this normally happens when calling unw_init_local() for a cross-platform version of libunwind). so like, wrong libunwind, bestie 😭
  • UNW_EUNSPEC β€” an unspecified error occurred. vague, mysterious, not it πŸ™ˆ
  • UNW_EBADREG β€” a register needed by unw_init_local() wasn't accessible. the register ghosted you πŸ’€

πŸ¦‹ SEE ALSO πŸ¦‹


πŸ‘‘ AUTHOR πŸ‘‘

David Mosberger-Tang Email: dmosberger@gmail.com WWW: http://www.nongnu.org/libunwind/


and that's the whole page, bestie πŸ’– written up as part of the Programming Library docs, dated 29 August 2023, filed under UNW_INIT_LOCAL(3libunwind) β€” go forth and unwind locally, you absolute legend 🌸🫢✨