[prev in list] [next in list] [prev in thread] [next in thread] 

List:       hpux-cxx-dev
Subject:    Re:  CXX-DEV: thread-safe rb_tree
From:       Dennis Handly <dhandly () cup ! hp ! com>
Date:       2006-04-20 3:48:20
Message-ID: 200604200348.UAA22208 () hpcll183 ! hp ! com
[Download RAW message or body]

> From: sunil <nicholaskoll@yahoo.com>
> I just wanted to get a small clarification - I have read in some of the
> documents that code compiled with __HPACC_THREAD_SAFE_RB_TREE is not
> compatible with the code thats not compiled with it.  Does this
> statement apply to code that doesn't use STL also?

If you aren't using -AP (PA only) set or map, it doesn't matter.
To be real specific, if you aren't using the exact template type, it
won't matter either.

But from your stack trace below, it matters to you.

> But there are a couple of shared libraries that use STL.
> one of the shared libraries (lets say libA.sl) uses the
> __HPACC_THREAD_SAFE_RB_TREE flag.  The other shared library (lets say
> libB.sl) doesn't use the flag.

Since they use the same container type, this will abort.

> libA.sl is recently introduced in the mix, and to resolve some crashes
> that were occurring when STL maps are passed accross shared libraries,
> the __HPACC_THREAD_SAFE_RB_TREE flag was used.

Yes, you need to use -D__HPACC_THREAD_SAFE_RB_TREE if you are going to
use -Bsymbolic with <tree>.

> I am trying to investigate a crash in libB.sl where some of the STL
> operations like calling a copy constructor for a set, or calling a
> find/insert on a map are crashing.  The call stack showed that the
> rb_tree method where it is failing is actually being resolved in the
> libA.sl.  I was thinking that this should have been resolved in the
> libstd.sl

No, very few templates can be instantiated in libstd.sl.
If libB is calling stuff in libA, you have the same set or map container
as Amitav mentions.

> I tried compiling (and linking) libB.sl also with the flag; The results
> were worse this time.  It crashed in libB.sl but way before the point it
> was crashing the first time.  This time the rb_tree methods are resolved
> in libB.sl itself.

This could just be a simple heap corruption.

> I just wanted to find out whether all the components involved (all the
> shared libraries and the main App) needs to be compiled with this flag
> or just the ones that use STL needs to use this.
Nick

Just the ones using set or map.  Which is at least libA and libB.

> From: Amitav Mishra <amitavm@india.hp.com>
> since the tree header file (which implements the rb_tree
> class template) is used extensively in all STL associative containers
> (map, multimap, set, mutiset)

Yes.

> Note that this macro makes the STL (the part that is implemented as
> templates in header files) thread-safe, not the application code.

Yes, you still have to lock if you are trying to access the same container
from multiple threads.

> What you will find in libstd is mostly iostream and string
> implementations (actually specializations).

Iostream is in libstream for -AP.

> So probably one or more of the source files in libB.sl use the STL?
> How else is rb_tree getting into libB?
> it will be good to show us the stack trace of your crashes.
-amitav

Right.

> From: sunil <nicholaskoll@yahoo.com>
> libB.sl also uses STL.  Before libA.sl is introduced in the mix, we
> tried using __HPACC_THREAD_SAFE_RB_TREE with libB.sl and but we were
> seeing some sporadic crashes with this.

This is your clue.  It probably was already broken due to some heap
corruption.

> So we split some of the code and
> reimplemented it to using windows threads + port it with Mainwin.
> libB.sl as it stands today is pure STL (no Mainwin interaction), it
> doesn't use any threads, and it doesnt use __HPACC_THREAD_SAFE_RB_TREE
> to compile and link.

If you have ANY threads at all, you are using threads in libB.sl.
(I.e. if you link with libpthread or libcma.)

> Here is the call stack for one of the crashes.
> ClassXXXX is calling the copy constructor of set<string> in its member
> initialization list. 
#10 <signal handler called>
#11 0xcb510408 in
rb_tree<string,string,ident<string,string>,less<string>,allocator>::__copy+0x208
libA.sl
#12 0xc8733224 in ClassXXXX::Classxxxx+0x2a8 libB.sl

You are using the same container type.  You're not using -Bsymbolic are
you?  Or any tricky linker options like +e or -h??

> I tried a simple thing like the following in ClassXXXX constructor.
> set<string> s1;
> set<string> s2(s1); <--- this was crashing

Hmm.  I don't see how s1 could be corrupt in these two steps.
But rbtree<>::NIL could be.

> Following is the call stack of another crash after rebuilding libB.sl
> with __HPACC_THREAD_SAFE_RB_TREE.
> This time it fails when find is called on a map.  As you can notice in
> this call stack the rb_tree..::find is being resolved in libB.sl itself.
#0  0xc6a34298 in
rb_tree<string,pair<string const, int>,select1st<pair<string const, \
int>,string>,less<string>,allocator>::find+0x5c libB.sl #1  0xc6f14174 in \
ClassYYYY::getUniqueName+0x40 libB.sl

Except this template has a different rb_tree<>::NIL.

> When you say part "the code actually becomes part of your own program",
> do you mean part of the shared library or part of main Aapp and shared
> between different shared libraries?  If it becomes part of the shared
> library why is rb_tree...::__copy resolved in libA.sl instead of libB.sl
> itself.
Nick

It becomes part of any object that uses the template.
Whether in the a.out or in every shared lib.
And dld binds it to the first in binding order, which is libA.sl.

> From: Amitav Mishra <amitavm@india.hp.com>
> Even if libB itself does not use threads, if your app is multi
> threaded and multiple threads make calls into libB, it had better be
> thread-safe.

Right.

> But it looks like it interacts with libA, which is built with that
> macro enabled.  So unless libB is also built with the same macro, it
> will be binary incompatible with libA (i.e., they cant be used
> together).

Right.  Even if no threads are actually created.

> > Here is the call stack for one of the crashes.
> > #11 0xcb510408 in rb_tree<...>::__copy+0x208 .../libA.sl
> > #12 0xc8733224 in ClassXXXX::Classxxxx+0x2a8 .../libB.sl

> So control flows from libB into libA.  Since they interact, and both
> of them use STL associative containers, both must be built using the
> __HPACC_THREAD_SAFE_RB_TREE macro.

Right.

> Probably now the control flows into libB from some other lib that does
> use STL, but was not built with __HPACC_THREAD_SAFE_RB_TREE (similar
> to libB)?

Try using the following on all of your shared libs:
   nm -pxA libA.sl libB.sl ... | fgrep NIL__7rb_tree

> Since the references to the template class objects
> and their methods are resolved at link time, they wont be shared
> across load modules (e.g., shlibs) at runtime.

This isn't true for shared libs.  If -Bsymbolic is NOT used, dld will
bind the calls to the first in binding order.

> If you still have problems, let's take this discussion off this list,
> since it has become highly specialized.  Please write to me directly.
-amitav

You should probably include me too.
 _________________________________________________________________
 To leave this mailing list, send mail to majordomo@cxx.cup.hp.com
    with the message UNSUBSCRIBE cxx-dev
 _________________________________________________________________


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic