Solved

Throwing exceptions under Solaris

Posted on 2000-02-18
15
291 Views
Last Modified: 2013-12-05
I have an exception class under NT inside a DLL. When I want to throw this exception, I use "throw new TException ("hello")".

Then I port this class to Solaris, but when the program flow gets to the catch statement, an "Abort" message appears and then the program stops. This doesn't happen under Windows NT : when a cpp throws the exception, the catch statement intercepts the exception and the program flow continues.

This is the code :

** In TException.so file :

class TException : public exception
{
public :
        TException (char *string);
        ~TException ();
}

** In TMyClass.so :

void TMyClass::f ()
{
       throw new TException ("hello");
}

** In main.cpp :

try {
    myclass->f ();
}
catch (TException *e) {
    printf ("catch...\n");

    delete e;
}

The message "catch..." doesn't appear. Appear an "Abort" message.

What's the matter?
0
Comment
Question by:Lucsat
  • 8
  • 7
15 Comments
 
LVL 22

Expert Comment

by:nietod
Comment Utility
There's no way to tell from just that.  Could you show us some code?
0
 

Author Comment

by:Lucsat
Comment Utility
Edited text of question.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Please do not edit the question once a dialog has started.  It makes it impossible for other experts to follow.

I don't see a problem there.  If you move the code to a single file does the problem go away?
0
 

Author Comment

by:Lucsat
Comment Utility
Sorry for edit the question. I never use experts-exchange service and I'm a bit lost.

When I move all the code to a single file, then the problem disappears.

Another case : if main.cpp throws a TException exception, the catch statement works correctly.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> Sorry for edit the question.
You shouldn't even be given the option to edit after a comment has been posted.  Hopefully that will be fixed in the next version.

That is sounding a lot like it has something to do with the implimentaiton of exceptions and DLLs on solaris.   (i.e it is not a C++ issue, but an OS-specific issue.)  There is a chance that you can get some more info here, but I sort-of doubt it.  Because this is so specific, I would consider gettting help from the compiler manufacturer or OS.  (maybe wait a little first to see what happens here.)  And there is a good chance that help might only be an explanation of why it doesn't work, not how to make it work.

Although I can't image why it wouldn't work...
0
 

Author Comment

by:Lucsat
Comment Utility
Adjusted points to 50
0
 

Author Comment

by:Lucsat
Comment Utility
I have found the problem :

When I declared the function that throws the exception, I use "MyClass::f () throws (TException)".

When I deleted the "throws (TException)" statement, then all was OK.

But, I don't understand why under Windows NT this statement functions but under Solaris or Linux doesn't works correctly.

What's the matter?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 22

Accepted Solution

by:
nietod earned 60 total points
Comment Utility
That makes sense!  You didn't mention you had exception specifications in your code  (I should have though to ask.)

The problem is you were violating the specification.

continues.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> When I declared the function that throws the
>> exception, I use "MyClass::f () throws (TException)".

This specificaton assures that the f() throws only TException (or types that convert to it) or doesn't throw at all.  If you attempt to throw any type that can't be converted to TException, the program won't allow it and will abort the program with an unhandled exception.

But you are throwing TException right?  wrong.  You are throwing "TException *".  This is a diferent type.  If you changed the throw code from

throw new TException ("hello");

to

throw TException ("hello");

Then you should be okay.

By the way, it is often best to throw exceptions by value, not pointer and is usually best to catch excetptions by reference, not value.

Let me know if you have any quesions.
0
 

Author Comment

by:Lucsat
Comment Utility
Adjusted points to 60
0
 

Author Comment

by:Lucsat
Comment Utility
There are only one problem : the locality of the throwed object.

When I use

throw TException ("hello")       (internally I store "hello")

in a function, this object only live in this function, and when an external function catch that exception, the "hello" string doesn't exist because in the TException destructor I use delete [] the_string.

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Does TException store a pointer the string?  If so, did you write a working copy constructor (and while you are at it operator =) for the class.  The defaullt versions of these two procedures don't work right when you have data members that are to point to "private" blocks of allocated memory.  And the copy constructor will almost assuredly be used when throwing an exception.
0
 

Author Comment

by:Lucsat
Comment Utility
The definition of TException are :

class TException
{
public:
   TException (char *pszString);
   ~TException ();

private:
   char *m_pszString;
};

TException::TException (char *pszString)
{
   m_pszString = new char (strlen (pszString) + 1);

   strcpy (m_pszString, pszString);
}

TException::~TException ()
{
   delete [] m_pszString;
}

I don't understand when you say me "write a working copy constructor". How I can to throw an exception using the copy constructor? How I can to change the char pointer to another solution (I'm sure that an static array is a solution, but I like to reserve memory as I need too much...)
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
If that is the entire class definition it definitely has a problem.   The problem has nothing to do with exceptions.  This is enherint in the current class design.  i.e. the class behaves poorly with or without an exception.  For example try

int main()
{
   TException A("this is a test.");

   {
      TException B(A);
   }
   return 0;
}

This should yeild an error at the end of main().  Actually this WILL yield  an error at the end of main, the only dobut I have is that your debugger might not pick it up.  try it.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
The problem is that you have not provided a copy constructor so when TException object's are copied the default copy constructor is used.  This copy constructor does not work well for this case.  What it does is copy ever single member of the class.  So as a result the new TException object has the same pointer in m_pszString as the old.  i.e you have two objects that are both sharing the same string data.  when the first object is destroyed it deletes teh string and the 2nd object is left holding a pointer to string data that has been deleted.  

You need to write a copy constructor for this class that copies the string data.  Then it will be safe to make copies of TException.   (And the compiler makes copies when you throw--as well as other times.)

The same problem exists for operator =.  I you ever do an = with Texception you will have a problem too.  So you need to define you own operator = or make sure you never use operator = (declare it private for example) on this class.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Every server (virtual or physical) needs a console: and the console can be provided through hardware directly connected, software for remote connections, local connections, through a KVM, etc. This document explains the different types of consol…
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now