linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* sigaction() handler question
@ 2003-03-01 15:34 Jan-Benedict Glaw
  2003-03-01 19:42 ` Glynn Clements
  0 siblings, 1 reply; 2+ messages in thread
From: Jan-Benedict Glaw @ 2003-03-01 15:34 UTC (permalink / raw)
  To: linux-c-programming

[-- Attachment #1: Type: text/plain, Size: 1312 bytes --]

Hi!

I've added a handler function for a SEGSEGV signal. I'm now that far
that I do know where (from the third void * parameter to the handling
function) to find the entry to the stack. So, for i386, I now can climb
down the stack printing out the stack trace.

Unfortunately, the void * (it is mentioned to be a (ucontext_t *) in
reality...) isn't *that* big help. The stack (with "stack" I here mean
that pointer which points to some stack frame's next stack pointer) is
(on i386) 11*sizeof(long) away. To the worse, I've not really found
helpful manpages or example sources on how to "really" walk down the
stack (from a segsegv handler function). I think this could really help
in debugging for production applications esp. on slow, small
memory-sized system where you otherwise can't shoot down some really
rarely SEGViolations which (of course:-) you can't reproduce in the labs
and (because of it being a multi-threaded application) you won't even
get a core from it...

MfG, JBG

-- 
   Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481
   "Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg
    fuer einen Freien Staat voll Freier Bürger" | im Internet! |   im Irak!
      ret = do_actions((curr | FREE_SPEECH) & ~(IRAQ_WAR_2 | DRM | TCPA));

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: sigaction() handler question
  2003-03-01 15:34 sigaction() handler question Jan-Benedict Glaw
@ 2003-03-01 19:42 ` Glynn Clements
  0 siblings, 0 replies; 2+ messages in thread
From: Glynn Clements @ 2003-03-01 19:42 UTC (permalink / raw)
  To: Jan-Benedict Glaw; +Cc: linux-c-programming


Jan-Benedict Glaw wrote:

> I've added a handler function for a SEGSEGV signal. I'm now that far
> that I do know where (from the third void * parameter to the handling
> function) to find the entry to the stack. So, for i386, I now can climb
> down the stack printing out the stack trace.
> 
> Unfortunately, the void * (it is mentioned to be a (ucontext_t *) in
> reality...) isn't *that* big help. The stack (with "stack" I here mean
> that pointer which points to some stack frame's next stack pointer) is
> (on i386) 11*sizeof(long) away.

11? Looking at sys/ucontext.h, that would be:

	((ucontext_t *)ptr)->uc_mcontext.gregs[ESP];

whereas you probably want:

	((ucontext_t *)ptr)->uc_mcontext.gregs[EBP];

which is the previous entry, i.e. ((int *)ptr)[10].

> To the worse, I've not really found
> helpful manpages or example sources on how to "really" walk down the
> stack (from a segsegv handler function).

Each stack frame is of the form:

	...
	<local variables>
EBP->	saved EBP
	saved EIP
	<arguments>
	...

where memory addresses increase downwards.

The saved EBP for the topmost stack frame is NULL.

So, walking the linked list of stack frames should be a matter of:

static void handler(int sig, siginfo_t *si, void *ptr)
{
	ucontext_t *uc = ptr;
	void **ebp;
	for (ebp = (void **) uc->uc_mcontext.gregs[EBP]; ebp; ebp = ebp[0])
	{
		void *saved_eip = ebp[1];
		/* arguments are at &ebp[2] and above */
		/* local variables are below ebp */
	}
	...
}

A couple of caveats:

1. If any of the functions in the call chain were compiled with
-fomit-frame-pointer, it won't generate usable stack frames, and the
above code will probably crash. To prevent this, you would need to
"validate" each stack frame by checking that the saved EBP and EIP
values are plausible.

2. If SIGSEGV is raised, arbitrary portions of the process' memory
could be trashed. Don't expect that library functions will work
correctly (or at all), or that static variables will contain correct
values.

-- 
Glynn Clements <glynn.clements@virgin.net>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-03-01 19:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-03-01 15:34 sigaction() handler question Jan-Benedict Glaw
2003-03-01 19:42 ` Glynn Clements

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).