Re: Crash seen from c++ runtime exception handling code (535 Views)
Reply
Occasional Visitor
Rohitash Panda
Posts: 5
Registered: ‎02-02-2011
Message 1 of 14 (535 Views)

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.
Honored Contributor
Zygmunt Krawczyk
Posts: 825
Registered: ‎09-05-2003
Message 2 of 14 (535 Views)

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

Did you try the latest aC++ Runtime libraries provided by patch PHSS_41185?
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 3 of 14 (535 Views)

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.
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 4 of 14 (535 Views)

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".
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 5 of 14 (535 Views)

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.
Occasional Visitor
Rohitash Panda
Posts: 5
Registered: ‎02-02-2011
Message 6 of 14 (535 Views)

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 .
Occasional Visitor
Rohitash Panda
Posts: 5
Registered: ‎02-02-2011
Message 7 of 14 (535 Views)

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.
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 8 of 14 (535 Views)

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?
Occasional Visitor
Rohitash Panda
Posts: 5
Registered: ‎02-02-2011
Message 9 of 14 (535 Views)

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.
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 10 of 14 (535 Views)

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.
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 11 of 14 (535 Views)

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

The latest libcl patch for 11.31:
http://www.itrc.hp.com/service/patch/patchDetail.do?patchid=PHSS_40804

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

Here is an example function that you can reuse parts.
#include
#include
extern void U_STACK_TRACE(void);
void redirect_stack_trace(FILE *filest) {
int fd, fd2, err;
fd = fileno(filest);
fflush(filest);
fflush(stderr);
fd2 = dup(STDERR_FILENO);
err = dup2(fd, STDERR_FILENO);
U_STACK_TRACE();
// Restore; not needed here
fflush(stderr);
fd = dup2(fd2, STDERR_FILENO);
close(fd2);
}

You only need to do this the first time. And you wouldn't want to restore it since you want those throw errors on stderr.
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 12 of 14 (535 Views)

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

If you are optimizing and using EH you can NOT use +Oentrysched.
Occasional Visitor
Rohitash Panda
Posts: 5
Registered: ‎02-02-2011
Message 13 of 14 (535 Views)

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

We don't have a terminate handler set , so it uses the default provider in the C++ runtime which aborts the message .

The gdb command 'catch throw' won't work on this platform , and yes I have recompiled debug the relevant files and also changed the attributes on the executable for setting a breakpoint on a shared library :
chatr +dbg enable

__throw__FPvT1 ( __throw(void *,void *) ) is just the runtime throw function and not the one . I want the glue exception handler that sets up the stuff for the catch exception and the unwind.

From the below stack :
TxsOqRenameConflictChecker::throwException TxsOqRenameConflictChecker::checkForConflicts
TxsOqIDRegenerator::regenerateIDs
TxsOqMetadataContext::getModifiedObjects
TxsOqPersistentMetadataContext::commitChild
TxsOqMetadataContext::commit
TxsOqDefinitionManager::commitRootTransaction


Yes this is the one and only throw which aborts . I did a continue and it just crashed after that without hitting it again.

The patches might not be latest , but I don't think thats an option . And yes this is the right stack , I had not listed the function earlier .

Also yes , we are optimizing and using EH , but we still use the flag '+Oentrysched' during compilation . EH works for most of the cases , just that its failing in this particular case .

Thanks for your time and patience .
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 14 of 14 (535 Views)

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

>I want the glue exception handler that sets up the stuff for the catch exception and the unwind.

The first thing ThrowException does is try to unwind to find the handler. This is failing.
I don't know what you think a glue exception handler will do?

>we are optimizing and using EH, but we still use the flag '+Oentrysched' during compilation. EH works for most of the cases, just that it's failing in this particular case.

As documented, if you want EH to work correctly in all cases, you must NOT use +Oentrysched.
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.