Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Jun 2001 02:25:08 -0400 (EDT)
From:      Daniel Eischen <eischen@vigrid.com>
To:        Valentin Nechayev <netch@iv.nn.kiev.ua>
Cc:        Louis-Philippe Gagnon <louisphilippe@macadamian.com>, freebsd-hackers@FreeBSD.ORG
Subject:   Re: pthread/longjmp/signal problem
Message-ID:  <Pine.SUN.3.91.1010625022147.6848A-100000@pcnet1.pcnet.com>
In-Reply-To: <20010625090332.A416@iv.nn.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 25 Jun 2001, Valentin Nechayev wrote:
>  Thu, Jun 21, 2001 at 10:55:10, louisphilippe (Louis-Philippe Gagnon) wrote about "pthread/longjmp/signal problem": 
> 
> > I've been trying to implement a IsBadReadPtr-style function in FreeBSD by
> > using signal handlers and longjmp/setjmp. It seemed to work as expected,
> > until I started using the -pthread option to gcc (thus linking against
> > libc_r). Now the function only works on the first call; subsequent calls
> > hang on the segmentation fault.
> 
> libc_r provides its own signal handling. sigaction() called by you
> is libc_r function which replaces your handler with its own and record
> your handler in its private data. On SIGSEGV, not your handler is called,
> but libc_r's:
> 
>   1370 lou      CALL  write(0x2,0xbfbff050,0xf)
>   1370 lou      GIO   fd 2 wrote 15 bytes
>        "before sigsegv
>        "
>   1370 lou      RET   write 15/0xf
>   1370 lou      PSIG  SIGSEGV caught handler=0x28072444 mask=0x0 code=0x0
>   1370 lou      CALL  sigprocmask(0x3,0x2807f0d8,0)
>   1370 lou      RET   sigprocmask 0
>   1370 lou      CALL  sigaltstack(0x28084aa0,0)
>   1370 lou      RET   sigaltstack 0
>   1370 lou      CALL  write(0x2,0xbfbfecf0,0xb)
>   1370 lou      GIO   fd 2 wrote 11 bytes
>        "in handler
>        "
>   1370 lou      RET   write 11/0xb
>   1370 lou      CALL  write(0x2,0xbfbff050,0x13)
>   1370 lou      GIO   fd 2 wrote 19 bytes
>        "longjmp successful
>        "
> 
> Your handler doesn't contain sigaltstack() call, does it? ;)
> 
> With longjmp, you destruct libc_r's internals because it can't do
> needed cleanups.

This is suppose to work as long as you are jumping to the current
threads stack.

> > Basically, the app registers a signal handler for SIGSEGV, initializes a
> > setjmp() buffer, then provokes a segmentation fault. The expected behavior
> > is for the signal handler to get called, which will longjmp() bask to main,
> > where another segmentation fault will occur, which repeats the process.
> > After 10 times, the if(y>=10) condition makes the program exit.
> 
> You cannot do longjmp() out from signal handler with libc_r.

You are suppose to be able to do this.  I will look at it when I
get the chance.

> If you nevertheless want to implement your function, you should
> 
> 1) Block all signals except SIGSERV via sigprocmask();
> especially block SIGVTALRM (libc_r on-timer switching signal)
> 2) Call __sys_sigaction() instead of sigaction(), to call real syscall
> and not libc_r wrapper. Don't forget to restore previous handler
> with the same call after restoring.

__sys_sigaction is only in current, -stable still has 
_thread_sys_sigaction.  But you don't really want to know
that -- it is suppose to work correctly.

> 3) Really call test and handle return from signal handler.
> 4) Restore kernel's sigaction and sigprocmask.
> 
> And this way uses undocumented implementation details of libc_r
> and can stop to work in any moment.
> 
> > Out of curiosity, I tried installing the linuxthreads port and using that :
> > this actually works, but I may not be able to use it as a permanent
> > solution.
> 
> linuxthreads uses another approach. But it also deals with signal handlers.

-- 
Dan Eischen

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.SUN.3.91.1010625022147.6848A-100000>