Re: [DynInst_API:] How to use DyninstAPI to get thread/process call stack in case of a signal delivery


Date: Mon, 21 Apr 2014 17:47:10 +0000
From: "Legendre, Matthew P." <legendre1@xxxxxxxx>
Subject: Re: [DynInst_API:] How to use DyninstAPI to get thread/process call stack in case of a signal delivery
> -----Original Message-----
> From: Dyninst-api [mailto:dyninst-api-bounces@xxxxxxxxxxx] On Behalf Of Bill
> Williams
> Sent: Monday, April 21, 2014 10:31 AM
> To: JiangJie
> Cc: dyninst-api@xxxxxxxxxxx
> Subject: Re: [DynInst_API:] How to use DyninstAPI to get thread/process call
> stack in case of a signal delivery
> 
> On 04/21/2014 10:26 AM, JiangJie wrote:
> >
> >
> >  > Date: Mon, 21 Apr 2014 09:59:44 -0500
> >  > From: bill@xxxxxxxxxxx
> >  > To: yangtzj@xxxxxxxxxxx
> >  > CC: dyninst-api@xxxxxxxxxxx
> >  > Subject: Re: [DynInst_API:] How to use DyninstAPI to get
> > thread/process call stack in case of a signal delivery
> >  >
> >  > On 04/20/2014 09:02 AM, JiangJie wrote:
> >  > > Hi Ray,
> >  > >
> >  > > Yes it's possible to use ProcControlAPI directly to just intercept
> > signal.
> >  > >
> >  > > But my purpose is to collect the thread/process's callstack in case of
> >  > > a signal delivery,
> >  > > in order to know the context where the signal is raised.
> >  > > So I would like to call some API like BPatch_thread::getCallStack()
> >  > > in the registered event callback for ProcControl
> >  > >
> >  > > My question is, if I use
> >  > > ProcControlAPI->Process::registerEventCallback(EventType::Signal,
> >  > > my_signal_cb)
> >  > > to register a callback to intercept a signal, how to get the callstack
> >  > > in the registered callback?
> >  > > Is it possible to make use of BPatch_thread::getCallStack() in the
> >  > > registered signal callback?
> >  > > Or is there any other solution?
> >  > >
> >  > > Regards,
> >  > > Jie
> >  > >
> >  > Jie--
> >  >
> >  > I'm assuming that you just want a debugging call stack, and aren't
> >  > aiming for any sort of recovery.
> >  >
> >  > If you set DYNINST_DEBUG_CRASH in your environment, that should
> produce
> >  > a stack trace and register contents. You can set that variable to the
> >  > location of your preferred gdb, which will attempt to attach gdb to the
> >  > mutatee, or set it to "sleep", which will leave the mutator spinning in
> >  > a sleep loop. Any other value should produce a core file (if your
> >  > environment is set up to allow them).
> >  >
> >  > Hope that helps.
> >  >
> >  > --bw
> >  >
> >
> > Bill,
> >
> > Do you know STAT?
> > One main functionality of STAT is to collect call stacks from target
> > processes on demand,
> > on the base of DyninstAPI or StackWalkerAPI.
> > But STAT only supports on-demand collecting of call stacks.
> > Actually what I am planning to do is to extend STAT to support
> > event-based collection of call stacks,
> > e.g, to collect call stacks in case of SIGSEGV. Since I still want to
> > reuse STAT's infrastructure
> > ( especially for parallel jobs ), I would prefer to collect the target
> > mutatee's call stacks in the context of STAT Backend process and then
> > send it back to STAT front end.
> >
> > I haven't tried your solution yet and have no idea if it works for my
> > purpose.
> > But I think a signal handler callback is more intuitive for me.
> >
> Jie--
> 
> I do in fact know STAT, including its internals, a fair bit. And this
> should be a fairly obvious extension if you take a look at the STAT
> back-end code, as everything it's doing is with ProcControlAPI and
> Stackwalker directly. You'd simply want to register your signal handler
> callback with ProcControl, and have that callback trigger a stack walk
> with the back end's Walker.

There's a new release of STAT 2.1 that includes the initial version of DysectAPI support.  With DysectAPI you should be able to configure STAT to do a stackwalk on a signal.


And if you still want to roll your own, Bill suggested the correct approach.  More specifically:

1. Use StackwalkerAPI to attach to a process.  You'll get a Walker object
2. From a Walker, you can use getProcessState() to get a ProcDebug object.
3. A ProcDebug has a getProc() call that gets you a ProcControlAPI Process handle.
4. With ProcControlAPI you can register a callback that can trigger on a signal.  From that callback, you can use the Walker to take a Stackwalk.

You'd also need to modify the STAT source to coordinate a global stack walk upon a signal.    Right now STAT expects to take a stackwalk from every process when triggered.  It doesn't support taking a stackwalk from just a small subset of process that fault.

-Matt


[← Prev in Thread] Current Thread [Next in Thread→]