is C++ worth it ?

B

BGB

On 7/31/2012 9:20 AM, Scott Lurndal wrote:
[...]
yeah, and nifty stuff can be done in signal handlers, potentially
including, among other things, triggering an exception to the thrown and
the stack to be unwound. whether or not this is a good idea is a
separate issue, normal C++ exceptions may not necessarily work (a custom
mechanism may be needed), and have not yet determined how portable or
versatile this is.

You cannot throw in a signal handler. The results are undefined
behavior. And it doesn't reliably work on any platform I know.
though, granted, some of this could be determined by testing it.

Testing won't give you many answers here. Throwing in a signal
handler is undefined behavior. It may work in your tests, but
not in any real application.

probably it wouldn't be "throwing" via using C++ exceptions directly
within the signal handler, but probably rather via a different mechanism.

one possible strategy would be using siglongjmp to get out of the singal
handler, and then throw at this point using a different
exception-handling mechanism.
 
N

Nick Keighley

the invisible ones are more worrisome IMHO. the operator overloading
"problem"
is a bit of a myth to my thinking.
Hmm... if one is so "unfamiliar" with the language that he doesn't
even know about operator overloading then really one should not read
the code and worry about how mouch code is execute when one line of
source code is read.  It's not as if C++ was the only language
offering operatior overloading.  Of course if the only language one
has ever been exposed to is Java, one might find C++ operator
overloading a novel concept.

Operator overloading can have two effect:
A) Improve the code base and make it more readable and more
maintainable.
B) Obfuscate the code base and make it less maintainable.

The difference between A) and B) is good programmers vs crap
programmers.  C++ philosophy is to give good programmers the tools to
write better programs.  Protection against B) is not built in the
language.

I'm not sure it could be built into *any* language. If the language
is expressive enough to be useful then you give the programmer the
freedom to express things badly.
 
N

none

I'm not sure it could be built into *any* language. If the language
is expressive enough to be useful then you give the programmer the
freedom to express things badly.

Absolutely, no language can stop crap programmers writing crap code.
Some languages are easier than other but the languages can only go so
far. Java excuse for not including operator overloading is very
flimsy and I reckon invalid. Operator overloading allows a good
programmer to write code that is actually more maintainable contrary
to some claims by Java proponents.

A good programmer will use operator overloading for something like a
Matrix class and implement Matrix addition and multiplication as
overloaded operators.

This leads to clearer code:

Matrix a, b;
// populate a and b;
Matrix c = a + b;
Matrix d = a * b;

The above is clear, usable, maintainable. Using a function named
"MatrixMult" or "MatrixAdd" would actually reduce the readability of
the code.


For example, a bad programmers will do silly things like:

class Rectangle
{
//...
Rectangle operator+(Rectangle &);
Rectangle operator+(Point &);
Rectangle operator+(Line &);
//...

Rectangle a, b;
Point p;
Rectangle c = a + b; // ?? WTF is adding 2 rectangles?
Rectangle d = a + p; // ?? WTF is adding a point to a rectangle?

Whatever the bad programmer meant would be much clearer if he used
informative functions named something like
Rectangle RetangleEnlarge(Rectangle &, int, int) or
Rectangle RectangleRelocate(Rectangle &, Point) or whatever is
actually intended but using the function name to make the code clear.

But in the absence of operator overload, the bad programmer would
probably just of called the function Add(...). In the absence of
function overloading, the bad programmer would probably have created
AddPoint(...) and AddRectangle(...)

So nothing a language can do.

Yannick
 
N

none

No. The former involves an unknown amount of code in any language. In
C++, the latter also involves an unknown amount of code (and that code
isn't limited to the definition of operator+, as copy or conversion
operators may be invoked before operator+ is called).

Operator overloading is the least of the issues; many languages allow
functions to have non-alphanumeric names. It's the constructors,
destructors, and conversion operators which are the main pitfall.

I am finding it interesting and worrying that you are bunching
destructors with conversion operator like that.

I am willing to agree that conversion operators have drawbacks that
may trump their benefits and that using ToInt(blah), ToString(foo) is
quite easy and make code clear. However, removing destructors from
the language would definitely make the language worse. They are one
of the most important thing in C++ and RAII is an fantastic tool to
make code higher quality, faster to write, easier to maintain.

Yannick
 
N

none

On 7/31/2012 9:20 AM, Scott Lurndal wrote:
[...]
yeah, and nifty stuff can be done in signal handlers, potentially
including, among other things, triggering an exception to the thrown and
the stack to be unwound. whether or not this is a good idea is a
separate issue, normal C++ exceptions may not necessarily work (a custom
mechanism may be needed), and have not yet determined how portable or
versatile this is.

You cannot throw in a signal handler. The results are undefined
behavior. And it doesn't reliably work on any platform I know.
though, granted, some of this could be determined by testing it.

Testing won't give you many answers here. Throwing in a signal
handler is undefined behavior. It may work in your tests, but
not in any real application.

probably it wouldn't be "throwing" via using C++ exceptions directly
within the signal handler, but probably rather via a different mechanism.

one possible strategy would be using siglongjmp to get out of the singal
handler, and then throw at this point using a different
exception-handling mechanism.

And close your eyes, put you fingers in your ears while signing loudly:
"THIS WILL WORK! THIS WILL WORK! ..."

??

As mentinoned, signal handler are out of scope of C++ but this is well
documented that you should not try to do anything too fancy in a
signal handler. It's potentially even worse in C++, your suggestion
would siglongjmp outside the previously executing function, all
automatics would not get destroyed potentially leading to very
undesireable consequences

Yannick
 
N

Nobody

I am willing to agree that conversion operators have drawbacks that may
trump their benefits and that using ToInt(blah), ToString(foo) is quite
easy and make code clear. However, removing destructors from the language
would definitely make the language worse. They are one of the most
important thing in C++ and RAII is an fantastic tool to make code higher
quality, faster to write, easier to maintain.

I'm not suggesting that destructors are a Bad Thing overall, just that
they're a pitfall. If you're going to write non-trivial destructors, it's
especially important that they're thread-safe, exception-safe and
otherwise devoid of surprises.
 
G

Gerhard Fiedler

James said:
yeah, and nifty stuff can be done in signal handlers, potentially
including, among other things, triggering an exception to the thrown
and the stack to be unwound. [...]

You cannot throw in a signal handler. The results are undefined
behavior. And it doesn't reliably work on any platform I know.

What does then the following GCC option do? [1]

-fnon-call-exceptions
Generate code that allows trapping instructions to throw exceptions.
Note that this requires platform-specific runtime support that does
not exist everywhere. Moreover, it only allows trapping instructions
to throw exceptions, i.e. memory references or floating-point
instructions. It does not allow exceptions to be thrown from
arbitrary signal handlers such as SIGALRM.

I know that this is not portable, and that this is not defined in the
C++ standard. (In this sense it is "undefined behavior", but this
doesn't mean that a given compiler and platform can't define it.)

This seems to indicate that GCC allows to throw an exception in a signal
handler for a SIGSEGV, at least on some platforms.

Or do I read this wrong?

Thanks,
Gerhard

[1] http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
 
J

James Kanze

James Kanze wrote:
yeah, and nifty stuff can be done in signal handlers, potentially
including, among other things, triggering an exception to the thrown
and the stack to be unwound. [...]
You cannot throw in a signal handler. The results are undefined
behavior. And it doesn't reliably work on any platform I know.
What does then the following GCC option do? [1]
-fnon-call-exceptions
Generate code that allows trapping instructions to throw exceptions.
Note that this requires platform-specific runtime support that does
not exist everywhere. Moreover, it only allows trapping instructions
to throw exceptions, i.e. memory references or floating-point
instructions. It does not allow exceptions to be thrown from
arbitrary signal handlers such as SIGALRM.
I know that this is not portable, and that this is not defined in the
C++ standard. (In this sense it is "undefined behavior", but this
doesn't mean that a given compiler and platform can't define it.)
This seems to indicate that GCC allows to throw an exception in a signal
handler for a SIGSEGV, at least on some platforms.

It does. I'd be interested in seeing how they implement it.
And on what platforms it's supported.

I suspect that the limitation to SIGSEGV is somehow linked to
the fact that you can't get a SIGSEGV at the critical moment,
after a successful call but before the necessary information has
been set up in the stack frame. Which isn't true for Intel
boxes, I don't think.

And does it work for all sources of SIGSEGV? Most Unix systems
I know convert stack overflow into SIGSEGV (which may mean that
you can't catch the signal).

Anyway, it's interesting information. *Most* of the time, you
don't want to convert the signal into an exception---you want an
immediate core dump. But for the rare times you do want the
exception...
 
J

James Kanze

James Kanze wrote:
On Tuesday, July 31, 2012 8:12:11 PM UTC+1, BGB wrote:
yeah, and nifty stuff can be done in signal handlers, potentially
including, among other things, triggering an exception to the thrown
and the stack to be unwound. [...]
You cannot throw in a signal handler. The results are undefined
behavior. And it doesn't reliably work on any platform I know.
What does then the following GCC option do? [1]
-fnon-call-exceptions
Generate code that allows trapping instructions to throw exceptions.
Note that this requires platform-specific runtime support that does
not exist everywhere. Moreover, it only allows trapping instructions
to throw exceptions, i.e. memory references or floating-point
instructions. It does not allow exceptions to be thrown from
arbitrary signal handlers such as SIGALRM.
I know that this is not portable, and that this is not defined in the
C++ standard. (In this sense it is "undefined behavior", but this
doesn't mean that a given compiler and platform can't define it.)
This seems to indicate that GCC allows to throw an exception in a signal
handler for a SIGSEGV, at least on some platforms.
James said "reliably". It's likely that it would work properly when
catching a SIGFPE. However, with SIGSEGV all bets are off, since the
unwind tables used during exception delivery could have been corrupted,
or some object referenced in the try/catch block may have been corrupted.

I think that there are some obvious restrictions; if the SIGSEGV
comes because you're memset'ing a local array, and you got the
count wrong by a couple of meg (overwriting *all* of the stack);
quite obviously, there's no way that they can make it work. A
more interesting question is if the SIGSEGV is due to stack
overflow.

And while the traditional core dump is usually what you want,
there are exceptions where being able to catch it most of the
time is useful.
 
M

Melzzzzz

What if the destructor in question is responsible for ending some
threads accessing the object being destroyed?

thread joining in destructor was common practice...
 
B

BGB

James Kanze said:
James Kanze wrote:
On Tuesday, July 31, 2012 8:12:11 PM UTC+1, BGB wrote:
yeah, and nifty stuff can be done in signal handlers, potentially
including, among other things, triggering an exception to the thrown
and the stack to be unwound. [...]
You cannot throw in a signal handler. The results are undefined
behavior. And it doesn't reliably work on any platform I know.
What does then the following GCC option do? [1]
-fnon-call-exceptions
Generate code that allows trapping instructions to throw exceptions.
Note that this requires platform-specific runtime support that does
not exist everywhere. Moreover, it only allows trapping instructions
to throw exceptions, i.e. memory references or floating-point
instructions. It does not allow exceptions to be thrown from
arbitrary signal handlers such as SIGALRM.
I know that this is not portable, and that this is not defined in the
C++ standard. (In this sense it is "undefined behavior", but this
doesn't mean that a given compiler and platform can't define it.)
This seems to indicate that GCC allows to throw an exception in a signal
handler for a SIGSEGV, at least on some platforms.

It does. I'd be interested in seeing how they implement it.
And on what platforms it's supported.

I suspect that the limitation to SIGSEGV is somehow linked to
the fact that you can't get a SIGSEGV at the critical moment,
after a successful call but before the necessary information has
been set up in the stack frame. Which isn't true for Intel
boxes, I don't think.

And does it work for all sources of SIGSEGV? Most Unix systems
I know convert stack overflow into SIGSEGV (which may mean that
you can't catch the signal).

If you setup an alternate stack for signals (sigaltstack(2)),
you should be ok as far as catching the signal goes.

You likely cannot throw an exeception then since the alternate
stack starts with the signal handler activation record. Siglongjmp
would work, but after the longjmp, you'd still have the problem
where you don't know _what_ corruption resulted in the SIGSEGV.

in many/most cases, probably.

there are some cases though where one may know what caused it.

consider for example a person implementing a garbage collector which
scans the stack. upon trying to read from a guard-page, then a signal
may be generated, and can be fairly safely handled (the signal then
essentially serving as an indication that the end of the stack being
scanned has been reached). (whether or not this is a good way to
implement stack-scanning in a GC is a secondary issue).

likewise, in such a scenario, recovering from a signal may be relatively
safe (rather then in the general case, where a SIGSEGV or similar can be
taken as an indication that something went wrong).
 
A

Andre Kaufmann

A perfect language would generate an exception with a stacktrace upon an
Access Violation, which is much more preferable to a Core Dump. For

Why? You can load the Core Dump with Visual Studio under Windows and
then you have stack traces of all threads running when the access
violation occured.


generate such a dump when the exception is not caught (AFAIK, Win32 does
not offer a setting that generates dumps upon Access Violations).

The opposite is the case. Windows does generate dumps by default - always.
If no debugger is running the default debugger will be started.
- Either Dr. Watson or in newer versions of Windows Windows Error Reporting
is started.
- On Blue Screens (core dumps) a mini dump file will be written

These applications can send dump files to a central server (application must
be registered
by the developer for that), where they can be downloaded.
Optionally they can generated by calling a single Win API function or copied
from the Windows
temporary directory, which is generated by Dr. Watson / WER (Windows Error
Reporting).
Thanks in advance,
Stuart

Andre
 
S

Stuart

That's a problem regarding the platform, *not* C++. The last
thing you want in such cases is for the stack to be unwound.
You want a dump of the state exactly where the error occurred.
A core dump, under Unix. (From what I understand, it's possible
to configure Windows to behave correctly as well.)

Actually, I'm relying heavily on the stack unwind, since this
constitutes a kind of emergency stop procedure for me. The only
alternative would be to create a separate stack with emergency stop
actions that should be executed when an Access Violation occurs, but
that would be equally cumbersome.
How is unwinding the stack preferrable to a core dump. The
stack trace tells where you were, but doesn't offer any
possiblity to see the surrounding state at each level.
Unwinding the stack looses important information.

I totally agree. But I thought that if backtraces in exceptions will
never make it into the standard, then core dumps will be out of the
question.

So let me rephrase it: Ideally, I would like the language to dump when
an Access Violation occurs (gives me all the information to debug the
programming error later on), and then to unwind the stack (brings the
measurement machine back into a defined state). Unfortunately, the C++
standard just says that upon Access Violations I will enter the land of UB.

I wonder how all those life-critical components for example in the
medical or aviation business are written. Probably with some compiler
that won't bust upon Access Violations. I mean, what good is a core dump
when your plane is already cruising at an altitude of 10.000 feet?

Regards,
Stuart
 
S

Stuart

The opposite is the case. Windows does generate dumps by default - always.
If no debugger is running the default debugger will be started.
- Either Dr. Watson or in newer versions of Windows Windows Error Reporting
is started.
- On Blue Screens (core dumps) a mini dump file will be written

These applications can send dump files to a central server (application
must be registered
by the developer for that), where they can be downloaded.
Optionally they can generated by calling a single Win API function or
copied from the Windows
temporary directory, which is generated by Dr. Watson / WER (Windows
Error Reporting).

Gosh, I never even suspected such a thing. I think what fooled me into
this belief is that the window that informs you about an Access
Violation tells you that it wants to send some information to Microsoft
but never even mentions that it generated a core dump file. Our
workaround was to run the measurement application from the debugger, but
that is not an option when the application should run in the field.

Thanks,
Stuart
 
J

Jorgen Grahn

.
Actually, I'm relying heavily on the stack unwind, since this
constitutes a kind of emergency stop procedure for me. The only
alternative would be to create a separate stack with emergency stop
actions that should be executed when an Access Violation occurs, but
that would be equally cumbersome. ....
So let me rephrase it: Ideally, I would like the language to dump when
an Access Violation occurs (gives me all the information to debug the
programming error later on), and then to unwind the stack (brings the
measurement machine back into a defined state).

There's possibly one non-C++ mechanism at play here.

If you're into controlling hardware (or other I/O not heavily
encapsulated by the OS) you often have OS mechanisms as a last resort.

E.g. if you control a flatbed scanner you want the light to go off and
the camera arm to move back to its parked position. A well-designed
device driver for that will see its file descriptor (in Unix) close as
the application crashes, and reset itself. Placing responsibility for
the reset on the application would be a very bad idea. Even if you
changed C++ so you could reliably do that before crashing, the device
could still not be safely used from C, Python, Perl, ...
Unfortunately, the C++
standard just says that upon Access Violations I will enter the land of UB.

I wonder how all those life-critical components for example in the
medical or aviation business are written. Probably with some compiler
that won't bust upon Access Violations.

Such software must always rely on assumptions not found in the C++
standard, e.g. what the OS promises. I think the situation would be
the same if you chose any other mainstream language.
I mean, what good is a core dump
when your plane is already cruising at an altitude of 10.000 feet?

Ever watch Discovery Channel? Lots of people are very interested in
finding out why a plane crashed. I'm sure there are very detailed
requirements for this.

/Jorgen
 
N

Nobody

So actually the destructor is one piece of code
where one actually does not need to worry about thread-safety at all.

Other threads shouldn't be accessing the object being destroyed, but the
destructor may need to access referenced objects.

In theory, the issues can be dealt with by ensuring that all such accesses
are thread-safe (e.g. protected by a mutex). In practice, fine-grained
locking can have signicant performance costs, so it's not uncommon to seek
strategies to reduce this. Some of those strategies push the burden of
thread-safety onto callers, which may be problematic when calls are
implicit.
 
B

BGB

There's possibly one non-C++ mechanism at play here.

If you're into controlling hardware (or other I/O not heavily
encapsulated by the OS) you often have OS mechanisms as a last resort.

E.g. if you control a flatbed scanner you want the light to go off and
the camera arm to move back to its parked position. A well-designed
device driver for that will see its file descriptor (in Unix) close as
the application crashes, and reset itself. Placing responsibility for
the reset on the application would be a very bad idea. Even if you
changed C++ so you could reliably do that before crashing, the device
could still not be safely used from C, Python, Perl, ...

yeah. it also makes sense to try to design software so that it can
recover from crashes.

usually, this often means explicit recover mechanisms, say the app can
fix its data once it restarts, and generally avoid leaving data in a
state where it will be "dead in the water" if a crash occurs.


drivers can often help here.

likewise, even a lot of hardware itself has its own safety mechanisms,
usually in the form of on-device firmware, and sometimes via
electromechanical mechanisms or similar, such as in the case of HDDs and
similar (for example, if an HDD looses power, it will automatically park
the heads, ...).

sadly, OS filesystem drivers and similar are often not as robustly
designed, as damage in the right spot may often render the drive unable
to recover (say, damage to the partition table / MBR, corruption of the
boot-sector or other core filesystem structures, ...).

things like journals/... can help, but usually performance and low
overhead are preferred over robustness, which is often left over to the
HDD (which itself is left implementing things like ECC and
sector-remapping, ..., at some cost to total drive capacity).


but, ultimately, I think this is also part of why file-based software
(and OS's which does full reboots, and recompiling software from
source-code, ...) are ultimately preferable to software based solely on
"process images" and "living systems", since in this latter case, if
something crashes or goes terribly wrong, there may be no recovery
(whereas with a file-based system, in the worst case, assuming the HDD
still works, a person can still recover all of their files from the
drive, reinstall the OS and software, and get back to whatever they were
doing).


Such software must always rely on assumptions not found in the C++
standard, e.g. what the OS promises. I think the situation would be
the same if you chose any other mainstream language.


Ever watch Discovery Channel? Lots of people are very interested in
finding out why a plane crashed. I'm sure there are very detailed
requirements for this.

I once saw an episode of Nova talking about a plane that crashed.
basically, something went wrong (wind speed sensor froze, started
returning 0 wind-speed, causing control software to crash), the plane
sent a crash dump back to the manufacturer over radio, and then the
plane promptly crashed into the ocean.

the manufacturer later found the crash dump and this helped them
identify why the plane crashed.
 
A

Andre Kaufmann

Gosh, I never even suspected such a thing.

I still wonder why such a feature isn't communicated widely by Microsoft.
but never even mentions that it generated a core dump file.

Yes, not directly. But there is a link in the lower half of the dialog,
"additional info" or "view attached files" or something like that.

If you click on that it will open a list with some files. One of these
files is the dump file (*.dmp).


Additionally since IIRC Windows Vista you can write a dump file
of an application by right clicking on it's entry in the task manager.


I've added a kind of live debugging feature to our application.
You can load directly a snapshot dump file from inside Visual Studio
over a http channel of our running application and debug for example
deadlocks.
Thanks,
Stuart

Your welcome,
Andre
 
G

Gerhard Fiedler

BGB said:
James Kanze said:
On Tuesday, July 31, 2012 8:12:11 PM UTC+1, BGB wrote:
yeah, and nifty stuff can be done in signal handlers, potentially
including, among other things, triggering an exception to the thrown
and the stack to be unwound. [...]

You cannot throw in a signal handler. The results are undefined
behavior. And it doesn't reliably work on any platform I know.

What does then the following GCC option do? [1]

-fnon-call-exceptions
Generate code that allows trapping instructions to throw exceptions.
Note that this requires platform-specific runtime support that does
not exist everywhere. Moreover, it only allows trapping instructions
to throw exceptions, i.e. memory references or floating-point
instructions. It does not allow exceptions to be thrown from
arbitrary signal handlers such as SIGALRM.

I know that this is not portable, and that this is not defined in the
C++ standard. (In this sense it is "undefined behavior", but this
doesn't mean that a given compiler and platform can't define it.)

This seems to indicate that GCC allows to throw an exception in a signal
handler for a SIGSEGV, at least on some platforms.

It does. I'd be interested in seeing how they implement it.
And on what platforms it's supported.

I suspect that the limitation to SIGSEGV is somehow linked to
the fact that you can't get a SIGSEGV at the critical moment,
after a successful call but before the necessary information has
been set up in the stack frame. Which isn't true for Intel
boxes, I don't think.

And does it work for all sources of SIGSEGV? Most Unix systems
I know convert stack overflow into SIGSEGV (which may mean that
you can't catch the signal).

If you setup an alternate stack for signals (sigaltstack(2)),
you should be ok as far as catching the signal goes.

You likely cannot throw an exeception then since the alternate
stack starts with the signal handler activation record. Siglongjmp
would work, but after the longjmp, you'd still have the problem
where you don't know _what_ corruption resulted in the SIGSEGV.

in many/most cases, probably.

there are some cases though where one may know what caused it.

consider for example a person implementing a garbage collector which
scans the stack. upon trying to read from a guard-page, then a signal
may be generated, and can be fairly safely handled (the signal then
essentially serving as an indication that the end of the stack being
scanned has been reached). (whether or not this is a good way to
implement stack-scanning in a GC is a secondary issue).

likewise, in such a scenario, recovering from a signal may be
relatively safe (rather then in the general case, where a SIGSEGV or
similar can be taken as an indication that something went wrong).

FWIW, it was such "controlled" segfaults of which I was thinking, not
the rogue type where you really don't know what and why.

I don't think it would work for SIGSEGVs because of stack overflow.
Either your stack is bad, or you're using a separate stack for signal
handlers, in which case it seems that the mechanism won't work.

I haven't yet found an answer to the platform support. (GCC
documentation only says "Note that this requires platform-specific
runtime support that does not exist everywhere.") If anybody happens to
have a pointer for documentation about the platform support of this
feature, I'd be grateful.

Thanks,
Gerhard
 
B

BGB

BGB said:
On Tuesday, July 31, 2012 8:12:11 PM UTC+1, BGB wrote:
yeah, and nifty stuff can be done in signal handlers, potentially
including, among other things, triggering an exception to the thrown
and the stack to be unwound. [...]

You cannot throw in a signal handler. The results are undefined
behavior. And it doesn't reliably work on any platform I know.

What does then the following GCC option do? [1]

-fnon-call-exceptions
Generate code that allows trapping instructions to throw exceptions.
Note that this requires platform-specific runtime support that does
not exist everywhere. Moreover, it only allows trapping instructions
to throw exceptions, i.e. memory references or floating-point
instructions. It does not allow exceptions to be thrown from
arbitrary signal handlers such as SIGALRM.

I know that this is not portable, and that this is not defined in the
C++ standard. (In this sense it is "undefined behavior", but this
doesn't mean that a given compiler and platform can't define it.)

This seems to indicate that GCC allows to throw an exception in a signal
handler for a SIGSEGV, at least on some platforms.

It does. I'd be interested in seeing how they implement it.
And on what platforms it's supported.

I suspect that the limitation to SIGSEGV is somehow linked to
the fact that you can't get a SIGSEGV at the critical moment,
after a successful call but before the necessary information has
been set up in the stack frame. Which isn't true for Intel
boxes, I don't think.

And does it work for all sources of SIGSEGV? Most Unix systems
I know convert stack overflow into SIGSEGV (which may mean that
you can't catch the signal).

If you setup an alternate stack for signals (sigaltstack(2)),
you should be ok as far as catching the signal goes.

You likely cannot throw an exeception then since the alternate
stack starts with the signal handler activation record. Siglongjmp
would work, but after the longjmp, you'd still have the problem
where you don't know _what_ corruption resulted in the SIGSEGV.

in many/most cases, probably.

there are some cases though where one may know what caused it.

consider for example a person implementing a garbage collector which
scans the stack. upon trying to read from a guard-page, then a signal
may be generated, and can be fairly safely handled (the signal then
essentially serving as an indication that the end of the stack being
scanned has been reached). (whether or not this is a good way to
implement stack-scanning in a GC is a secondary issue).

likewise, in such a scenario, recovering from a signal may be
relatively safe (rather then in the general case, where a SIGSEGV or
similar can be taken as an indication that something went wrong).

FWIW, it was such "controlled" segfaults of which I was thinking, not
the rogue type where you really don't know what and why.

I don't think it would work for SIGSEGVs because of stack overflow.
Either your stack is bad, or you're using a separate stack for signal
handlers, in which case it seems that the mechanism won't work.

I haven't yet found an answer to the platform support. (GCC
documentation only says "Note that this requires platform-specific
runtime support that does not exist everywhere.") If anybody happens to
have a pointer for documentation about the platform support of this
feature, I'd be grateful.

I think GCC has this support on Linux and x86.

what little I am aware of is that GCC (often?) implements exception
unwinding using a variant of the DWARF debug format, and by making calls
to API functions. the API magic then proceeds basically to start
unwinding call frames and restoring registers.

the uncertainty I have is regarding how Linux goes about transferring
control to the signal handler. there is a certain possibility that
control will pass through code which potentially lacks
exception-handling data, at which case the behavior of the unwinding
logic would be uncertain, though it is just as possible that the
unwinding API could just as easily detect/handle this case specially
(restoring the preserved state or similar, and resuming normal unwind
behavior within the code which generated the signal).

granted, yes, even if it does work, it is probably not exactly portable,
so other options may still be better.

I have not actually tried any of this personally though. most of my
experience has more been with longjmp and Win32 SEH and implementing a
"fake SEH" mechanism and similar (basically, unwinding via recursive
longjmp), which are admittedly a bit different from using C++ exceptions.


or such...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top