activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kevin Quick (JIRA)" <>
Subject [jira] Reopened: (AMQCPP-327) SEGFAULT on shutdown with global variable AMQCPP references
Date Tue, 09 Nov 2010 22:51:00 GMT


Kevin Quick reopened AMQCPP-327:

Fair deuce on the need for the shutdownLibrary() call.

I do disagree on the requirement for shutdown before exit from main... the example is valid
C++ and can be considered to be a useful method of resource management (see Chapter 3, "Effective
C++" by Scott Meyers)... one which I've used with many other libraries without issues.

I may have been too trivial in my original example; I'll provide an enhanced version representing
a long-running server which performs a shutdown on Ctrl-C.  With the exception of this AMQCPP
issue, the shutdown is otherwise ordered and managed.

I would like to point out as well that the current AMQCPP implementation precludes linking
with any other libraries using the apr, and especially if they do so in the same manner as
AMQCPP, so it's one of the potential issues we are evaluating in whether or not to use AMQCPP.

I don't wish to dictate your design, but if I may suggest a possible solution to these issues:

  * The core problem is that the AMQCPP initialization calls decaf::lang::Runtime::initializeRuntime(),
which in turn calls a classic Singleton to obtain a DecafRuntime object whose initializer
calls apr_initialize().  The corresponding ~DecafRuntime calls apr_terminate() and is invoked
when the singleton object goes out of scope (a similar technique to the auto_ptr in my example,

    I would suggest having getRuntime return a decaf Pointer to a new'ed static global, and
furthermore having initializeRuntime return this to ActiveMQCPP which would store it internally.
 Each object then returned by an ActiveMQCPP call (e.g. createCMSConnectionFactory(), createConnection(),
etc.) would get a copy of this Pointer.

   By using this technique you would be able to ensure that the ~DecafRuntime() wasn't called
until all the Pointer references were released, which would solve the shutdown ordering problem.

  * I would also then recommend adding a boolean flag parameter (defaulting to false) to ActiveMQCPP::initializeLibrary()
that would pass through to decaf::Runtime::initializeRuntime() and would indicate to the initializeRuntime()
code that the Pointer should be left as NULL instead of calling getRuntime().  This flag would
be the way for the application to indicate that it was managing apr initialization/shutdown
of apr itself and that the ActiveMQCPP library should not do this management---which would
then allow the use of other apr-using libraries by that application.  The NULL Pointer is
nicely compatible with the above suggestion and requires no additional work to deactivate
apr management by ActiveMQCPP.

I hope you find these suggestions helpful (and apologies if you don't!): ActiveMQCPP seems
to be very nice and useful and I'm just hoping to help with polishing a few final spots on
the finish.  If you close this again I promise not to re-open it.

> SEGFAULT on shutdown with global variable AMQCPP references
> -----------------------------------------------------------
>                 Key: AMQCPP-327
>                 URL:
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>          Components: CMS Impl
>    Affects Versions: 3.2.1
>         Environment: CentOS
>            Reporter: Kevin Quick
>            Assignee: Timothy Bish
>            Priority: Minor
>         Attachments: mbtest.cpp, mbtest3.cpp
> If AMQ-CPP resources are managed by global variables and those global variables are not
explicitly shutdown, the post-exit shutdown code ordering usually causes a segfault.  This
is because the AMQ-CPP internal threads shutdown the apr library first and then the global
variables attempt to close() their connections which result in apr calls.
> A simple program to demonstrate this is attached; when run it results in the segfault
core trace:
> Program received signal SIGSEGV, Segmentation fault.
> 0xb72f72fe in mutex_hash (mem=0x806089c) at atomic/unix/mutex.c:78
> 78	atomic/unix/mutex.c: No such file or directory.
> 	in atomic/unix/mutex.c
> (gdb) bt
> #0  0xb72f72fe in mutex_hash (mem=0x806089c) at atomic/unix/mutex.c:78
> #1  0xb72f7457 in apr_atomic_cas32 (mem=0x806089c, with=0, cmp=1) at atomic/unix/mutex.c:152
> #2  0xb7e35bca in decaf::util::concurrent::atomic::AtomicBoolean::compareAndSet (
>     this=0x8060898, expect=true, update=false)
>     at decaf/util/concurrent/atomic/AtomicBoolean.cpp:42
> #3  0xb7a51238 in activemq::core::ActiveMQConnection::stop (this=0x8060880)
>     at activemq/core/ActiveMQConnection.cpp:425
> #4  0xb7a56ad0 in activemq::core::ActiveMQConnection::close (this=0x8060880)
>     at activemq/core/ActiveMQConnection.cpp:355
> #5  0x08048adc in mgr::~mgr() ()
> #6  0x08048b6b in std::auto_ptr<mgr>::~auto_ptr() ()
> #7  0x08048974 in __tcf_1 ()
> #8  0xb7346529 in exit () from /System/Links/Libraries/
> Note: possibly related to AMQCPP-231.

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message