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