Date: Mon, 25 Jun 2001 09:03:32 +0300 From: Valentin Nechayev <netch@iv.nn.kiev.ua> To: Louis-Philippe Gagnon <louisphilippe@macadamian.com> Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: pthread/longjmp/signal problem Message-ID: <20010625090332.A416@iv.nn.kiev.ua> In-Reply-To: <0db001c0fa62$2b567800$2964a8c0@macadamian.com>; from louisphilippe@macadamian.com on Thu, Jun 21, 2001 at 10:55:10AM -0400 References: <0db001c0fa62$2b567800$2964a8c0@macadamian.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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. > 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. 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. 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. /netch 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?20010625090332.A416>