tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Request for implementation of KERN_PROC_SIGTRAMP sysctl
Hi Jason,
For the purpose of supporting GCC stack unwinding, the __sigtramp_check_np
function would work as a solution.
Backporting to NetBSD-9 branch would definitely be nice as well.
Thanks,
John
On Wed, Oct 27, 2021 at 9:51 AM Jason Thorpe <thorpej%me.com@localhost> wrote:
>
> > On Oct 18, 2021, at 9:41 AM, John Marino (NetBSD) <netbsd%marino.st@localhost>
> wrote:
> >
> > yes, it sounds like a __in_signal_trampoline function would work for
> > the GCC unwind, and I would think it would work for GDB as well.
>
> Ok, I have implemented a new function with this signature:
>
> /*
> * __sigtramp_check_np --
> *
> * Non-portable function that checks if the specified program
> * counter value is within the signal return trampoline. Returns
> * the trampoline version numnber corresponding to what style of
> * trampoline it matches, or -1 if the program value is not within
> * the signal return trampoline.
> */
> int __sigtramp_check_np(void *pc);
>
> Usage would be like:
>
> /*
> * If you need access to “struct sigcontext” to perform the unwind, you
> must
> * define _LIBC before including <signal.h>.
> */
> #define _LIBC
> #include <signal.h>
>
> .
> .
> .
>
> int rv = __sigtramp_check_np((void *)context->return_address);
>
> if (rv == -1) {
> /* address was not within a signal return trampoline. */
> }
>
> if (rv == __SIGTRAMP_SIGCODE_VERSION) {
> /*
> * ultra-legacy — this will never be returned for modern
> binaries.
> * in fact, the current implementation of
> __sigtramp_check_np()
> * will never return it and there is no reason to add
> support for it.
> */
> }
>
> if (rv >= __SIGTRAMP_SIGCONTEXT_VERSION_MIN &&
> rv <= __SIGTRAMP_SIGCONTEXT_VERSION_MAX) {
> #ifdef __HAVE_STRUCT_SIGCONTEXT
> /* do sigcontext stuff, distinguishing between versions,
> as needed */
> #else
> /*
> * no sigcontext structure is available here, so none of
> these values
> * should have been returned.
> */
> #endif
> }
>
> if (rv >= __SIGTRAMP_SIGINFO_VERSION_MIN &&
> rv <= __SIGTRAMP_SIGINFO_VERSION_MAX) {
> /* do siginfo stuff, distinguishing between versions, as
> needed */
> }
>
> /*
> * Address was within a signal return trampoline, but it’s not a
> version
> * that this program knows how to decode so *shrug*.
> */
>
> For the most part, the MIN and MAX values will be the same (currently only
> the VAX has multiple versions of either kind of signal trampoline, and it’s
> for the “sigcontext” type).
>
> Again, to be clear, this can query the current process ONLY.
>
> Is this suitable for your needs? Looking at your GCC unwinder for FreeBSD
> (link in your original email), it seems it would work fine (that unwinder
> uses getpid() to pass to the sysctl).
>
> You would be able to test for the availability of __sigtramp_check_np() by
> testing for __SIGTRAMP_SIGCODE_VERSION being defined:
>
> #ifdef __SIGTRAMP_SIGCODE_VERSION
> /*
> * Code to check if we’re in a NetBSD signal trampoline.
> */
> ...
> #endif /* __SIGTRAMP_SIGCODE_VERSION */
>
> It’s not the prettiest API in the world, but you’re by definition diving
> into implementation details here, and the API does provide all the info
> needed to do the work.
>
> Any other comments? Christos?
>
> …and while there was a flurry of activity lately around this area, the
> minimal changes to support __sigtramp_check_np() are easily isolated and
> could be back ported to the netbsd-9 branch without much trouble.
>
> -- thorpej
>
>
Home |
Main Index |
Thread Index |
Old Index