www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - SegmentationFault exception throwing, request for feedback - segfault.d

reply derick_eddington nospam.dot.yahoo.dot.com writes:
I've made a Linux SIGSEGV signal handler which throws a SegmentationFault which
can be caught and used to get info about the segfault.  (The signal handler is
called on the stack which is why the throw works.)  I'm wondering about the
implications of this and how useful it could be.  I've attached it.

Since Linux dmd doesn't support -g yet I've been using it to help squash
segfaults.  SegmentationFault tells the type of segfault and the offending
address, and try-catching for it helps me narrow down where the segfault is
happening.

I'm hoping people more knowledgeable can tell me if there are bugs with my
implementation and reasons doing this might not be a good idea.




begin 0644 segfault.d
M<')I=F%T92!I;7!O<G0 <W1D+G-T<FEN9SL-"G!R:79A=&4 :6UP;W)T('-T
M9"YC+G-T9&QI8CL)+R\ 9F]R(%]E>&ET*&EN="D-"F1E8G5G*'-E9V9A=6QT





M871E. T*"0ES=&%T:6, 8VAA<EM=(&UA<&5R<E]M<V< /2`B=6YM87!P960 
M861D<F5S<R`P>"4P.' B.PT*"0ES=&%T:6, 8VAA<EM=(&%C8V5R<E]M<V< 
M/2`B=6YP97)M:71T960 86-C97-S(&]F(&%D9')E<W, ,' E,#AX(CL-" T*



M7VUS9RP 8V%S="AS:7IE7W0I:6YF;RYS:5]A9&1R*3L-" D)"65L<V4 :68H
M:6YF;RYS:5]C;V1E(#T
M=')I;F<N9F]R;6%T*&%C8V5R<E]M<V<L(&-A<W0H<VEZ95]T*6EN9F\N<VE?







M=&%L;%]S96=F875L=%]S:6=H86YD;&5R*"DB*3L-" T*"6%C="YS85]F;&%G
M<R!\/2!305]324=)3D9/.PT*"6%C="YS85]S:6=A8W1I;VX /2`F<V5G9F%U
M;'1?<VEG:&%N9&QE<CL-" T*"6EF("AS:6=A8W1I;VXH4TE'4T5'5BP )F%C


M<BAI;G0 <VEG+"!S:6=I;F9O7W0J(&EN9F\L('9O:60J('5C;VYT97AT*0T*

M9FQN*")S96=F875L=%]S:6=H86YD;&5R*"DB*3L-" T*"71H<F]W(&YE=R!3

M("AI;G0 <VEG;G5M+"!S=')U8W1?<VEG86-T:6]N*B!A8W0L('-T<G5C=%]S







M97)?="!S85]H86YD;&5R.PT*"0EV;VED(&9U;F-T:6]N*&EN="P <VEG:6YF

M;6%S:SL-" EU:6YT('-A7V9L86=S.PT*"79O:60 9G5N8W1I;VXH*2!S85]R
M97-T;W)E<CL-"GT-" T*86QI9VXH-"D <W1R=6-T('-I9VEN9F]?=`T*('L-



M<W1R=6-T('L-" D)"5]?<&ED7W0 <VE?<&ED.PT*"0D)7U]U:61?="!S:5]U

M<VE?;W9E<G)U;CL-" D)"7-I9W9A;%]T('-I7W-I9W9A;#L-" D)?0T*"0ES

M9#L-" D)"7-I9W9A;%]T('-I7W-I9W9A;#L-" D)?0T*"0ES=')U8W0 >PT*





M" T*+RH 1F]R('-O;64 <F5A<V]N+"!C875S:6YG(&$ <V5C;VYD('-E9V9A

M97( =&\ 8F4 8V%L;&5D(&%G86EN(&%N9"!T:')O=R!A;F]T:&5R(%-E9VUE
M;G1A=&EO;D9A=6QT.PT*"71H92!D969A=6QT(&AA;F1L97( =VAI8V  :VEL
M;', =&AE('!R;V-E<W, 9V5T<R!U<V5D+`T*"7-O('1H:7, =6YI='1E<W0 


M(&-U<G)E;G1L>2!D;V5S;B=T('-U<'!O<G0 +F]F9G-E=&]F(&9O<B!S;VUE


M)60 4T%?4TE'24Y&3STE9"P 4T5'5E]-05!%4E(])60 4T5'5E]!0T-%4E(]
M)60B+"!324=314=6+"!305]324=)3D9/+"!314=67TU!4$524BP 4T5'5E]!
M0T-%4E(I.PT*"0EW<FET969L;B B<VEZ96]F.B!S=')U8W1?<VEG86-T:6]N
M(#T
M*")S:7IE;V8Z('-I9VEN9F]?="`]("5D(BP <VEG:6YF;U]T+G-I>F5O9BD[

M="YS:7IE;V8I.PT*"0DO+W=R:71E9FQN*")O9F9S971O9CH <W1R=6-T7W-I
M9V%C=&EO;BYS85]S:6=A8W1I;VX /2`E9"(L('-T<G5C=%]S:6=A8W1I;VXN


M:6=A8W1I;VX /2`E9"(L(&]F9G-E=&]F*"9S82P )G-A+G-A7W-I9V%C=&EO
M;BDI.PT*"0EW<FET969L;B B;V9F<V5T;V8Z('-T<G5C=%]S:6=A8W1I;VXN
M<V%?9FQA9W, /2`E9"(L('-T<G5C=%]S:6=A8W1I;VXN<V%?9FQA9W,N;V9F
M<V5T;V8I.PT*"0EW<FET969L;B B;V9F<V5T;V8Z('-I9VEN9F]?="YS:5]C
M;V1E(#T
M=W)I=&5F;&XH(F]F9G-E=&]F.B!S:6=I;F9O7W0N<VE?861D<B`]("5D(BP 
M<VEG:6YF;U]T+G-I7V%D9'(N;V9F<V5T;V8I.PT*"0ES:6=I;F9O7W0 <VD[



M="!I="!C86X 8F4 8V%U9VAT(&ES(&EN('1H92!P<F5V:6]U<R!F=6YC=&EO
M;B!I;B!T:&4 <W1A8VL-" D)*&-A<W0H3V)J96-T*6-A<W0H=F]I9"HI,' S


M96YT871I;VY&875L="!S92D >PT*"0ED96)U9RAS96=F875L="D =W)I=&5F
M;&XH(G-E9V9A=6QT+G5N:71T97-T*"D 8V%U9VAT(&ET.B`E<R(L('-E*3L-
M" D)8V%U9VAT:70 /2!T<G5E.PT*"7T-" EA<W-E<G0 *&-A=6=H=&ET*3L-


M;B B<V$N<V%?<VEG86-T:6]N(#T]("9S96=F875L=%]S:6=H86YD;&5R(#H 
M)7,B+"!C87-T*&)O;VPI*'-A+G-A7W-I9V%C=&EO;B`]/2`F<V5G9F%U;'1?
M<VEG:&%N9&QE<BDI.PT*"0EW<FET969L;B B<V$N<V%?<VEG86-T:6]N(#T 
M)3`X>"(L(&-A<W0H<VEZ95]T*6-A<W0H=F]I9"HI<V$N<V%?<VEG86-T:6]N
M*3L-" D)=W)I=&5F;&XH(B9S96=F875L=%]S:6=H86YD;&5R(#T )3`X>"(L
M(&-A<W0H<VEZ95]T*6-A<W0H=F]I9"HI*"9S96=F875L=%]S:6=H86YD;&5R

M95]S96=F875L=" I.PT*"7T-" EC871C:"`H4V5G;65N=&%T:6]N1F%U;'0 
M<V4I('L-" D)9&5B=6<H<V5G9F%U;'0I('=R:71E9FQN*")S96=F875L="YU
M;FET=&5S=" I(&-A=6=H="!I=#H


`
end
Mar 25 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 26 Mar 2005 07:15:56 +0000 (UTC),  
<derick_eddington nospam.dot.yahoo.dot.com> wrote:
 I've made a Linux SIGSEGV signal handler which throws a  
 SegmentationFault which
 can be caught and used to get info about the segfault.  (The signal  
 handler is
 called on the stack which is why the throw works.)  I'm wondering about  
 the
 implications of this and how useful it could be.  I've attached it.

 Since Linux dmd doesn't support -g yet I've been using it to help squash
 segfaults.  SegmentationFault tells the type of segfault and the  
 offending
 address, and try-catching for it helps me narrow down where the segfault  
 is
 happening.

 I'm hoping people more knowledgeable can tell me if there are bugs with  
 my
 implementation and reasons doing this might not be a good idea.
You can catch segmentation faults using catch(Object) eg. void main() { try { (cast(Object)cast(void*)0x321).print(); } catch (Object o) { } } Regan
Mar 26 2005
parent reply derick_eddington nospam.dot.yahoo.dot.com writes:
In article <opsn8tr6pw23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Sat, 26 Mar 2005 07:15:56 +0000 (UTC),  
<derick_eddington nospam.dot.yahoo.dot.com> wrote:
 I've made a Linux SIGSEGV signal handler which throws a  
 SegmentationFault which
 can be caught and used to get info about the segfault.  (The signal  
 handler is
 called on the stack which is why the throw works.)  I'm wondering about  
 the
 implications of this and how useful it could be.  I've attached it.

 Since Linux dmd doesn't support -g yet I've been using it to help squash
 segfaults.  SegmentationFault tells the type of segfault and the  
 offending
 address, and try-catching for it helps me narrow down where the segfault  
 is
 happening.

 I'm hoping people more knowledgeable can tell me if there are bugs with  
 my
 implementation and reasons doing this might not be a good idea.
You can catch segmentation faults using catch(Object) eg. void main() { try { (cast(Object)cast(void*)0x321).print(); } catch (Object o) { } } Regan
Doesn't work for me on Linux. It results in the default process death. Does it really work for you? How does this work?
Mar 26 2005
next sibling parent John Demme <me teqdruid.com> writes:
derick_eddington nospam.dot.yahoo.dot.com wrote:
 In article <opsn8tr6pw23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 
On Sat, 26 Mar 2005 07:15:56 +0000 (UTC),  
<derick_eddington nospam.dot.yahoo.dot.com> wrote:

I've made a Linux SIGSEGV signal handler which throws a  
SegmentationFault which
can be caught and used to get info about the segfault.  (The signal  
handler is
called on the stack which is why the throw works.)  I'm wondering about  
the
implications of this and how useful it could be.  I've attached it.

Since Linux dmd doesn't support -g yet I've been using it to help squash
segfaults.  SegmentationFault tells the type of segfault and the  
offending
address, and try-catching for it helps me narrow down where the segfault  
is
happening.

I'm hoping people more knowledgeable can tell me if there are bugs with  
my
implementation and reasons doing this might not be a good idea.
You can catch segmentation faults using catch(Object) eg. void main() { try { (cast(Object)cast(void*)0x321).print(); } catch (Object o) { } } Regan
Doesn't work for me on Linux. It results in the default process death. Does it really work for you? How does this work?
I recall something like this working on Linux if you recompile phobos with the -debug and/or -g switches, and without -release. John Demme
Mar 26 2005
prev sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 26 Mar 2005 23:08:18 +0000 (UTC),  
<derick_eddington nospam.dot.yahoo.dot.com> wrote:
 In article <opsn8tr6pw23k2f5 nrage.netwin.co.nz>, Regan Heath says...
 On Sat, 26 Mar 2005 07:15:56 +0000 (UTC),
 <derick_eddington nospam.dot.yahoo.dot.com> wrote:
 I've made a Linux SIGSEGV signal handler which throws a
 SegmentationFault which
 can be caught and used to get info about the segfault.  (The signal
 handler is
 called on the stack which is why the throw works.)  I'm wondering about
 the
 implications of this and how useful it could be.  I've attached it.

 Since Linux dmd doesn't support -g yet I've been using it to help  
 squash
 segfaults.  SegmentationFault tells the type of segfault and the
 offending
 address, and try-catching for it helps me narrow down where the  
 segfault
 is
 happening.

 I'm hoping people more knowledgeable can tell me if there are bugs with
 my
 implementation and reasons doing this might not be a good idea.
You can catch segmentation faults using catch(Object) eg. void main() { try { (cast(Object)cast(void*)0x321).print(); } catch (Object o) { } } Regan
Doesn't work for me on Linux. It results in the default process death.
Sorry. I realised you were on linux some time after posting this .. i.e when I woke in the middle of the night. IIRC Walter has yet to implement this for Linux, tho it appears John disagrees.. I don't really know I only use D on Windows.
 Does it
 really work for you?  How does this work?
Yes. Walter "magic" makes it work. Regan
Mar 27 2005
prev sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
derick_eddington wrote:

 I've made a Linux SIGSEGV signal handler which throws a SegmentationFault which
 can be caught and used to get info about the segfault.  (The signal handler is
 called on the stack which is why the throw works.)  I'm wondering about the
 implications of this and how useful it could be.  I've attached it.
There is a similar implementation already, in DMD for Windows I believe? Walter seemed to think it was a good idea at the time: (Jan 15, 2005)
 Ok, I see the problem. Under windows, access violations are trapped and
 converted into D exceptions. This isn't done under linux, though it should
 be. 
My simple suggestion was that this runtime exception should be defined as a standard class in Phobos, and be consistant over platforms... Having a special class called SegmentationFault for Linux, or just a Exception with a special message like I believe Windows uses is no good. The error itself is called: - Segmentation Fault (Linux) - Access Violation (Windows) - Bus Error (Mac OS X) Better to name it abstractly ? My suggestion was to call it NullPointerError, or simpler NullError. (this is a little biased towards Java, of course, but consistant...) --anders
Mar 26 2005
parent reply derick_eddington nospam.dot.yahoo.dot.org writes:
In article <d24ter$p7u$1 digitaldaemon.com>,
=?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...
derick_eddington wrote:

 I've made a Linux SIGSEGV signal handler which throws a SegmentationFault which
 can be caught and used to get info about the segfault.  (The signal handler is
 called on the stack which is why the throw works.)  I'm wondering about the
 implications of this and how useful it could be.  I've attached it.
There is a similar implementation already, in DMD for Windows I believe? Walter seemed to think it was a good idea at the time: (Jan 15, 2005)
 Ok, I see the problem. Under windows, access violations are trapped and
 converted into D exceptions. This isn't done under linux, though it should
 be. 
My simple suggestion was that this runtime exception should be defined as a standard class in Phobos, and be consistant over platforms... Having a special class called SegmentationFault for Linux, or just a Exception with a special message like I believe Windows uses is no good. The error itself is called: - Segmentation Fault (Linux) - Access Violation (Windows) - Bus Error (Mac OS X) Better to name it abstractly ? My suggestion was to call it NullPointerError, or simpler NullError. (this is a little biased towards Java, of course, but consistant...) --anders
Not all segmentation faults on Linux are caused by trying to use null/0 address; it could be 0x1234 which isn't null. Also, SIGSEGV signals are also delivered if use of an address is attempted which violates the permissions of the segment, i.e. a page is non-executable and you try to call an address in it. The SIGSEGV handler can check which type it is and the offending address and could throw NullError if the address is 0, UnmappedAddressError(?) if non-0 but not a permission violation, and AddressPermissionError(?). From my segfault.d it seems there is the difference that with Windows you can try-catch the statement that causes it but with Linux the closest you can catch it is the call-statement of the function it is in.
Mar 27 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
derick_eddington wrote:

My suggestion was to call it NullPointerError, or simpler NullError.
(this is a little biased towards Java, of course, but consistant...)
Not all segmentation faults on Linux are caused by trying to use null/0 address; it could be 0x1234 which isn't null. Also, SIGSEGV signals are also delivered if use of an address is attempted which violates the permissions of the segment, i.e. a page is non-executable and you try to call an address in it. The SIGSEGV handler can check which type it is and the offending address and could throw NullError if the address is 0, UnmappedAddressError(?) if non-0 but not a permission violation, and AddressPermissionError(?).
Good point, I was only thinking of the *null "error" for now... (I'm not 100% sure just what causes Access Violations on Windows) Anyway, the point was that if it was going to throw exceptions at run-time, there should be classes for those in Phobos. And probably a "handler" too, like there is for assert/outofmemory ? i.e. the segfault handler checks the "type" of segmentation fault, and if the address is null it calls an extern(C) function in Phobos that creates and throws a NullError. Like _d_assert/_d_OutOfMemory... I'm not sure if getting this error increases or decreases the chance of finding the line of code that caused it, though ? At least with GDB you have a decent chance of getting a file/line (not every, with DMD) Of course, the Error is still nicer than the default segfault without debugger on (another related thread is regarding how to avoid causing those nulls to be dereferenced in the first place, as it happens even in e.g. Java) --anders
Mar 28 2005