[M3devel] SEGV mapping to RuntimeError

Jay K jay.krell at cornell.edu
Tue Feb 22 23:08:58 CET 2011


Heap vs. stack is indeed an unsolvable dilemna.
Stack is much faster, but some arbitrary size must be chosen, that bothers me too, and detection and recovery from out of stack is tricky and not portable.
Heap is slow, but portable, and generally limited to address space (but subject to fragmentation), easy to detect exhaustion.
GC heap is usually fast to allocate, competitive with stack allocation, but the more you allocate, the more work for the GC to do.
There is no free lunch -- not even as cheap as it might seem. :)
 
Some systems..which I have never worked on..statically allocate everything.
They need to know they will never run out of memory.
 
> I realize my code is perhaps difficult to read.
 
Not necessarily. I didn't even try yet. :)
For many programmers, it is difficult to get them to read any code. :)
 
 
 - Jay
 
> To: jay.krell at cornell.edu
> Date: Tue, 22 Feb 2011 10:45:02 -0800
> From: mika at async.caltech.edu
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] SEGV mapping to RuntimeError
> 
> Jay K writes:
> >--_ab466c75-f74a-4983-8fec-4f513f45fe0b_
> >Content-Type: text/plain; charset="iso-8859-1"
> >Content-Transfer-Encoding: quoted-printable
> >
> >
> >(aside=2C and possible agreement: right -- an interpreter should consider N=
> >OT recursing on the machine
> >stack whenever code it is interpreting recurses=2C but definitely some do)
> >=20
> > - Jay
> 
> 
> Jay, yes I agree---but:
> 
> 1. of course it's easier to code the interpreter to recurse on the machine
> stack
> 
> 2. code called out from the interpreter will in any case recurse on the (a)
> machine stack 
> 
> 3. again if one can "fix" the stack mechanism so that running out of
> stack space is non-fatal, there's no reason not to use the machine stack
> 
> I've found that Modula-3's garbage collector is brutally slow and that
> converting code to using stack-allocated memory whenever possible is a
> huge performance win under both PM3 and CM3. Perhaps this is a problem
> with the garbage collector.
> 
> I also have a partial design for a Scheme compiler (emitting Modula-3)
> that would use the machine stack whenever possible rather than heap
> allocation and do a "tricky thing" with local procedures to copy the
> stack whenever a reference to the stack escapes. (Most of the time you
> can implement Scheme on a stack but sometimes you need to keep part
> of it live after you return; hence implementations (including mine)
> heap-allocate local variables...)
> 
> I realize my code is perhaps difficult to read. The gist of it is this:
> when you run out of stack space, allocate a new stack anywhere else
> in memory. Make it appear that you have alloca'd all the space between
> the old and new stacks (into a variable that you of course never touch),
> then continue. An issue is what to do when you return, you have to make
> sure that you restore your old redzone.. perhaps you don't need to free
> the stack eagerly: you could instead remember you have that page allocated
> and re-use it next time you hit the redzone, or put it in a pool to allow
> it to be used by another thread.
> 
> The arbitrary choice of stack sizes has always bothered me greatly.
> Some of my programs have thousands of threads and they use stack space
> irregularly...
> 
> Mika
> 
> 
> >> To: rodney_bates at lcwb.coop
> >> Date: Tue=2C 22 Feb 2011 09:44:05 -0800
> >> From: mika at async.caltech.edu
> >> CC: m3devel at elegosoft.com
> >> Subject: Re: [M3devel] SEGV mapping to RuntimeError
> >>=20
> >>=20
> >> Ok so I was thinking about this.
> >>=20
> >> Why on earth is stack overflow even a problem?
> >>=20
> >> Consider the following procedure call (in my code=2C stack grows upwards)=
> >:
> >>=20
> >> (* sp at x=2C pc at y *)
> >> y: P(args)
> >> z: next_statement
> >>=20
> >> decompose as follows:
> >>=20
> >> (* sp at x=2C pc at y *)
> >> y: Push(args etc. and ret. address z)
> >> Jump(P)
> >> z: next_statement
> >>=20
> >> Now=2C we say:
> >>=20
> >> y: ok :=3D check_stack(size of frame)
> >> IF NOT ok THEN abort() END=3B
> >> Push(args etc. and ret. address z)
> >> Jump(P)
> >> z: next_statement
> >>=20
> >> (note check_stack and the following IF can be implemented by hardware=2C
> >> need not actually be an instruction)
> >>=20
> >> Let me change the code a tad:
> >>=20
> >> y: ok :=3D check_stack(size of frame)
> >> y':IF NOT ok THEN=20
> >> WITH new_stack_bottom =3D malloc(stack_size)
> >> huge_amount =3D new_stack_bottom - sp DO
> >> create_redzone_at(new_stack_bottom+stack_size-redzone_size)
> >> EVAL alloca(huge_amount)=20
> >> END
> >> END=3B
> >> Push(args etc. and ret. address z)
> >> Jump(P)
> >> z: IF NOT ok THEN destroy_redzone(...)=3B free(new_stack_bottom) END
> >>=20
> >> Note 1. cleanup of redzone could be postponed to return of caller....when
> >> alloca in any case has to be cleaned up.
> >>=20
> >> Note 2. the test IF NOT ok at z is more expensive to implement than the
> >> one at y because you can't really use hardware for it. A hardware callbac=
> >k
> >> can be arranged though:
> >>=20
> >> VAR ptr :=3D sp=3B
> >> y: ok :=3D check_stack(size of frame)
> >> y':IF NOT ok THEN=20
> >> ptr :=3D 0=3B (* illegal address *)
> >> fault_address :=3D z=3B
> >> WITH new_stack_bottom =3D malloc(stack_size)
> >> huge_amount =3D new_stack_bottom - sp DO
> >> create_redzone_at(new_stack_bottom+stack_size-redzone_size)
> >> EVAL alloca(huge_amount)=20
> >> END
> >> END=3B
> >> Push(args etc. and ret. address z)
> >> Jump(P)
> >> z: EVAL ptr^ (* [ NOT ok -> hardware callback to SEGV: ] *)
> >>=20
> >> SEGV(signalpc): IF NOT ok AND signalpc =3D fault_address THEN destroy_red=
> >zone(...)=3B free(new_stack_bottom) END
> >>=20
> >> Mika
> >>=20
> >>=20
> >>=20
> >>=20
> >>=20
> >> "Rodney M. Bates" writes:
> >> >
> >> >
> >> >On 02/20/2011 12:37 PM=2C Mika Nystrom wrote:
> >> >> On a 64-bit machine=2C at least=2C there ought to be enough virtual
> >> >> memory that you could just have a gap between thread stacks big
> >> >> enough to allow for a protection area larger than the largest possible
> >> >> (implementation-defined) activation record=2C no? I know I've run into
> >> >> trouble with very large activation records in the past (and not becaus=
> >e
> >> >> I was running out of stack space=2C either).
> >> >>
> >> >> Or at least a procedure with a very large activation record (or
> >> >> a procedure calling it) could be required to call some sort of check
> >> >> routine "EnoughStackSpaceRemaining()" before starting to scribble
> >> >> on the activation record?
> >> >
> >> >Hmm=2C I like this idea. It would introduce normal-case runtime overhead
> >> >only for such procedures=2C and these are likely rare. Also=2C assuming =
> >the procedure
> >> >actually uses very much of its large AR=2C it should also have enough co=
> >mputation
> >> >time to wash out the stack check overhead.
> >> >
> >> >>
> >> >> Also the end of the activation record must be written to at least once=
> >=2C
> >> >> or else the memory protection won't be triggered.
> >> >>
> >> >
> >> >I was thinking (as an alternative mechanism) of having the compiler inte=
> >ntionally
> >> >add enough artificial write(s) as necessary to ensure storing within the
> >> >red zone=2C and not just beyond it. This seems trickier to get right and
> >> >harder to distinguish after the fact from a NIL dereference.
> >> >
> >> >> In any case if this is done properly the same mechanism I proposed for
> >> >> SIGSEGV ought to be able to catch stack overflow=2C no? Well=2C as lon=
> >g as
> >> >> signals are delivered on a separate stack. If signals are delivered on
> >> >> the same stack=2C the signal handler would get nastier=2C it would hav=
> >e to
> >> >> make space through some manipulations (maybe temporarily unporotecting
> >> >> the redzone page?) for its own purposes... but I don't see why it
> >> >> couldn't be done.
> >> >>
> >> >> Not sure why I'm getting SIGILL... maybe I am getting my signal handle=
> >r
> >> >> activated inside the redzone page because of a difference in signal
> >> >> handling..? I remember reading something about sigaltstack...
> >> >>
> >> >> I would of course love to be able to recover from stack overflow=2C to=
> >o.
> >> >> In some sense=2C since it's a generally unknown limit=2C it's even les=
> >s of
> >> >> a fatal error than a NIL dereference (hence makes even more sense to
> >> >> catch it).
> >> >
> >> >I think this would be a nice mechanism to have available. It would have =
> >to
> >> >be used with some care. In any case=2C it would be really nice and more
> >> >frequently so=2C to at least have runtime error messages that distinguis=
> >hed
> >> >stack overflow from NIL deref.
> >> >
> >> >>
> >> >> Mika
> >> >>
> >> >> "Rodney M. Bates" writes:
> >> >>> I am pretty sure the cases I've seen are SIGSEGV on LINUXLIBC6 and AM=
> >D64_LINUX.
> >> >>> Probably a fully protected guard page at the end of the stack. This t=
> >echnique
> >> >>> always worries me a bit because a procedure with a really big activat=
> >ion record
> >> >>> could jump right past it. Probably it would almost always access the =
> >first page
> >> >>> of the big area before storing anything into later pages.
> >> >>>
> >> >>> On 02/19/2011 05:27 PM=2C Mika Nystrom wrote:
> >> >>>> Ah=2C yes=2C stack protection.
> >> >>>>
> >> >>>> Do you know if it's a SIGSEGV=2C not a SIGBUS? I know I have seen SI=
> >GILL on Macs.
> >> >>>>
> >> >>>> Hmm=2C 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=2C of course=2C 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 pro=
> >tection
> >> >>>>> to detect a checked runtime error=2C and that is stack overflow. Th=
> >is won't
> >> >>>>> corrupt anything=2C but is hard to distinguish from dereferencing N=
> >IL.
> >> >>>>> This could probably be distinguished after the fact by some low-lev=
> >el=2C
> >> >>>>> 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=2C as it is so frequent. I am no=
> >t
> >> >>>>> aware of any really good solution to this in any implementation of =
> >any
> >> >>>>> language.
> >> >>>>>
> >> >>>>> On 02/19/2011 02:38 PM=2C Mika Nystrom wrote:
> >> >>>>>> Jay=2C sometimes I wonder about you: this is a Modula-3 mailing li=
> >st=2C
> >> >>>>>> you know!
> >> >>>>>>
> >> >>>>>> "Corrupting the heap" is something that can only happen as a resul=
> >t of
> >> >>>>>> an unchecked runtime error. Unchecked runtime errors cannot happen=
> > in
> >> >>>>>> modules not marked UNSAFE.
> >> >>>>>>
> >> >>>>>> SEGV is=2C however=2C used by the CM3 implementation (and its pred=
> >ecessors)
> >> >>>>>> to signal a certain kind of *checked* runtime error=2C namely=2C t=
> >he
> >> >>>>>> dereferencing of a NIL reference. Correct me if I am wrong=2C but =
> >an
> >> >>>>>> attempt to dereference NIL is not going to leave the heap corrupte=
> >d?
> >> >>>>>>
> >> >>>>>> And if you stick to safe code=2C the only SEGVs I think you get in=
> > the
> >> >>>>>> current CM3 are ones from NIL dereferences.
> >> >>>>>>
> >> >>>>>> Hence=2C as long as you stick with safe code=2C the only time the =
> >code I
> >> >>>>>> checked in earlier gets triggered is for NIL dereferences=2C which=
> > should
> >> >>>>>> never corrupt the heap. So SEGV is not sometimes=2C but in fact al=
> >ways
> >> >>>>>> recoverable.
> >> >>>>>>
> >> >>>>>> :-)
> >> >>>>>>
> >> >>>>>> Mika
> >> >>>>>>
> >> >>>>>> P.S. the bit above "if you stick to safe code": if you actually pr=
> >ogram 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=2C559. Furtherm=
> >ore=2C
> >> >>>>>> many of the UNSAFE modules are glue code to Fortran routines=2C wh=
> >ich
> >> >>>>>> could relatively easily be verified to be safe in the Modula-3 sen=
> >se.
> >> >>>>>> Almost all what remains is glue to some C library=2C which wouldn'=
> >t be
> >> >>>>>> necessary if the rest of the world would wake up out of the dark a=
> >ges=2C 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=3B charset=3D"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.
> >> >>>>>>> =3D20
> >> >>>>>>> I suppose there might be an application that maps memory
> >> >>>>>>> gradually=3D2C as pieces of a buffer are hit. Might.
> >> >>>>>>> =3D20
> >> >>>>>>> - Jay
> >> >>>>>>> =3D20
> >> >>>>>>>> To: m3devel at elegosoft.com
> >> >>>>>>>> Date: Sat=3D2C 19 Feb 2011 10:29:30 -0800
> >> >>>>>>>> From: mika at async.caltech.edu
> >> >>>>>>>> Subject: [M3devel] SEGV mapping to RuntimeError
> >> >>>>>>>> =3D20
> >> >>>>>>>> =3D20
> >> >>>>>>>> Dear m3devel=3D2C
> >> >>>>>>>> =3D20
> >> >>>>>>>> For a while it has annoyed me that segmentation violations cause=
> > an
> >> >>>>>>>> unconditional program abort. I've changed that now so that (unde=
> >r user
> >> >>>>>>>> threads at least) we instead get a RuntimeError. Here's an examp=
> >le of
> >> >>>>>>>> the mechanism at work in an interactive Scheme environment. Cons=
> >ider
> >> >>>>>>>> the unhelpful interface and module Crash:
> >> >>>>>>>> =3D20
> >> >>>>>>>> INTERFACE Crash=3D3B PROCEDURE Me()=3D3B END Crash.
> >> >>>>>>>> =3D20
> >> >>>>>>>> MODULE Crash=3D3B
> >> >>>>>>>> =3D20
> >> >>>>>>>> PROCEDURE Me() =3D3D
> >> >>>>>>>> VAR ptr : REF INTEGER :=3D3D NIL=3D3B BEGIN
> >> >>>>>>>> ptr^ :=3D3D 0
> >> >>>>>>>> END Me=3D3B
> >> >>>>>>>> =3D20
> >> >>>>>>>> BEGIN END Crash.
> >> >>>>>>>> =3D20
> >> >>>>>>>> Here's an example of what happens if you now call this from an i=
> >nteractiv=3D
> >> >>>>>>> e
> >> >>>>>>>> interpreter that catches the exception RuntimeError.E:
> >> >>>>>>>> =3D20
> >> >>>>>>>> M-Scheme Experimental
> >> >>>>>>>> LITHP ITH LITHENING.
> >> >>>>>>>>> (require-modules "m3")
> >> >>>>>>>> #t
> >> >>>>>>>>> (Crash.Me)
> >> >>>>>>>> EXCEPTION! RuntimeError! Attempt to reference an illegal memory =
> >location.
> >> >>>>>>>>> (+ 3 4)=3D20
> >> >>>>>>>> 7
> >> >>>>>>>>> =3D20
> >> >>>>>>>> =3D20
> >> >>>>>>>> I just realized I may have broken pthreads=3D2C let me go back a=
> >nd double-c=3D
> >> >>>>>>> heck it.=3D20
> >> >>>>>>>> runtime/POSIX and thread/POSIX don't refer to the same thing do =
> >they...
> >> >>>>>>>> =3D20
> >> >>>>>>>> Mika
> >> >>>>>>>> =3D20
> >> >>>>>>> =3D
> >> >>>>>>>
> >> >>>>>>> --_a2a24b92-3b4c-456e-ab1b-c3f5e912854f_
> >> >>>>>>> Content-Type: text/html=3B charset=3D"iso-8859-1"
> >> >>>>>>> Content-Transfer-Encoding: quoted-printable
> >> >>>>>>>
> >> >>>>>>> <html>
> >> >>>>>>> <head>
> >> >>>>>>> <style><!--
> >> >>>>>>> .hmmessage P
> >> >>>>>>> {
> >> >>>>>>> margin:0px=3D3B
> >> >>>>>>> padding:0px
> >> >>>>>>> }
> >> >>>>>>> body.hmmessage
> >> >>>>>>> {
> >> >>>>>>> font-size: 10pt=3D3B
> >> >>>>>>> font-family:Tahoma
> >> >>>>>>> }
> >> >>>>>>> --></style>
> >> >>>>>>> </head>
> >> >>>>>>> <body class=3D3D'hmmessage'>
> >> >>>>>>> Letting any code run after a SIGSEGV is dubious.<BR>
> >> >>>>>>> Imagine the heap&nbsp=3D3Bis corrupted.<BR>
> >> >>>>>>> And then you run more code.<BR>
> >> >>>>>>> And the code happens to call malloc.<BR>
> >> >>>>>>> Or printf to log something.<BR>
> >> >>>>>>> &nbsp=3D3B<BR>
> >> >>>>>>> I suppose there might be an application that maps memory<BR>
> >> >>>>>>> gradually=3D2C as pieces of a buffer are hit. Might.<BR>
> >> >>>>>>> &nbsp=3D3B<BR>
> >> >>>>>>> &nbsp=3D3B- Jay<BR>&nbsp=3D3B<BR>
> >> >>>>>>> &gt=3D3B To: m3devel at elegosoft.com<BR>&gt=3D3B Date: Sat=3D2C 19 =
> >Feb 2011 10:29:3=3D
> >> >>>>>>> 0 -0800<BR>&gt=3D3B From: mika at async.caltech.edu<BR>&gt=3D3B Subj=
> >ect: [M3devel]=3D
> >> >>>>>>> SEGV mapping to RuntimeError<BR>&gt=3D3B<BR>&gt=3D3B<BR>&gt=3D3B =
> >Dear m3devel=3D
> >> >>>>>>> =3D2C<BR>&gt=3D3B<BR>&gt=3D3B For a while it has annoyed me that =
> >segmentation vi=3D
> >> >>>>>>> olations cause an<BR>&gt=3D3B unconditional program abort. I've c=
> >hanged that =3D
> >> >>>>>>> now so that (under user<BR>&gt=3D3B threads at least) we instead =
> >get a Runtim=3D
> >> >>>>>>> eError. Here's an example of<BR>&gt=3D3B the mechanism at work in=
> > an interact=3D
> >> >>>>>>> ive Scheme environment. Consider<BR>&gt=3D3B the unhelpful interf=
> >ace and modu=3D
> >> >>>>>>> le Crash:<BR>&gt=3D3B<BR>&gt=3D3B INTERFACE Crash=3D3B PROCEDURE =
> >Me()=3D3B END Cra=3D
> >> >>>>>>> sh.<BR>&gt=3D3B<BR>&gt=3D3B MODULE Crash=3D3B<BR>&gt=3D3B<BR>&gt=
> >=3D3B PROCEDURE Me(=3D
> >> >>>>>>> ) =3D3D<BR>&gt=3D3B VAR ptr : REF INTEGER :=3D3D NIL=3D3B BEGIN<B=
> >R>&gt=3D3B ptr^ :=3D3D=3D
> >> >>>>>>> 0<BR>&gt=3D3B END Me=3D3B<BR>&gt=3D3B<BR>&gt=3D3B BEGIN END Crash=
> >.<BR>&gt=3D3B<BR>=3D
> >> >>>>>>> &gt=3D3B Here's an example of what happens if you now call this f=
> >rom an inter=3D
> >> >>>>>>> active<BR>&gt=3D3B interpreter that catches the exception Runtime=
> >Error.E:<BR>=3D
> >> >>>>>>> &gt=3D3B<BR>&gt=3D3B M-Scheme Experimental<BR>&gt=3D3B LITHP ITH =
> >LITHENING.<BR>&=3D
> >> >>>>>>> gt=3D3B&gt=3D3B (require-modules "m3")<BR>&gt=3D3B #t<BR>&gt=3D3B=
> >&gt=3D3B (Crash.Me=3D
> >> >>>>>>> )<BR>&gt=3D3B EXCEPTION! RuntimeError! Attempt to reference an il=
> >legal memory=3D
> >> >>>>>>> location.<BR>&gt=3D3B&gt=3D3B (+ 3 4)<BR>&gt=3D3B 7<BR>&gt=3D3B&g=
> >t=3D3B<BR>&gt=3D
> >> >>>>>>> =3D3B<BR>&gt=3D3B I just realized I may have broken pthreads=3D2C=
> > let me go back=3D
> >> >>>>>>> and double-check it.<BR>&gt=3D3B runtime/POSIX and thread/POSIX d=
> >on't refer=3D
> >> >>>>>>> to the same thing do they...<BR>&gt=3D3B<BR>&gt=3D3B Mika<BR>&gt=
> >=3D3B<BR> =3D
> >> >>>>>>> </body>
> >> >>>>>>> </html>=3D
> >> >>>>>>>
> >> >>>>>>> --_a2a24b92-3b4c-456e-ab1b-c3f5e912854f_--
> >> >>>>>>
> >> >>>>
> >> >>
> > =
> >
> >--_ab466c75-f74a-4983-8fec-4f513f45fe0b_
> >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'>
> >(aside=2C and possible agreement: right -- an interpreter should consider N=
> >OT recursing on the machine<BR>
> >stack whenever code it is interpreting recurses=2C but definitely some do)<=
> >BR>
> >&nbsp=3B<BR>
> >&nbsp=3B- Jay<BR>&nbsp=3B<BR>
> >&gt=3B To: rodney_bates at lcwb.coop<BR>&gt=3B Date: Tue=2C 22 Feb 2011 09:44:=
> >05 -0800<BR>&gt=3B From: mika at async.caltech.edu<BR>&gt=3B CC: m3devel at elego=
> >soft.com<BR>&gt=3B Subject: Re: [M3devel] SEGV mapping to RuntimeError<BR>&=
> >gt=3B <BR>&gt=3B <BR>&gt=3B Ok so I was thinking about this.<BR>&gt=3B <BR>=
> >&gt=3B Why on earth is stack overflow even a problem?<BR>&gt=3B <BR>&gt=3B =
> >Consider the following procedure call (in my code=2C stack grows upwards):<=
> >BR>&gt=3B <BR>&gt=3B (* sp at x=2C pc at y *)<BR>&gt=3B y: P(args)<BR>&gt=
> >=3B z: next_statement<BR>&gt=3B <BR>&gt=3B decompose as follows:<BR>&gt=3B =
> ><BR>&gt=3B (* sp at x=2C pc at y *)<BR>&gt=3B y: Push(args etc. and ret. ad=
> >dress z)<BR>&gt=3B Jump(P)<BR>&gt=3B z: next_statement<BR>&gt=3B <BR>&gt=3B=
> > Now=2C we say:<BR>&gt=3B <BR>&gt=3B y: ok :=3D check_stack(size of frame)<=
> >BR>&gt=3B IF NOT ok THEN abort() END=3B<BR>&gt=3B Push(args etc. and ret. a=
> >ddress z)<BR>&gt=3B Jump(P)<BR>&gt=3B z: next_statement<BR>&gt=3B <BR>&gt=
> >=3B (note check_stack and the following IF can be implemented by hardware=
> >=2C<BR>&gt=3B need not actually be an instruction)<BR>&gt=3B <BR>&gt=3B Let=
> > me change the code a tad:<BR>&gt=3B <BR>&gt=3B y: ok :=3D check_stack(size=
> > of frame)<BR>&gt=3B y':IF NOT ok THEN <BR>&gt=3B WITH new_stack_bottom =3D=
> > malloc(stack_size)<BR>&gt=3B huge_amount =3D new_stack_bottom - sp DO<BR>&=
> >gt=3B create_redzone_at(new_stack_bottom+stack_size-redzone_size)<BR>&gt=3B=
> > EVAL alloca(huge_amount) <BR>&gt=3B END<BR>&gt=3B END=3B<BR>&gt=3B Push(ar=
> >gs etc. and ret. address z)<BR>&gt=3B Jump(P)<BR>&gt=3B z: IF NOT ok THEN d=
> >estroy_redzone(...)=3B free(new_stack_bottom) END<BR>&gt=3B <BR>&gt=3B Note=
> > 1. cleanup of redzone could be postponed to return of caller....when<BR>&g=
> >t=3B alloca in any case has to be cleaned up.<BR>&gt=3B <BR>&gt=3B Note 2. =
> >the test IF NOT ok at z is more expensive to implement than the<BR>&gt=3B o=
> >ne at y because you can't really use hardware for it. A hardware callback<B=
> >R>&gt=3B can be arranged though:<BR>&gt=3B <BR>&gt=3B VAR ptr :=3D sp=3B<BR=
> >>&gt=3B y: ok :=3D check_stack(size of frame)<BR>&gt=3B y':IF NOT ok THEN <=
> >BR>&gt=3B ptr :=3D 0=3B (* illegal address *)<BR>&gt=3B fault_address :=3D =
> >z=3B<BR>&gt=3B WITH new_stack_bottom =3D malloc(stack_size)<BR>&gt=3B huge_=
> >amount =3D new_stack_bottom - sp DO<BR>&gt=3B create_redzone_at(new_stack_b=
> >ottom+stack_size-redzone_size)<BR>&gt=3B EVAL alloca(huge_amount) <BR>&gt=
> >=3B END<BR>&gt=3B END=3B<BR>&gt=3B Push(args etc. and ret. address z)<BR>&g=
> >t=3B Jump(P)<BR>&gt=3B z: EVAL ptr^ (* [ NOT ok -&gt=3B hardware callback t=
> >o SEGV: ] *)<BR>&gt=3B <BR>&gt=3B SEGV(signalpc): IF NOT ok AND signalpc =
> >=3D fault_address THEN destroy_redzone(...)=3B free(new_stack_bottom) END<B=
> >R>&gt=3B <BR>&gt=3B Mika<BR>&gt=3B <BR>&gt=3B <BR>&gt=3B <BR>&gt=3B <BR>&gt=
> >=3B <BR>&gt=3B "Rodney M. Bates" writes:<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3B<=
> >BR>&gt=3B &gt=3BOn 02/20/2011 12:37 PM=2C Mika Nystrom wrote:<BR>&gt=3B &gt=
> >=3B&gt=3B On a 64-bit machine=2C at least=2C there ought to be enough virtu=
> >al<BR>&gt=3B &gt=3B&gt=3B memory that you could just have a gap between thr=
> >ead stacks big<BR>&gt=3B &gt=3B&gt=3B enough to allow for a protection area=
> > larger than the largest possible<BR>&gt=3B &gt=3B&gt=3B (implementation-de=
> >fined) activation record=2C no? I know I've run into<BR>&gt=3B &gt=3B&gt=3B=
> > trouble with very large activation records in the past (and not because<BR=
> >>&gt=3B &gt=3B&gt=3B I was running out of stack space=2C either).<BR>&gt=3B=
> > &gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B Or at least a procedure with a very la=
> >rge activation record (or<BR>&gt=3B &gt=3B&gt=3B a procedure calling it) co=
> >uld be required to call some sort of check<BR>&gt=3B &gt=3B&gt=3B routine "=
> >EnoughStackSpaceRemaining()" before starting to scribble<BR>&gt=3B &gt=3B&g=
> >t=3B on the activation record?<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3BHmm=2C I li=
> >ke this idea. It would introduce normal-case runtime overhead<BR>&gt=3B &gt=
> >=3Bonly for such procedures=2C and these are likely rare. Also=2C assuming =
> >the procedure<BR>&gt=3B &gt=3Bactually uses very much of its large AR=2C it=
> > should also have enough computation<BR>&gt=3B &gt=3Btime to wash out the s=
> >tack check overhead.<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3B&gt=3B<BR>&gt=3B &gt=
> >=3B&gt=3B Also the end of the activation record must be written to at least=
> > once=2C<BR>&gt=3B &gt=3B&gt=3B or else the memory protection won't be trig=
> >gered.<BR>&gt=3B &gt=3B&gt=3B<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3BI was thinki=
> >ng (as an alternative mechanism) of having the compiler intentionally<BR>&g=
> >t=3B &gt=3Badd enough artificial write(s) as necessary to ensure storing wi=
> >thin the<BR>&gt=3B &gt=3Bred zone=2C and not just beyond it. This seems tri=
> >ckier to get right and<BR>&gt=3B &gt=3Bharder to distinguish after the fact=
> > from a NIL dereference.<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3B&gt=3B In any cas=
> >e if this is done properly the same mechanism I proposed for<BR>&gt=3B &gt=
> >=3B&gt=3B SIGSEGV ought to be able to catch stack overflow=2C no? Well=2C a=
> >s long as<BR>&gt=3B &gt=3B&gt=3B signals are delivered on a separate stack.=
> > If signals are delivered on<BR>&gt=3B &gt=3B&gt=3B the same stack=2C the s=
> >ignal handler would get nastier=2C it would have to<BR>&gt=3B &gt=3B&gt=3B =
> >make space through some manipulations (maybe temporarily unporotecting<BR>&=
> >gt=3B &gt=3B&gt=3B the redzone page?) for its own purposes... but I don't s=
> >ee why it<BR>&gt=3B &gt=3B&gt=3B couldn't be done.<BR>&gt=3B &gt=3B&gt=3B<B=
> >R>&gt=3B &gt=3B&gt=3B Not sure why I'm getting SIGILL... maybe I am getting=
> > my signal handler<BR>&gt=3B &gt=3B&gt=3B activated inside the redzone page=
> > because of a difference in signal<BR>&gt=3B &gt=3B&gt=3B handling..? I rem=
> >ember reading something about sigaltstack...<BR>&gt=3B &gt=3B&gt=3B<BR>&gt=
> >=3B &gt=3B&gt=3B I would of course love to be able to recover from stack ov=
> >erflow=2C too.<BR>&gt=3B &gt=3B&gt=3B In some sense=2C since it's a general=
> >ly unknown limit=2C it's even less of<BR>&gt=3B &gt=3B&gt=3B a fatal error =
> >than a NIL dereference (hence makes even more sense to<BR>&gt=3B &gt=3B&gt=
> >=3B catch it).<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3BI think this would be a nic=
> >e mechanism to have available. It would have to<BR>&gt=3B &gt=3Bbe used wit=
> >h some care. In any case=2C it would be really nice and more<BR>&gt=3B &gt=
> >=3Bfrequently so=2C to at least have runtime error messages that distinguis=
> >hed<BR>&gt=3B &gt=3Bstack overflow from NIL deref.<BR>&gt=3B &gt=3B<BR>&gt=
> >=3B &gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B Mika<BR>&gt=3B &gt=3B&gt=3B<BR>&gt=
> >=3B &gt=3B&gt=3B "Rodney M. Bates" writes:<BR>&gt=3B &gt=3B&gt=3B&gt=3B I a=
> >m pretty sure the cases I've seen are SIGSEGV on LINUXLIBC6 and AMD64_LINUX=
> >.<BR>&gt=3B &gt=3B&gt=3B&gt=3B Probably a fully protected guard page at the=
> > end of the stack. This technique<BR>&gt=3B &gt=3B&gt=3B&gt=3B always worri=
> >es me a bit because a procedure with a really big activation record<BR>&gt=
> >=3B &gt=3B&gt=3B&gt=3B could jump right past it. Probably it would almost a=
> >lways access the first page<BR>&gt=3B &gt=3B&gt=3B&gt=3B of the big area be=
> >fore storing anything into later pages.<BR>&gt=3B &gt=3B&gt=3B&gt=3B<BR>&gt=
> >=3B &gt=3B&gt=3B&gt=3B On 02/19/2011 05:27 PM=2C Mika Nystrom wrote:<BR>&gt=
> >=3B &gt=3B&gt=3B&gt=3B&gt=3B Ah=2C yes=2C stack protection.<BR>&gt=3B &gt=
> >=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B Do you know if it'=
> >s a SIGSEGV=2C not a SIGBUS? I know I have seen SIGILL on Macs.<BR>&gt=3B &=
> >gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B Hmm=2C I get SIG=
> >ILL on AMD64_FREEBSD as well:<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B =
> >&gt=3B&gt=3B&gt=3B&gt=3B time ../AMD64_FREEBSD/stubexample<BR>&gt=3B &gt=3B=
> >&gt=3B&gt=3B&gt=3B M-Scheme Experimental<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B=
> > LITHP ITH LITHENING.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B (define (f a=
> >) (+ (f (+ a 1)) (f (+ a 2))))<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B f<BR>&gt=
> >=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B (f 0)<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B=
> > Illegal instruction<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B 3.847u 0.368s 0:13.=
> >32 31.5% 2160+284478k 0+0io 0pf+0w<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&g=
> >t=3B &gt=3B&gt=3B&gt=3B&gt=3B What absolutely must not happen=2C of course=
> >=2C is that the runtime hangs<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B while exec=
> >uting only safe code...<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B=
> >&gt=3B&gt=3B&gt=3B Mika<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B=
> >&gt=3B&gt=3B&gt=3B "Rodney M. Bates" writes:<BR>&gt=3B &gt=3B&gt=3B&gt=3B&g=
> >t=3B&gt=3B I know of one other place the compilers rely on hardware memory =
> >protection<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B to detect a checked run=
> >time error=2C and that is stack overflow. This won't<BR>&gt=3B &gt=3B&gt=3B=
> >&gt=3B&gt=3B&gt=3B corrupt anything=2C but is hard to distinguish from dere=
> >ferencing NIL.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B This could probably=
> > be distinguished after the fact by some low-level=2C<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B target-dependent code. I have found it by looking at =
> >assembly code at<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B the point of fail=
> >ure--usually right after a stack pointer push.<BR>&gt=3B &gt=3B&gt=3B&gt=3B=
> >&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Detecting this via co=
> >mpiler-generated checks would probably be more<BR>&gt=3B &gt=3B&gt=3B&gt=3B=
> >&gt=3B&gt=3B extravagant than many other checks=2C as it is so frequent. I =
> >am not<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B aware of any really good so=
> >lution to this in any implementation of any<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B language.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B On 02/19/2011 02:38 PM=2C Mika Nystrom wrote:<B=
> >R>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Jay=2C sometimes I wonder abo=
> >ut you: this is a Modula-3 mailing list=2C<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B you know!<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR=
> >>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B "Corrupting the heap" is somet=
> hing that can only happen as a result of<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B=
> >&gt=3B&gt=3B an unchecked runtime error. Unchecked runtime errors cannot ha=
> >ppen in<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B modules not marked U=
> >NSAFE.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B SEGV is=2C however=2C used by the CM3 implement=
> >ation (and its predecessors)<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> > to signal a certain kind of *checked* runtime error=2C namely=2C the<BR>&g=
> >t=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B dereferencing of a NIL reference.=
> > Correct me if I am wrong=2C but an<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B attempt to dereference NIL is not going to leave the heap corrupt=
> >ed?<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&g=
> >t=3B&gt=3B&gt=3B&gt=3B And if you stick to safe code=2C the only SEGVs I th=
> >ink you get in the<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B current C=
> >M3 are ones from NIL dereferences.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> >&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Hence=2C as long as y=
> >ou stick with safe code=2C the only time the code I<BR>&gt=3B &gt=3B&gt=3B&=
> >gt=3B&gt=3B&gt=3B&gt=3B checked in earlier gets triggered is for NIL derefe=
> >rences=2C which should<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B never=
> > corrupt the heap. So SEGV is not sometimes=2C but in fact always<BR>&gt=3B=
> > &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B recoverable.<BR>&gt=3B &gt=3B&gt=3B&g=
> >t=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B :-)<B=
> >R>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&=
> >gt=3B&gt=3B&gt=3B Mika<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&g=
> >t=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B P.S. the bit above "if you stick =
> >to safe code": if you actually program in<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B Modula-3 you almost never use UNSAFE. I went through my rep=
> >ository and<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B I have 40 module=
> >s using UNSAFE out of a total of 4=2C559. Furthermore=2C<BR>&gt=3B &gt=3B&g=
> >t=3B&gt=3B&gt=3B&gt=3B&gt=3B many of the UNSAFE modules are glue code to Fo=
> >rtran routines=2C which<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B coul=
> >d relatively easily be verified to be safe in the Modula-3 sense.<BR>&gt=3B=
> > &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Almost all what remains is glue to so=
> >me C library=2C which wouldn't be<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B necessary if the rest of the world would wake up out of the dark ages=
> >=2C but<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B I don't have the tim=
> >e to rewrite every single library from scratch myself.<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<=
> >BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Jay K writes:<BR>&gt=3B &gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B --_a2a24b92-3b4c-456e-ab1b-c3f5e912=
> >854f_<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Content-Type: te=
> >xt/plain=3B charset=3D"iso-8859-1"<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> >&gt=3B&gt=3B Content-Transfer-Encoding: quoted-printable<BR>&gt=3B &gt=3B&g=
> >t=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> >&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Letting a=
> >ny code run after a SIGSEGV is dubious.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B&gt=3B&gt=3B Imagine the heap is corrupted.<BR>&gt=3B &gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B And then you run more code.<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B And the code happens to call malloc.<BR>&=
> >gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Or printf to log something=
> >.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D20<BR>&gt=3B &gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B I suppose there might be an applica=
> >tion that maps memory<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =
> >gradually=3D2C as pieces of a buffer are hit. Might.<BR>&gt=3B &gt=3B&gt=3B=
> >&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B - Jay<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =
> >=3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B To: m3deve=
> >l at elegosoft.com<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =
> >Date: Sat=3D2C 19 Feb 2011 10:29:30 -0800<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B From: mika at async.caltech.edu<BR>&gt=3B &gt=3B&g=
> >t=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Subject: [M3devel] SEGV mapping to=
> > RuntimeError<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =
> >=3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D20<BR>&=
> >gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Dear m3devel=3D2C<BR=
> >>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D20<BR>&gt=3B &g=
> >t=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B For a while it has annoyed m=
> >e that segmentation violations cause an<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B&gt=3B&gt=3B&gt=3B unconditional program abort. I've changed that now =
> >so that (under user<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B threads at least) we instead get a RuntimeError. Here's an example of<B=
> >R>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B the mechanism at =
> >work in an interactive Scheme environment. Consider<BR>&gt=3B &gt=3B&gt=3B&=
> >gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B the unhelpful interface and module Cras=
> >h:<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D20<BR>&gt=
> >=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B INTERFACE Crash=3D3B P=
> >ROCEDURE Me()=3D3B END Crash.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B MODULE Crash=3D3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =
> >PROCEDURE Me() =3D3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&g=
> >t=3B VAR ptr : REF INTEGER :=3D3D NIL=3D3B BEGIN<BR>&gt=3B &gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B ptr^ :=3D3D 0<BR>&gt=3B &gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B END Me=3D3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&=
> >gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B BEGIN END Crash.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&g=
> >t=3B&gt=3B&gt=3B&gt=3B =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> >&gt=3B&gt=3B Here's an example of what happens if you now call this from an=
> > interactiv=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B e<BR>&g=
> >t=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B interpreter that catc=
> >hes the exception RuntimeError.E:<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B&gt=3B&gt=3B =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B M-Scheme Experimental<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B LITHP ITH LITHENING.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B (require-modules "m3")<BR>&gt=3B &gt=3B&gt=3B&g=
> >t=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B #t<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B (Crash.Me)<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&g=
> >t=3B&gt=3B&gt=3B&gt=3B EXCEPTION! RuntimeError! Attempt to reference an ill=
> >egal memory location.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B&gt=3B (+ 3 4)=3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B 7<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D20<=
> >BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B I just realized =
> >I may have broken pthreads=3D2C let me go back and double-c=3D<BR>&gt=3B &g=
> >t=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B heck it.=3D20<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B runtime/POSIX and thread/POSIX don'=
> >t refer to the same thing do they...<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B&gt=3B Mika<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> > =3D20<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D<BR>&gt=3B &=
> >gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B --_a2a24b92-3b4c-456e-ab1b-c3f5e912854f_<BR>&gt=3B &g=
> >t=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Content-Type: text/html=3B charset=
> >=3D"iso-8859-1"<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Conten=
> >t-Transfer-Encoding: quoted-printable<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3B=
> >html&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3Bhead&=
> >gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3Bstyle&gt=
> >=3B&lt=3B!--<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B .hmmessag=
> >e P<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B {<BR>&gt=3B &gt=3B=
> >&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B margin:0px=3D3B<BR>&gt=3B &gt=3B&gt=3B=
> >&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B padding:0px<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B }<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B body.hmmessage<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B {<B=
> >R>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B font-size: 10pt=3D3B<BR=
> >>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B font-family:Tahoma<BR>&g=
> >t=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B }<BR>&gt=3B &gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B --&gt=3B&lt=3B/style&gt=3B<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3B/head&gt=3B<BR>&gt=3B &gt=3B&gt=3B&=
> >gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3Bbody class=3D3D'hmmessage'&gt=3B<BR>&gt=
> >=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Letting any code run after a=
> > SIGSEGV is dubious.&lt=3BBR&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> >&gt=3B&gt=3B Imagine the heap&amp=3Bnbsp=3D3Bis corrupted.&lt=3BBR&gt=3B<BR=
> >>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B And then you run more co=
> >de.&lt=3BBR&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B And =
> >the code happens to call malloc.&lt=3BBR&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B=
> >&gt=3B&gt=3B&gt=3B&gt=3B Or printf to log something.&lt=3BBR&gt=3B<BR>&gt=
> >=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &amp=3Bnbsp=3D3B&lt=3BBR&gt=
> >=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B I suppose there mi=
> >ght be an application that maps memory&lt=3BBR&gt=3B<BR>&gt=3B &gt=3B&gt=3B=
> >&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B gradually=3D2C as pieces of a buffer are hit=
> >. Might.&lt=3BBR&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> > &amp=3Bnbsp=3D3B&lt=3BBR&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B &amp=3Bnbsp=3D3B- Jay&lt=3BBR&gt=3B&amp=3Bnbsp=3D3B&lt=3BBR&gt=3B=
> ><BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &amp=3Bgt=3D3B To: m3=
> >devel at elegosoft.com&lt=3BBR&gt=3B&amp=3Bgt=3D3B Date: Sat=3D2C 19 Feb 2011 =
> >10:29:3=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B 0 -0800&lt=
> >=3BBR&gt=3B&amp=3Bgt=3D3B From: mika at async.caltech.edu&lt=3BBR&gt=3B&amp=3B=
> >gt=3D3B Subject: [M3devel]=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B SEGV mapping to RuntimeError&lt=3BBR&gt=3B&amp=3Bgt=3D3B&lt=3BBR&=
> >gt=3B&amp=3Bgt=3D3B&lt=3BBR&gt=3B&amp=3Bgt=3D3B Dear m3devel=3D<BR>&gt=3B &=
> >gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D2C&lt=3BBR&gt=3B&amp=3Bgt=3D3B=
> >&lt=3BBR&gt=3B&amp=3Bgt=3D3B For a while it has annoyed me that segmentatio=
> >n vi=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B olations cause=
> > an&lt=3BBR&gt=3B&amp=3Bgt=3D3B unconditional program abort. I've changed t=
> >hat =3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B now so that (u=
> >nder user&lt=3BBR&gt=3B&amp=3Bgt=3D3B threads at least) we instead get a Ru=
> >ntim=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B eError. Here's=
> > an example of&lt=3BBR&gt=3B&amp=3Bgt=3D3B the mechanism at work in an inte=
> >ract=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B ive Scheme env=
> >ironment. Consider&lt=3BBR&gt=3B&amp=3Bgt=3D3B the unhelpful interface and =
> >modu=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B le Crash:&lt=
> >=3BBR&gt=3B&amp=3Bgt=3D3B&lt=3BBR&gt=3B&amp=3Bgt=3D3B INTERFACE Crash=3D3B =
> >PROCEDURE Me()=3D3B END Cra=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B sh.&lt=3BBR&gt=3B&amp=3Bgt=3D3B&lt=3BBR&gt=3B&amp=3Bgt=3D3B MODUL=
> >E Crash=3D3B&lt=3BBR&gt=3B&amp=3Bgt=3D3B&lt=3BBR&gt=3B&amp=3Bgt=3D3B PROCED=
> >URE Me(=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B ) =3D3D&lt=
> >=3BBR&gt=3B&amp=3Bgt=3D3B VAR ptr : REF INTEGER :=3D3D NIL=3D3B BEGIN&lt=3B=
> >BR&gt=3B&amp=3Bgt=3D3B ptr^ :=3D3D=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B&gt=3B 0&lt=3BBR&gt=3B&amp=3Bgt=3D3B END Me=3D3B&lt=3BBR&gt=3B&amp=
> >=3Bgt=3D3B&lt=3BBR&gt=3B&amp=3Bgt=3D3B BEGIN END Crash.&lt=3BBR&gt=3B&amp=
> >=3Bgt=3D3B&lt=3BBR&gt=3B=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B &amp=3Bgt=3D3B Here's an example of what happens if you now call this=
> > from an inter=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B acti=
> >ve&lt=3BBR&gt=3B&amp=3Bgt=3D3B interpreter that catches the exception Runti=
> >meError.E:&lt=3BBR&gt=3B=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B &amp=3Bgt=3D3B&lt=3BBR&gt=3B&amp=3Bgt=3D3B M-Scheme Experimental&lt=
> >=3BBR&gt=3B&amp=3Bgt=3D3B LITHP ITH LITHENING.&lt=3BBR&gt=3B&amp=3B=3D<BR>&=
> >gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B gt=3D3B&amp=3Bgt=3D3B (req=
> >uire-modules "m3")&lt=3BBR&gt=3B&amp=3Bgt=3D3B #t&lt=3BBR&gt=3B&amp=3Bgt=3D=
> >3B&amp=3Bgt=3D3B (Crash.Me=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B )&lt=3BBR&gt=3B&amp=3Bgt=3D3B EXCEPTION! RuntimeError! Attempt to=
> > reference an illegal memory=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=
> >=3B&gt=3B location.&lt=3BBR&gt=3B&amp=3Bgt=3D3B&amp=3Bgt=3D3B (+ 3 4)&lt=3B=
> >BR&gt=3B&amp=3Bgt=3D3B 7&lt=3BBR&gt=3B&amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3BBR&=
> >gt=3B&amp=3Bgt=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D3=
> >B&lt=3BBR&gt=3B&amp=3Bgt=3D3B I just realized I may have broken pthreads=3D=
> >2C let me go back=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B a=
> >nd double-check it.&lt=3BBR&gt=3B&amp=3Bgt=3D3B runtime/POSIX and thread/PO=
> >SIX don't refer=3D<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B to =
> >the same thing do they...&lt=3BBR&gt=3B&amp=3Bgt=3D3B&lt=3BBR&gt=3B&amp=3Bg=
> >t=3D3B Mika&lt=3BBR&gt=3B&amp=3Bgt=3D3B&lt=3BBR&gt=3B =3D<BR>&gt=3B &gt=3B&=
> >gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3B/body&gt=3B<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3B/html&gt=3B=3D<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&=
> >gt=3B&gt=3B --_a2a24b92-3b4c-456e-ab1b-c3f5e912854f_--<BR>&gt=3B &gt=3B&gt=
> >=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &g=
> >t=3B&gt=3B<BR> </body>
> ></html>=
> >
> >--_ab466c75-f74a-4983-8fec-4f513f45fe0b_--
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20110222/df3ffe22/attachment-0002.html>


More information about the M3devel mailing list