Operating System - HP-UX
1753681 Members
5941 Online
108799 Solutions
New Discussion юеВ

Re: Crash seen from c++ runtime exception handling code

 
Rohitash Panda
New Member

Crash seen from c++ runtime exception handling code

Hi,
I am working on HP PARISC64 11.31. The problem, succinctly, is that certain exceptions are not caught when thrown from a C++ shared library that is run from a C executable. This results in some run-time errors from the C++ runtime libraries and imminent crash with the below stack :

The top of the frame looks like as below :
#0 0xc0000000000fa0ec in _lwp_kill+0x2c () from /usr/lib/pa20_64/libpthread.1
#1 0xc0000000000b934c in pthread_kill+0x6ec () from /usr/lib/pa20_64/libpthread.1
#2 0xc0000000001a66bc in raise+0x6c () from /usr/lib/pa20_64/libc.2
#3 0xc0000000001f6864 in abort_C+0xbc () from /usr/lib/pa20_64/libc.2
#4 0xc0000000001f698c in abort+0x1c () from /usr/lib/pa20_64/libc.2
#5 0xc00000000024bee0 in std::terminate+0x48 () from /lib/pa20_64/libCsup_v2.2
#6 0xc00000000024ccf0 in ThrowException+0xf8 () from /lib/pa20_64/libCsup_v2.2
#7 0xc00000000024c514 in __throw__FPvT1+0x15c () from /lib/pa20_64/libCsup_v2.2
#8 0xc00000000e7f4670 in TxsOqRenameConflictChecker::throwException+0x270 () from /ade/b/622489922/oracle/lib/libolapapi11.sl
#9 0xc00000000e7f3ed4 in TxsOqRenameConflictChecker::checkForConflicts+0x12c () from /ade/b/622489922/oracle/lib/libolapapi11.sl
#10 0xc00000000e7f357c in TxsOqIDRegenerator::regenerateIDs+0x19c () from /ade/b/622489922/oracle/lib/libolapapi11.sl
#11 0xc00000000ebc7348 in TxsOqMetadataContext::getModifiedObjects+0x1a8 () from /ade/b/622489922/oracle/lib/libolapapi11.sl

Has someone faced similar problems and can there be any workarounds ? Also if someone could speculate about the possible reasons for the crash or how we can go about trying to debug the issue . This certainly looks to be some issue with the C++ runtime code on the platform and there might be some way , maybe some linker/compiler flags to avoid it .

Much appreciate your valuable comments .

Thanks.

Thanks.
13 REPLIES 13
Zygmunt Krawczyk
Honored Contributor

Re: Crash seen from c++ runtime exception handling code

Did you try the latest aC++ Runtime libraries provided by patch PHSS_41185?
Dennis Handly
Acclaimed Contributor

Re: Crash seen from c++ runtime exception handling code

>that certain exceptions are not caught when thrown from a C++ shared library that is run from a C executable.

Are there any messages to stderr? If you port to Integrity and run this, you get a detailed error message.

This stack trace is the standard "user messed up" trace. There wasn't any catch handler.
What frame do you think has the handler?
What is the type that is thrown?
Does this work on another platform?
What aC++ runtime patch do you have?

>if someone could speculate about the possible reasons for the crash or how we can go about trying to debug the issue.

1) No handler
2) A throw spec violation
3) Trying to throw out of a thread
4) rethrow without active exception (not this case)
5) The types are hidden/private in your shlib.

Try adding some catch(...) handlers to debug.

>This certainly looks to be some issue with the C++ runtime code

Not from the stack trace.

>Zygmunt: latest aC++ Runtime libraries provided by patch PHSS_41185?

That's not likely to help since there were only aCC6 changes there.
Dennis Handly
Acclaimed Contributor

Re: Crash seen from c++ runtime exception handling code

If you have a new enough aC++ runtime patch, you'll see a message like this to stderr:
aCC runtime: Uncaught exception of type "%s".
Dennis Handly
Acclaimed Contributor

Re: Crash seen from c++ runtime exception handling code

One other thing you can do is put a call to U_STACK_TRACE() before the throw. If that fails, then it would explain why the throw fails.
Rohitash Panda
New Member

Re: Crash seen from c++ runtime exception handling code

U_STACK_TRACE() is not available on PA-RISC64 systems .
We don't have any static members or global variables except for constants and the library is loaded dynamically ( using dlopen() ) on first use .

The interesting thing is that exceptions work when thrown from some locations, but when thrown from other locations, the exceptions are not caught. The same type of exception is being thrown in both cases, and all of the outer functions' catch blocks are the same.

The only thing that might be unusual is that the calling function in this case has declared an object on the stack, and calls into a (non-virtual) function on that object which throws the exception ( which doesn't get caught ) .

The catch handler is 3 stack frames below the frame where throw() is called . I think for every throw , the C++ runtime calls the appropriate handler , albeit with the older approach . Else why would it go into the C++ runtime and crash there without calling the catch block ? Most of the newer implementations maintain a table to call the appropriate catch handler .
Rohitash Panda
New Member

Re: Crash seen from c++ runtime exception handling code

Also the latest patch version for C++ is as below :

$ swlist -l patch | grep -i C++
# PHSS_38141 1.0 aC++ Runtime (IA: A.06.20, PA: A.03.85)

show_patches -a -s | grep C++
PHSS_38141 aC++ Runtime (IA: A.06.20, PA: A.03.85)
PHSS_37501 aC++ Runtime (IA: A.06.16, PA: A.03.76) - Superseded Patch

I hope this is the correct way to check it.
Dennis Handly
Acclaimed Contributor

Re: Crash seen from c++ runtime exception handling code

>U_STACK_TRACE() is not available on PA-RISC systems.

Sure it is, you have to type in the prototype:
extern "C" void U_STACK_TRACE();

(No progress can be made until this is done.)

>The catch handler is 3 stack frames below the frame where throw() is called.

So frame #11, getModifiedObjects?

>I think for every throw, the C++ runtime calls the appropriate handler, albeit with the older approach.

I'm not sure what you mean by "older" approach? (And more specifically it does a goto to the handler.)

>Else why would it go into the C++ runtime and crash there without calling the catch block?

Because it can't find the handler, it can't unwind the stack, the catch type is wrong or there is a throw spec that blocks the throw.

>Most of the newer implementations maintain a table to call the appropriate catch handler.

And that's what aC++ uses. This isn't cfront.

>Also the latest patch version for aC++ is as below

What's the version for Trap/Unwind lib in libcl.sl?
Rohitash Panda
New Member

Re: Crash seen from c++ runtime exception handling code

The U_STACK_TRACE() gets called ( I forgot I was using C++ code and hence needed the extern "C" thing ) now . But the problem is , U_STACK_TRACE() spits the o/p on the stderr and , and for us since the process runs as a daemon , it doesn't have a terminal and can't write to the terminal .

I tried to use call/print in gdb , it doesn't help . Also trying to set a catchpoint for a throw gives me the below message :
(gdb) catch throw
warning: Unable to find exception callback routine (__d_eh_notify_callback).
warning: Suggest linking executable with -g (links in /opt/langtools/lib/end.o).
warning: GDB will be unable to intercept exception events.
Unsupported with this platform/compiler combination.
Perhaps you can achieve the effect you want by setting
a breakpoint on __raise_exception().

So this also isn't working .

Also I want to stop just before the C++ exception handler is hit . In the case of GNU C++, exceptions are raised by calling a library function named __raise_exception
( as hinted by gdb too above ) . If we can know the function name of the exception handler for this platform , maybe we can get a better picture of the stack before its unwound on the exception .

If I attach through gdb and break at the function which calls throw , I can get the stack as below :

TxsOqRenameConflictChecker::throwException TxsOqRenameConflictChecker::checkForConflictsTxsOqIDRegenerator::regenerateIDs
TxsOqMetadataContext::getModifiedObjects
TxsOqPersistentMetadataContext::commitChild
TxsOqMetadataContext::commit
TxsOqDefinitionManager::commitRootTransaction

TxsOqPersistentMetadataContext::commitChild() function has the catch block and its a generic catch(...) block .

So it looks like the runtime is screwing up something here .

We are using the older unwind library :
what /usr/lib/pa20_64/libcl.2
/usr/lib/pa20_64/libcl.2:
libIO77 HP HPUX [ Release B.11.23.23 ]
(hp700:hp/ux) Jul 16 2008
Copyright (c) 2001 Hewlett Packard.
HP Port of Compaq Convert RTL V0.0.00
HP Fortran of Alpha RT V0.0.00
Intel Fortran RTL V1.1-929 1+ 1-Aug-2003
libcl.sl version B.11.XX.21 - Aug 4 2008
Trap Library version UX.11.01.06 - 02/04/16
Unwind Library version UX.11.01.05 - 00/08/15

Thanks for all your suggestion . Let me know if you could conjure up some better ideas.

Thanks.
Dennis Handly
Acclaimed Contributor

Re: Crash seen from c++ runtime exception handling code

>the problem is, U_STACK_TRACE() spits the o/p on the stderr and since the process runs as a daemon, it doesn't have a terminal and can't write to the terminal.

I would think long and hard about making a C++ application a demon. You need to redirect/reopen stderr to a file so you can log those abort messages.

I suppose you could do this in a std::terminate handler but you would lose your detailed abort message.

You can reopen stderr just before those calls to U_STACK_TRACE and throw so you can get that output.

>set a catchpoint for a throw gives me the below message:
(gdb) catch throw
warning: Suggest linking executable with -g (links in /opt/langtools/lib/end.o).

Yes, you have to relink your app with -g. And you may have to use pxdb on the application so you can set breakpoints in shlibs.

>I want to stop just before the C++ exception handler is hit.

Since it isn't hit, that won't help.

>If we can know the function name of the exception handler for this platform, maybe we can get a better picture of the stack before its unwound on the exception.

From the stack trace, it's called __throw__FPvT1.

>If I attach through gdb and break at the function which calls throw, I can get the stack as below:
TxsOqRenameConflictChecker::throwException TxsOqRenameConflictChecker::checkForConflicts
TxsOqIDRegenerator::regenerateIDs
TxsOqMetadataContext::getModifiedObjects
TxsOqPersistentMetadataContext::commitChild
TxsOqMetadataContext::commit
TxsOqDefinitionManager::commitRootTransaction

Are you sure this is the throw that will abort? Continue and see if hit again. (You want the last time. :-)

You can use "info break" to provide a count and back it up and use "ignore" to skip that many breaks. I'm not sure if your attach will stop your process in the same place each time?

>TxsOqPersistentMetadataContext::commitChild function has the catch block and it's a generic catch(...) block.
>So it looks like the runtime is screwing up something here.

You didn't list this function with your first stack trace.

>We are using the older unwind library:
what /usr/lib/pa20_64/libcl.2
libIO77 HP HPUX [Release B.11.23.23]
(hp700:hp/ux) Jul 16 2008

I'll have to check to make sure this is the latest but it wouldn't hurt to make sure you have the latest patch.

>Let me know if you could conjure up some better ideas.

You need to provide the full stack trace and verify if that stack trace is possible.

If it doesn't have commitChild and its catch block, the aC++ runtime is working correctly.