By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,165 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

question about "setjmp()"

P: n/a
Hello all,

I used setjmp() in a recent of program of mine (it is not completed, so
I have not the chance to test it out yet). I am not very profocient in
C coding as are some of my co-workers. They (my co-workers) say (with
vehement ardor ;) ) that the usage of setjmp() emplyoyed in function"C"
that was called from function "B" that was called from function "A"
that was called form the main(), will cause havoc in the stack. And it
makes sense, since the longjmp() function/macro has no way of knowing
how high is the stack is, in order to pop out the excess elements in
order to render it as it was when the setjmp() function first set the
"jmpbuf" environment. However, if that were the case the existence of
the setjmp()/longjmp() function pair will not exist.
So, is setjmp()/longjmp() reliable as a "non-local goto", or will it
eventually cause a stack overflow or some other problem?

P.S. I am using the setjmp()/longjmp() only for error handling.

Regards,
-Roger

Oct 1 '06 #1
Share this Question
Share on Google+
15 Replies


P: n/a
rover8898 wrote:
Hello all,

I used setjmp() in a recent of program of mine (it is not completed, so
I have not the chance to test it out yet). I am not very profocient in
C coding as are some of my co-workers. They (my co-workers) say (with
If you're not proficient with C then I definitely do not recommend playing
around with any *jmp() function. Even when you do become proficient, I'd find
another method. I personally never use them, but that doesn't necessarily
mean they are useless.
Oct 1 '06 #2

P: n/a
It's nice you have coworkers to help you. And they seem to be well
enough informed to realize there is a bit of fiddling required if
you're nested 33 levels deep and want to jump out to the mail program.

But setjmp/longjmp manage this just fine. The basic rigamarole is
setjmp() saves all the CPU registers, including the stack pointer, in
its save area parameter. Then longjmp() mostly just restores those
register values, including the old program counter. Quick and slick
and should probably be used sparingly. But in some cases it's almost
unavoidable.

In more refined languages, like old Pascal, there is no restriction on
goto's, and the compiler generates the right code to do the
inter-procedure jumps. And as a side-benefit, the compiler knows what
files are local to all the intermediate levels, and closes them. Poor
setjmp() doesnt have any way of knowing what files are open, so you'll
have to write your own code to clean up any open files.

Oct 1 '06 #3

P: n/a
Ancient_Hacker wrote:
It's nice you have coworkers to help you. And they seem to be well
enough informed to realize there is a bit of fiddling required if
you're nested 33 levels deep and want to jump out to the mail program.

But setjmp/longjmp manage this just fine. The basic rigamarole is
setjmp() saves all the CPU registers, including the stack pointer, in
its save area parameter. Then longjmp() mostly just restores those
register values, including the old program counter. Quick and slick
and should probably be used sparingly. But in some cases it's almost
unavoidable.

In more refined languages, like old Pascal, there is no restriction on
goto's, and the compiler generates the right code to do the
inter-procedure jumps. And as a side-benefit, the compiler knows what
files are local to all the intermediate levels, and closes them. Poor
setjmp() doesnt have any way of knowing what files are open, so you'll
have to write your own code to clean up any open files.
A.H. touches on one aspect of a larger problem: longjmp()
simply blasts past all the intermediate call levels back to the
setjmp() caller, without giving the skipped levels any chance to
clean up *anything* -- he mentions open files that don't get
closed, but it's the same problem with malloc()ed memory that
doesn't get free()d, painted windows that don't get erased, and
squitted wadgetts that don't get squatted.

In short, despite the word "long" in the name, longjmp() should
really only be used for "short" jumps within a tightly-coupled set
of functions. The functions between the setjmp() and the longjmp()
must be aware of their precarious position and must be written in a
way that requires no cleanup that longjmp() might cancel. Functions
can be written this way, and written usefully, but it is no small
task to write them *and* defend them against future changes. Hence
the advice: Avoid setjmp()/longjmp() most of the time, and when you
do use them, use them "locally." They are not general-purpose.

--
Eric Sosman
es*****@acm-dot-org.invalid
Oct 2 '06 #4

P: n/a
Ancient_Hacker wrote:
>
.... snip ...
>
In more refined languages, like old Pascal, there is no restriction
on goto's, and the compiler generates the right code to do the
inter-procedure jumps. And as a side-benefit, the compiler knows
what files are local to all the intermediate levels, and closes
them. Poor setjmp() doesnt have any way of knowing what files are
open, so you'll have to write your own code to clean up any open
files.
I am very sympathetic with the original C decision to ban goto out
of functions. I did the same in my PascalP, because the end
objective was micro-computers (e.g. 8080) with limited memory. All
functions were packed into segments and consisted of position
independent code. The segments could be freely swapped in and out
of memory, i.e. I had virtual memory for code. The functions were
accessed by a segment jump table, which could hold up to 127 entry
points. Allowing extra-functional jumps would have meant including
rarely used exit points in the table, doubling its size. So I
settled for one terminate system function, the equivalent of a C
exit function.

The result was the ability to run a full one-pass compiler, almost
completely standard compliant, in as little as 5k of object code
space. The disk thrashed a bit by then.

Another thing longjmp can lose is malloced pointers, creating
memory leaks.

--
Some informative links:
<news:news.announce.newusers
<http://www.geocities.com/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/>

Oct 2 '06 #5

P: n/a

rover8898 wrote:
Hello all,

I used setjmp() in a recent of program of mine (it is not completed, so
I have not the chance to test it out yet). I am not very profocient in
C coding as are some of my co-workers. They (my co-workers) say (with
vehement ardor ;) ) that the usage of setjmp() emplyoyed in function"C"
that was called from function "B" that was called from function "A"
that was called form the main(), will cause havoc in the stack. And it
makes sense, since the longjmp() function/macro has no way of knowing
how high is the stack is, in order to pop out the excess elements in
order to render it as it was when the setjmp() function first set the
"jmpbuf" environment. However, if that were the case the existence of
the setjmp()/longjmp() function pair will not exist.
So, is setjmp()/longjmp() reliable as a "non-local goto", or will it
eventually cause a stack overflow or some other problem?
Using setjmp() when
you are a few levels down will not cause problems. Part of
the information setjmp() saves is how deep the stack is. All longjmp()
has to do is keep poping elements from the stack until the stack
depth is correct (this may be as simple as resetting the stack
pointer).

On the other hand why are you using setjmp()/longjmp() at all. While I
am told they have their uses, I am also told that they are difficult
to use correctly. I have never used them.
P.S. I am using the setjmp()/longjmp() only for error handling.
Try unwinding the stack yourself. Hijack the return value so
that every function returns SUCCESS of FAILURE. Check the
result of every function call. If the return is FAILURE and
there is something you can do, do it, otherwise clean
up and return FAILURE.

You will soon find yourself writing reams of virtually identical code.
You may ask yourself, "Why isn't the compiler handling this?"
You will learn to appreciate exceptions.

- William Hughes

Oct 2 '06 #6

P: n/a
"Eric Sosman" <es*****@acm-dot-org.invalidwrote in message
news:1_******************************@comcast.com. ..
Ancient_Hacker wrote:
>It's nice you have coworkers to help you. And they seem to be
well
enough informed to realize there is a bit of fiddling required if
you're nested 33 levels deep and want to jump out to the mail
program.

But setjmp/longjmp manage this just fine. The basic rigamarole is
setjmp() saves all the CPU registers, including the stack pointer, in
its save area parameter. Then longjmp() mostly just restores those
register values, including the old program counter. Quick and slick
and should probably be used sparingly. But in some cases it's
almost
unavoidable.

In more refined languages, like old Pascal, there is no restriction
on
goto's, and the compiler generates the right code to do the
inter-procedure jumps. And as a side-benefit, the compiler knows
what
files are local to all the intermediate levels, and closes them.
Poor
setjmp() doesnt have any way of knowing what files are open, so
you'll
have to write your own code to clean up any open files.

A.H. touches on one aspect of a larger problem: longjmp()
simply blasts past all the intermediate call levels back to the
setjmp() caller, without giving the skipped levels any chance to
clean up *anything* -- he mentions open files that don't get
closed, but it's the same problem with malloc()ed memory that
doesn't get free()d, painted windows that don't get erased, and
squitted wadgetts that don't get squatted.

In short, despite the word "long" in the name, longjmp() should
really only be used for "short" jumps within a tightly-coupled set
of functions. The functions between the setjmp() and the longjmp()
must be aware of their precarious position and must be written in a
way that requires no cleanup that longjmp() might cancel.
.... unless, of course, you've called setjmp() just before calling
longjmp(), so that the jumped-to section of code can jump back. This
is, I believe, a standard mechanism for implementing user-mode threads
on platforms that don't natively support them.
Functions can be written this way, and written usefully, but it is no
small task to write them *and* defend them against future changes.
Hence the advice: Avoid setjmp()/longjmp() most of the time, and
when you do use them, use them "locally." They are not general-
purpose.
That sounds like a variation on the rule against using goto. The
problems with set/longjmp() are worse, but in general one should not use
either unless you're savvy enough to explain _why_ the rule doesn't
apply in a particular case and how there's no better (or even possible)
technique. There's virtually always a safer, more elegant way of doing
whatever needs doing.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

--
Posted via a free Usenet account from http://www.teranews.com

Oct 2 '06 #7

P: n/a
Stephen Sprunk wrote:
"Eric Sosman" <es*****@acm-dot-org.invalidwrote in message
news:1_******************************@comcast.com. ..
>[...]
In short, despite the word "long" in the name, longjmp() should
really only be used for "short" jumps within a tightly-coupled set
of functions. The functions between the setjmp() and the longjmp()
must be aware of their precarious position and must be written in a
way that requires no cleanup that longjmp() might cancel.

... unless, of course, you've called setjmp() just before calling
longjmp(), so that the jumped-to section of code can jump back. This
is, I believe, a standard mechanism for implementing user-mode threads
on platforms that don't natively support them.
It might be "standard" in the sense of "widespread," but it's
not "Standard." 7.12.2.1, paragraph 2, with footnote:

[...] if the function containing the invocation of the
setjmp macro has terminated execution _208) in the interim,
[...] the behavior is undefined.

208) For example, by executing a return statement or because
another longjmp call has caused a transfer to a setjmp
invocation in a function earlier in the set of nested calls.

So the "ping-pong" scheme you describe only works reliably if both
pairs of setjmp()/longjmp() are in the same function -- and if they
are in the same function, why not use goto?

--
Eric Sosman
es*****@acm-dot-org.invalid

Oct 2 '06 #8

P: n/a
In article <45***********************@free.teranews.com>,
Stephen Sprunk <st*****@sprunk.orgwrote:
>This
is, I believe, a standard mechanism for implementing user-mode threads
on platforms that don't natively support them.
s/standard mechanism/ancient hack/

-- Richard
Oct 2 '06 #9

P: n/a
rover8898 wrote:
Hello all,

I used setjmp() in a recent of program of mine (it is not completed, so
I have not the chance to test it out yet). I am not very profocient in
C coding as are some of my co-workers. They (my co-workers) say (with
vehement ardor ;) ) that the usage of setjmp() emplyoyed in function"C"
that was called from function "B" that was called from function "A"
that was called form the main(), will cause havoc in the stack. And it
makes sense, since the longjmp() function/macro has no way of knowing
how high is the stack is, in order to pop out the excess elements in
order to render it as it was when the setjmp() function first set the
"jmpbuf" environment. However, if that were the case the existence of
the setjmp()/longjmp() function pair will not exist.
So, is setjmp()/longjmp() reliable as a "non-local goto", or will it
eventually cause a stack overflow or some other problem?

P.S. I am using the setjmp()/longjmp() only for error handling.
You may have a look at:

http://cern.ch/laurent.deniau/html/e...exception.html
http://cern.ch/laurent.deniau/html/o...tml#Exceptions

I haven't really used these codes in my projects, it was more a didactic
approach of the concept. But I am using the same techniques with success
in a much more advanced OO framework.

a+, ld.
Oct 2 '06 #10

P: n/a
"rover8898" <ro*******@hotmail.comwrote in message
news:11*********************@k70g2000cwa.googlegro ups.com...
Hello all,

I used setjmp() in a recent of program of mine (it is not completed, so
I have not the chance to test it out yet). I am not very profocient in
C coding as are some of my co-workers.
Then you probably want to look at some of the web tutorials on how these
routines work. They don't often do what you expect.
In particualr note the warnings about auto variables in the calling
routine...
They (my co-workers) say (with
vehement ardor ;) ) that the usage of setjmp() emplyoyed in function"C"
that was called from function "B" that was called from function "A"
that was called form the main(), will cause havoc in the stack.
setjmp() saves the stack status. As longjmp() returns back to the same
location the should be fine.
>And it
makes sense, since the longjmp() function/macro has no way of knowing
how high is the stack is, in order to pop out the excess elements in
order to render it as it was when the setjmp() function first set the
"jmpbuf" environment.
It does not need to know where it is now. It just has to put it back how it
was when setjmp() was called.
>However, if that were the case the existence of
the setjmp()/longjmp() function pair will not exist.
So, is setjmp()/longjmp() reliable as a "non-local goto", or will it
eventually cause a stack overflow or some other problem?
No it just re-winds the stack...... Main thing is to be carefull of auto
variables in the routine that calls setjmp(). If I recall things properly
P.S. I am using the setjmp()/longjmp() only for error handling.
Thats about all its good for. Even then its probably to avoid it, if
possible...
Regards,
-Roger

Oct 2 '06 #11

P: n/a
"Eric Sosman" <es*****@acm-dot-org.invalidwrote in message
news:vf******************************@comcast.com. ..
Stephen Sprunk wrote:
>"Eric Sosman" <es*****@acm-dot-org.invalidwrote in message
news:1_******************************@comcast.com ...
>>[...]
In short, despite the word "long" in the name, longjmp() should
really only be used for "short" jumps within a tightly-coupled set
of functions. The functions between the setjmp() and the longjmp()
must be aware of their precarious position and must be written in a
way that requires no cleanup that longjmp() might cancel.

... unless, of course, you've called setjmp() just before calling
longjmp(), so that the jumped-to section of code can jump back. This
is, I believe, a standard mechanism for implementing user-mode
threads on platforms that don't natively support them.

It might be "standard" in the sense of "widespread," but it's
not "Standard."
I meant widespread; I'd have capitalized standard if I thought ISO had
endorsed such a practice.
7.12.2.1, paragraph 2, with footnote:

[...] if the function containing the invocation of the
setjmp macro has terminated execution _208) in the interim,
[...] the behavior is undefined.

208) For example, by executing a return statement or because
another longjmp call has caused a transfer to a setjmp
invocation in a function earlier in the set of nested calls.
I don't have the context handy, but isn't that referring to jumping into
a function (instance) that has returned previously?
So the "ping-pong" scheme you describe only works reliably if both
pairs of setjmp()/longjmp() are in the same function -- and if they
are in the same function, why not use goto?
Scenario:
Thread A calls fread(), which does a setjmp() and then longjmp() to
thread B. Thread B continues execution of a different instance of
fread(), returns to user code, and calls fwrite(), which does a setjmp()
and then a longjmp() back to thread A, which continues its instance of
fread(). "Ping-pong" is definitely an apt description for this.

However, is there any undefined behavior there? It seems well-defined
to me, or perhaps that's just because I've only seen *jmp() used on
implementations which work as expected in that case. I've never had a
reason to use *jmp() myself, so I've never studied the mechanism in
detail. Ditto for goto; I've seen one example of a necessary goto, but
I've never written any code using one.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

--
Posted via a free Usenet account from http://www.teranews.com

Oct 2 '06 #12

P: n/a
>"Eric Sosman" <es*****@acm-dot-org.invalidwrote in message
>news:vf******************************@comcast.com ...
> 7.12.2.1, paragraph 2, with footnote:
[...] if the function containing the invocation of the
setjmp macro has terminated execution _208) in the interim,
[...] the behavior is undefined.
In article <45***********************@free.teranews.com>
Stephen Sprunk <st*****@sprunk.orgwrote:
>I don't have the context handy, but isn't that referring to jumping into
a function (instance) that has returned previously?
Yes. But note that calling longjmp() constitutes "returning"
from the function calling longjmp(), and also any other function,
"up the chain" of stack-frames until it reaches the one that
called setjmp().

Imagine you have the following call stack:

main()
| has its own stuff in its stack-frame.
| calls f.
+-+------
|
v
f()
| has its own stuff in its frame, perhaps including a
| jmp_buf that it passes to setjmp() (remember that jmp_buf
| is an array type so it gets the address of the array's first
| element and can thus fill in the array).
+-+-------
|
v
g()
| has its own stuff in its frame.
| calls h.
+-+-------
|
v
h()
| calls longjmp(), passing f's jmp_buf (perhaps via "global
| variable" pointer, or as parameter from f to g to h)
+---------

The longjmp() in h() wipes out the frames for h() and g(), because
it is doing a long-distance "goto" to get back to the goto-label
set in f() (i.e., the call to setjmp()).

The only time longjmp() does not "return" from the function
calling longjmp() is when the target of the goto is within that
same function. For instance, if, in the setup above, f() does
a longjmp() that simply goes back into itself, no frames are
removed.
>Scenario:
Thread A calls fread(), which does a setjmp() ...
So far, this is OK.
>... and then longjmp() to thread B.
This longjmp() wipes out all the frames in "Thread A" that are
"below" the call to setjmp() in Thread B. There must be a direct
sequence of such calls from "Thread B" into "Thread A" for this
longjmp() to succeed at all, of course.

(Note that a sequence of "stack frames" forms a linked list, as
illustrated by the arrows above. The implementation normally has
the arrows pointing upward, to the previous frame, rather than
downward, to the next frame; debuggers may [or may not] invert the
arrows, as I have done, to show you the call stack from the top
down instead of bottom up. Note also that on many architectures,
most -- though not all -- "stack frames" are physically adjacent
to their neighboring frames, so that in many cases the pointer-arrows
can be eliminated entirely, depending on ABI and/or language. In
"pure C" they can usually be eliminated, though adding C99's VLAs,
or the alloca() function, requires adding at least *some*
pointer-arrows.)
>Thread B continues execution of a different instance of
fread(), returns to user code, and calls fwrite(), which does a setjmp()
and then a longjmp() back to thread A, ...
It cannot do this, because those frames (for Thread A) no longer
exist, having been wiped out by the goto into Thread B (which, to
make the first longjmp() work at all, called "Thread A" directly,
kind of eliminating the whole point of threads in the first place,
but oh well :-) ).
>... which continues its instance of
fread(). "Ping-pong" is definitely an apt description for this.

However, is there any undefined behavior there? It seems well-defined
to me, or perhaps that's just because I've only seen *jmp() used on
implementations which work as expected in that case.
There are some implementations in which longjmp()'s "destruction"
of the stack-frames for all the intermediate functions is sort of
a "virtual destruction", with no memory ever getting overwritten.
In this case, all the "destroyed" frames are still sitting intact
in RAM. If you can (somehow) arrange for "thread A" and "thread
B" to be sufficiently far apart, stack-frame-allocation-wise, so
that neither thread ever disturbs the other's "abandoned", "virtually
but not physically destroyed" stack frames, then at some point the
"abandoned" frames can be magically re-inhabited and, poof, everything
is back the way it was. (Meanwhile the other threads' stack frames
are now "abandoned", until another longjmp() "magically resurrects"
them.)

However, there are also implementations on which the destruction
is very real, and/or in which longjmp() makes sure that there is
a clear chain of arrows from "longjmp call" to "setjmp label".
In the latter case, a longjmp() that tries to switch threads
aborts immediately, while in the former, a longjmp() that tries
to switch threads -- and perhaps succeeds -- plants a time-bomb
that goes off when the suspended thread is resumed.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Oct 2 '06 #13

P: n/a
Thank you all for your responses/input.
-Roger

Oct 3 '06 #14

P: n/a
"Chris Torek" <no****@torek.netwrote in message
news:ef*********@news4.newsguy.com...
In article <45***********************@free.teranews.com>
Stephen Sprunk <st*****@sprunk.orgwrote:
>>I don't have the context handy, but isn't that referring to jumping
into
a function (instance) that has returned previously?

Yes. But note that calling longjmp() constitutes "returning"
from the function calling longjmp(), and also any other function,
"up the chain" of stack-frames until it reaches the one that
called setjmp().

Imagine you have the following call stack:

main()
| has its own stuff in its stack-frame.
| calls f.
+-+------
|
v
f()
| has its own stuff in its frame, perhaps including a
| jmp_buf that it passes to setjmp() (remember that jmp_buf
| is an array type so it gets the address of the array's first
| element and can thus fill in the array).
+-+-------
|
v
g()
| has its own stuff in its frame.
| calls h.
+-+-------
|
v
h()
| calls longjmp(), passing f's jmp_buf (perhaps via "global
| variable" pointer, or as parameter from f to g to h)
+---------

The longjmp() in h() wipes out the frames for h() and g(), because
it is doing a long-distance "goto" to get back to the goto-label
set in f() (i.e., the call to setjmp()).

The only time longjmp() does not "return" from the function
calling longjmp() is when the target of the goto is within that
same function. For instance, if, in the setup above, f() does
a longjmp() that simply goes back into itself, no frames are
removed.
All correct if you assume one stack and one thread, which is of course
how C89/C99 treat the world.

<OT>
However, an implementation of threads seems to require that each thread
have its own stack. In that case, calling longjmp() would logically
change to the stack referenced in the jmp_buf. If the current stack
weren't saved first by a call to setjmp(), it'd be lost, but as I said,
one would typically call setjmp() right before the longjmp() to save the
current thread's execution state.

Now, that requires that the implementation provide a non-standard means
to create a second stack, but once that is done a reasonable
implementation of set/longjmp() should be able to use the multiple
stacks without difficulty.

....
There are some implementations in which longjmp()'s "destruction"
of the stack-frames for all the intermediate functions is sort of
a "virtual destruction", with no memory ever getting overwritten.
In this case, all the "destroyed" frames are still sitting intact
in RAM. If you can (somehow) arrange for "thread A" and "thread
B" to be sufficiently far apart, stack-frame-allocation-wise, so
that neither thread ever disturbs the other's "abandoned", "virtually
but not physically destroyed" stack frames, then at some point the
"abandoned" frames can be magically re-inhabited and, poof, everything
is back the way it was. (Meanwhile the other threads' stack frames
are now "abandoned", until another longjmp() "magically resurrects"
them.)
That, I understand, is how user-mode threads work. Keep Stack A and
Stack B far enough apart in memory that they won't run into each other,
and then you can jump between them without harm. Provided, of course,
there's no processor logic that prevents longjmp() from mucking with the
stack/frame pointers.
However, there are also implementations on which the destruction
is very real, and/or in which longjmp() makes sure that there is
a clear chain of arrows from "longjmp call" to "setjmp label".
In the latter case, a longjmp() that tries to switch threads
aborts immediately, while in the former, a longjmp() that tries
to switch threads -- and perhaps succeeds -- plants a time-bomb
that goes off when the suspended thread is resumed.
I suppose it's reasonable that a software implementation may crater on
such usage, but unless the hardware actively enforces such destruction,
why would an implementation bother doing so?

I suppose there's also a problem for systems that don't have a stack,
but I don't know how such a system would work even without throwing
threads into the picture, having never seen such a machine.
</OT>

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

--
Posted via a free Usenet account from http://www.teranews.com

Oct 3 '06 #15

P: n/a
>"Chris Torek" <no****@torek.netwrote in message
>news:ef*********@news4.newsguy.com...
>>... there are ... implementations ... in which longjmp() makes
sure that [the jmp_buf being passed to it is a direct antecedent
in its call chain, and abort the program if not].
>In [this] case, a longjmp() that tries to switch threads
aborts immediately ...
In article <45***********************@free.teranews.com>
Stephen Sprunk <st*****@sprunk.orgwrote:
>I suppose it's reasonable that a software implementation may crater on
such usage, but unless the hardware actively enforces such destruction,
why would an implementation bother doing so?
If you have ever debugged a program that longjmp()ed into a "dead"
stack frame, and then continued to run for some time so that it
did very bad things to the contents of memory before crashing in
such a way that no debugger can unscramble the mess, you probably
would not ask this question. :-)

(I have done this with several programs. I think one of them was
a version of "sendmail". Switching to a longjmp() that aborted
immediately upon a "bad call" -- one in which the target frame
pointer was "below" the current frame pointer, on that system --
caught the problem where it occurred, so that debugging became
easy.)
>I suppose there's also a problem for systems that don't have a stack,
but I don't know how such a system would work even without throwing
threads into the picture ...
Systems that lack hardware stacks have to create fake software ones
for C code. These "software stacks" need not have contiguous frames.
If they *do* not have contiguous frames, adding threads to the system
is actually easier! Otherwise you end up with the same problem as
on systems that have hardware stacks: you have to pick out a "stack
size" for each thread, and you wind up with a "one size fits none"
situation, rather like off-the-rack clothing. :-)

("Real" thread switching may, depending on the target architecture,
do more than just changing stacks. For instance, on some machines,
you might want to set up a software "red zone" rather than using
protected pages between stacks, perhaps because the latter chews up
large chunks of address space, or is unavailable.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Oct 6 '06 #16

This discussion thread is closed

Replies have been disabled for this discussion.