Thrown exception doesn't get caught where it "should."

C

Chris

Hello all...

I have a program with the following structure (all classes
mentioned are of my own creation, and none of the classes contain try
or catch blocks):

- main() consists of a large try block with several catch blocks I
will describe below. main(), within the try block, declares, and
implicitly default-constructs, a variable (object) of class AppDBConn.

- The default AppDBConn constructor uses initialization syntax to
invoke a one-argument (std::string) constructor of its base class
IniDBConn.

- The one-argument IniDBConn constructor uses 'new' to construct an
IniFile object, again passing one argument (std::string). (IniFile
derives separately from IniCheck.)

- There is a hierarchy of exception classes: IniError derives from
RunError, which derives from Error, which is a base class.



My problem is this: main() has catch blocks for IecIniError and
"..." (catch-all). The IniFile constructor encounters an error and
invokes a base-class (IniCheck) method to process it, which culminates
with the throwing of an IniError. None of main()'s catch blocks --
including the catch-all block -- catch this, and the program SEGVs
instead of terminating gracefully.

By way of troubleshooting, If I eliminate main()'s use of
AppDBConn, and instead construct an IniDBConn object directly, the
problem remains; the thrown exception is not caught.

If I eliminate main()'s use of AppDBConn -and- IniDBConn, and
construct an IniFile object directly, the problem disappears; the
thrown exception IS caught, in main()'s catch block for IniError.

I need to fix this misbehavior, but am at a loss to do so. My
questions are:

1) Are there any coding (mis)constructs that cause this?

2) Could it be a problem with the OS (SuSE Linux 9) and/or compiler
(g++ 3.3.3)?

3) What else might I be overlooking?

I would be grateful for any light anyone could shed.

Thanks in advance,

Chris
 
J

JE

If I eliminate main()'s use of AppDBConn -and- IniDBConn, and
construct an IniFile object directly, the problem disappears; the
thrown exception IS caught, in main()'s catch block for IniError.
<snip>

Perhaps you have another exception while the first exception is
unwinding?
 
I

Ian Collins

Chris said:
Hello all...
My problem is this: main() has catch blocks for IecIniError and
"..." (catch-all). The IniFile constructor encounters an error and
invokes a base-class (IniCheck) method to process it, which culminates
with the throwing of an IniError. None of main()'s catch blocks --
including the catch-all block -- catch this, and the program SEGVs
instead of terminating gracefully.
At a guess, it his hitting a coding bug in your exception, if an
exception is thrown and not caught, the program will abort, not crash.

Use your debugger to catch the segv.
 
C

Chris

Thanks, JE and Ian. That was fast! :)

At a guess, it his hitting a coding bug in your exception, if an
exception is thrown and not caught, the program will abort, not crash.

Hm. I've been scouring the code for two days now, looking for coding
bugs, without finding any. I don't suppose that this particular
behavior would point to any specific kind of bug? Would the error be
in the exception-class code, or in one of the classes whose removal
from the chain eliminates the problem?
Use your debugger to catch the segv.

Catch as in C++ 'catch' statement, or are you speaking generally? I've
been looking at the code with the debugger and everything is normal
right up until the throw statement SEGVs. The location of the SEGV as
reported by the debugger is std::string::assign(). Prior to this I had
a SEGV on a statement

m_lastStatus = "";

where m_lastStatus is an std::string. Offhand it looks like there's
some sort of weirdness attached to std::string, but I still can't
figure out WHAT.

I guess I'll keep looking!

Chris
 
I

Ian Collins

Chris said:
Hm. I've been scouring the code for two days now, looking for coding
bugs, without finding any. I don't suppose that this particular
behavior would point to any specific kind of bug? Would the error be
in the exception-class code, or in one of the classes whose removal
from the chain eliminates the problem?




Catch as in C++ 'catch' statement, or are you speaking generally? I've
been looking at the code with the debugger and everything is normal
right up until the throw statement SEGVs. The location of the SEGV as
reported by the debugger is std::string::assign(). Prior to this I had
a SEGV on a statement

m_lastStatus = "";
I can only guess, but that would be memory corruption screwing up the
std::string object.
 
K

kwikius

Thanks, JE and Ian. That was fast! :)


bugs, without finding any. I don't suppose that this particular
behavior would point to any specific kind of bug? Would the error be
in the exception-class code, or in one of the classes whose removal
from the chain eliminates the problem?

been looking at the code with the debugger and everything is normal
right up until the throw statement SEGVs. The location of the SEGV as
reported by the debugger is std::string::assign(). Prior to this I had
a SEGV on a statement

m_lastStatus = "";

where m_lastStatus is an std::string. Offhand it looks like there's
some sort of weirdness attached to std::string, but I still can't
figure out WHAT.

A wild guess...

You could try changing to:

m_lastStatus = std::string("");

I had some sort of issue with this in VC7.1 and above is IIRC is how I
solved it

HTH

regards
Andy Little
 
R

Ron Natalie

kwikius said:
You could try changing to:

m_lastStatus = std::string("");

I had some sort of issue with this in VC7.1 and above is IIRC is how I
solved it
Never heard of any such problem in any version of VC++.

However, there is one thing to worry about. None of the std::string
functions that take char*'s guard against being passed something
other than a pointer to the beginning of a null terminated string.
Especially, passing a null pointer is right out!
 
C

Chris

You could try changing to:

m_lastStatus = std::string("");

Thanks, Andy. Unfortunately, this was the very first thing I tried --
which I guess I should have mentioned in the first place -- and it
didn't fix the problem.

However, I do seem to have "solved" the problem, by which I mean that I
set about simplifying the code so as to "distill it down to the
smallest code that demonstrates the problem," as the saying goes -- and
somewhere along the line the problem disappeared.

Specifically, recall that I originally said that

In that constructor, _before_ the 'new IniFile( string )' construction,
I had a couple of string assignments to member variables:

m_where = "IniDBConn constructor";
m_what = "One-argument construction";

(probably not those exact literals). I took these out.

I then also removed the three-argument IniError constructor --

IniError(std::string msg, std::string where, std::string what) :
RunError (where + ", " + what + ": " + msg) { }

When I rebuilt, the problem was gone.

When I took these statements out and rebuilt my program, the problem
was gone; the thrown IniError was correctly caught in main().

The only construction that seems a little dodgy to me is the string
concatenation in the constructor hand-off between IniError and
RunError. Is that a known no-no?

Thanks, everyone, for all your help.

Chris
 

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,020
Latest member
GenesisGai

Latest Threads

Top