Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / November 2007

Tip: Looking for answers? Try searching our database.

/clr and exceptions from native libs

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
rwf_20 - 29 Nov 2007 16:34 GMT
I'm seeing incorrect (I think) behavior in the event of an exception
thrown in a native C++ library.  Basically, the stack appears to
unwind correctly if the caller is native, but incorrectly if the
caller is /clr.  Consider the following C++ static lib:

// ehTestLib.h
#include <iostream>
class worker {
public:
    ~worker() { std::cerr << "~worker()\n"; }
    void doTheThingThatThrows();
};

class supervisor {
public:
    ~supervisor() { std::cerr << "~supervisor()\n"; }
    void supervise();

private:
};

class director {
public:
    ~director() { std::cerr << "~director()\n"; }
    void direct();
};

// ehTestLib.cpp
#include "ehTestLib.h"
void worker::doTheThingThatThrows() {
    throw "";
}

void supervisor::supervise() {
    worker w;
    w.doTheThingThatThrows();
}

void director::direct() {
    supervisor().supervise();
}

I build this lib via:
cl /c /EHsc /MD ehTestLib.cpp
link /out:ehTestLib.lib ehTestLib.obj

I test this library with the following code:
// ehTestApp.cpp
#include "ehTestLib.h"
int main() {
 try {
   director().direct();
 }
 catch (...) {
 }
}

The expected output is, obviously:
~worker()
~supervisor()
~director()

Now, when I build ehTestApp.cpp as native C++:
cl /c /EHsc /MD ehTestApp.cpp
link /out:ehTestApp.exe ehTestLib.lib ehTestApp.obj

I get the expected output.  However, when I build it as managed C++:
cl /c /clr /EHa /MD ehTestApp.cpp
link /out:ehTestApp.exe ehTestLib.lib ehTestApp.obj

I get the following only:
~director

Two other tidbits:
1. The problem as something to do with the throw being in a separate
library.  If I simply include the code directly in the exe, everything
works as expected in native and /clr.
2. The native example works the same with /EHa or /EHsc.

I'm hoping someone out there has some insight as to why this is
happening.  I've read through all of the related MSDN stuff (starting
with http://msdn2.microsoft.com/en-us/library/x057540h(VS.80).aspx),
but I don't see any mention of this.

Thanks in advance,
Ryan
rwf_20 - 29 Nov 2007 16:53 GMT
> Two other tidbits:
> 1. The problem as something to do with the throw being in a separate
> library.  If I simply include the code directly in the exe, everything
> works as expected in native and /clr.
> 2. The native example works the same with /EHa or /EHsc.

Another thing I just discovered:  this all works as expected with the
7.1 version of the compiler.  The incorrect behavior I describe only
occurs in 8.0 (VS 2005).

Ryan
Ben Voigt [C++ MVP] - 29 Nov 2007 18:16 GMT
> I'm seeing incorrect (I think) behavior in the event of an exception
> thrown in a native C++ library.  Basically, the stack appears to
> unwind correctly if the caller is native, but incorrectly if the
> caller is /clr.  Consider the following C++ static lib:

I see you compiled the host with both /EHsc and /EHa, but did you try the
library with /EHa?

> // ehTestLib.h
> #include <iostream>
[quoted text clipped - 77 lines]
> Thanks in advance,
> Ryan
rwf_20 - 29 Nov 2007 18:57 GMT
> I see you compiled the host with both /EHsc and /EHa, but did you try the
> library with /EHa?

Never thought to try that, but it fixes the issue.  Thanks for the
tip.  I'm curious as to why it's now necessary to enable SEH in my
native libs?  Something to do with the way the exceptions are handled
in the presence of the native/managed 'bridge'?

Are there any side-effects to using /EHa that I should know about?

Thanks again,
Ryan
Ben Voigt [C++ MVP] - 29 Nov 2007 20:06 GMT
>> I see you compiled the host with both /EHsc and /EHa, but did you try the
>> library with /EHa?
[quoted text clipped - 3 lines]
> native libs?  Something to do with the way the exceptions are handled
> in the presence of the native/managed 'bridge'?

Because it forces the C++ compiler to use the OS exception support.  The
.NET runtime only handles OS exceptions (SEH), so a /EHsc C++ exception
(which may be stored in an internal variable in the C++ runtime library)
won't be seen by the catch blocks, and hence the unwinding won't be done.

The stronger rule is to never throw exceptions across language boundaries,
because exceptions are language-specific (think MSIL for .NET, not
C#;VB.NET;F#;JavaScript.NET;C++/CLI;IronPython).

Possibly the C++/CLI compiler should catch both synchronous native C++
exceptions and SEH-based exceptions, but apparently it doesn't.

> Are there any side-effects to using /EHa that I should know about?

Some optimizations aren't possible (removing try-blocks around functions
that can't throw, that sort of thing).

Also catch (...) clauses will catch non-C++ exceptions.

> Thanks again,
> Ryan

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.