[M3devel] SEGV mapping to RuntimeError
Mika Nystrom
mika at async.caltech.edu
Sun Feb 20 00:27:29 CET 2011
Ah, yes, stack protection.
Do you know if it's a SIGSEGV, not a SIGBUS? I know I have seen SIGILL on Macs.
Hmm, I get SIGILL on AMD64_FREEBSD as well:
time ../AMD64_FREEBSD/stubexample
M-Scheme Experimental
LITHP ITH LITHENING.
> (define (f a) (+ (f (+ a 1)) (f (+ a 2))))
f
> (f 0)
Illegal instruction
3.847u 0.368s 0:13.32 31.5% 2160+284478k 0+0io 0pf+0w
What absolutely must not happen, of course, is that the runtime hangs
while executing only safe code...
Mika
"Rodney M. Bates" writes:
>I know of one other place the compilers rely on hardware memory protection
>to detect a checked runtime error, and that is stack overflow. This won't
>corrupt anything, but is hard to distinguish from dereferencing NIL.
>This could probably be distinguished after the fact by some low-level,
>target-dependent code. I have found it by looking at assembly code at
>the point of failure--usually right after a stack pointer push.
>
>Detecting this via compiler-generated checks would probably be more
>extravagant than many other checks, as it is so frequent. I am not
>aware of any really good solution to this in any implementation of any
>language.
>
>On 02/19/2011 02:38 PM, Mika Nystrom wrote:
>> Jay, sometimes I wonder about you: this is a Modula-3 mailing list,
>> you know!
>>
>> "Corrupting the heap" is something that can only happen as a result of
>> an unchecked runtime error. Unchecked runtime errors cannot happen in
>> modules not marked UNSAFE.
>>
>> SEGV is, however, used by the CM3 implementation (and its predecessors)
>> to signal a certain kind of *checked* runtime error, namely, the
>> dereferencing of a NIL reference. Correct me if I am wrong, but an
>> attempt to dereference NIL is not going to leave the heap corrupted?
>>
>> And if you stick to safe code, the only SEGVs I think you get in the
>> current CM3 are ones from NIL dereferences.
>>
>> Hence, as long as you stick with safe code, the only time the code I
>> checked in earlier gets triggered is for NIL dereferences, which should
>> never corrupt the heap. So SEGV is not sometimes, but in fact always
>> recoverable.
>>
>> :-)
>>
>> Mika
>>
>> P.S. the bit above "if you stick to safe code": if you actually program in
>> Modula-3 you almost never use UNSAFE. I went through my repository and
>> I have 40 modules using UNSAFE out of a total of 4,559. Furthermore,
>> many of the UNSAFE modules are glue code to Fortran routines, which
>> could relatively easily be verified to be safe in the Modula-3 sense.
>> Almost all what remains is glue to some C library, which wouldn't be
>> necessary if the rest of the world would wake up out of the dark ages, but
>> I don't have the time to rewrite every single library from scratch myself.
>>
>>
>> Jay K writes:
>>> --_a2a24b92-3b4c-456e-ab1b-c3f5e912854f_
>>> Content-Type: text/plain; charset="iso-8859-1"
>>> Content-Transfer-Encoding: quoted-printable
>>>
>>>
>>> Letting any code run after a SIGSEGV is dubious.
>>> Imagine the heap is corrupted.
>>> And then you run more code.
>>> And the code happens to call malloc.
>>> Or printf to log something.
>>> =20
>>> I suppose there might be an application that maps memory
>>> gradually=2C as pieces of a buffer are hit. Might.
>>> =20
>>> - Jay
>>> =20
>>>> To: m3devel at elegosoft.com
>>>> Date: Sat=2C 19 Feb 2011 10:29:30 -0800
>>>> From: mika at async.caltech.edu
>>>> Subject: [M3devel] SEGV mapping to RuntimeError
>>>> =20
>>>> =20
>>>> Dear m3devel=2C
>>>> =20
>>>> For a while it has annoyed me that segmentation violations cause an
>>>> unconditional program abort. I've changed that now so that (under user
>>>> threads at least) we instead get a RuntimeError. Here's an example of
>>>> the mechanism at work in an interactive Scheme environment. Consider
>>>> the unhelpful interface and module Crash:
>>>> =20
>>>> INTERFACE Crash=3B PROCEDURE Me()=3B END Crash.
>>>> =20
>>>> MODULE Crash=3B
>>>> =20
>>>> PROCEDURE Me() =3D
>>>> VAR ptr : REF INTEGER :=3D NIL=3B BEGIN
>>>> ptr^ :=3D 0
>>>> END Me=3B
>>>> =20
>>>> BEGIN END Crash.
>>>> =20
>>>> Here's an example of what happens if you now call this from an interactiv=
>>> e
>>>> interpreter that catches the exception RuntimeError.E:
>>>> =20
>>>> M-Scheme Experimental
>>>> LITHP ITH LITHENING.
>>>>> (require-modules "m3")
>>>> #t
>>>>> (Crash.Me)
>>>> EXCEPTION! RuntimeError! Attempt to reference an illegal memory location.
>>>>> (+ 3 4)=20
>>>> 7
>>>>> =20
>>>> =20
>>>> I just realized I may have broken pthreads=2C let me go back and double-c=
>>> heck it.=20
>>>> runtime/POSIX and thread/POSIX don't refer to the same thing do they...
>>>> =20
>>>> Mika
>>>> =20
>>> =
>>>
>>> --_a2a24b92-3b4c-456e-ab1b-c3f5e912854f_
>>> Content-Type: text/html; charset="iso-8859-1"
>>> Content-Transfer-Encoding: quoted-printable
>>>
>>> <html>
>>> <head>
>>> <style><!--
>>> .hmmessage P
>>> {
>>> margin:0px=3B
>>> padding:0px
>>> }
>>> body.hmmessage
>>> {
>>> font-size: 10pt=3B
>>> font-family:Tahoma
>>> }
>>> --></style>
>>> </head>
>>> <body class=3D'hmmessage'>
>>> Letting any code run after a SIGSEGV is dubious.<BR>
>>> Imagine the heap =3Bis corrupted.<BR>
>>> And then you run more code.<BR>
>>> And the code happens to call malloc.<BR>
>>> Or printf to log something.<BR>
>>>  =3B<BR>
>>> I suppose there might be an application that maps memory<BR>
>>> gradually=2C as pieces of a buffer are hit. Might.<BR>
>>>  =3B<BR>
>>>  =3B- Jay<BR> =3B<BR>
>>> >=3B To: m3devel at elegosoft.com<BR>>=3B Date: Sat=2C 19 Feb 2011 10:29:3=
>>> 0 -0800<BR>>=3B From: mika at async.caltech.edu<BR>>=3B Subject: [M3devel]=
>>> SEGV mapping to RuntimeError<BR>>=3B<BR>>=3B<BR>>=3B Dear m3devel=
>>> =2C<BR>>=3B<BR>>=3B For a while it has annoyed me that segmentation vi=
>>> olations cause an<BR>>=3B unconditional program abort. I've changed that =
>>> now so that (under user<BR>>=3B threads at least) we instead get a Runtim=
>>> eError. Here's an example of<BR>>=3B the mechanism at work in an interact=
>>> ive Scheme environment. Consider<BR>>=3B the unhelpful interface and modu=
>>> le Crash:<BR>>=3B<BR>>=3B INTERFACE Crash=3B PROCEDURE Me()=3B END Cra=
>>> sh.<BR>>=3B<BR>>=3B MODULE Crash=3B<BR>>=3B<BR>>=3B PROCEDURE Me(=
>>> ) =3D<BR>>=3B VAR ptr : REF INTEGER :=3D NIL=3B BEGIN<BR>>=3B ptr^ :=3D=
>>> 0<BR>>=3B END Me=3B<BR>>=3B<BR>>=3B BEGIN END Crash.<BR>>=3B<BR>=
>>> >=3B Here's an example of what happens if you now call this from an inter=
>>> active<BR>>=3B interpreter that catches the exception RuntimeError.E:<BR>=
>>> >=3B<BR>>=3B M-Scheme Experimental<BR>>=3B LITHP ITH LITHENING.<BR>&=
>>> gt=3B>=3B (require-modules "m3")<BR>>=3B #t<BR>>=3B>=3B (Crash.Me=
>>> )<BR>>=3B EXCEPTION! RuntimeError! Attempt to reference an illegal memory=
>>> location.<BR>>=3B>=3B (+ 3 4)<BR>>=3B 7<BR>>=3B>=3B<BR>>=
>>> =3B<BR>>=3B I just realized I may have broken pthreads=2C let me go back=
>>> and double-check it.<BR>>=3B runtime/POSIX and thread/POSIX don't refer=
>>> to the same thing do they...<BR>>=3B<BR>>=3B Mika<BR>>=3B<BR> =
>>> </body>
>>> </html>=
>>>
>>> --_a2a24b92-3b4c-456e-ab1b-c3f5e912854f_--
>>
More information about the M3devel
mailing list