Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

crash in std::string on dual processor

0 views
Skip to first unread message

Paul Pluzhnikov

unread,
Feb 21, 2002, 1:11:24 AM2/21/02
to
"Daniel Etzold" <det...@gmx-ag.de> wrote in message
news:8_Mc8.2$4G5...@news.ecrc.de...
> Hi,
> I'm running a multi threaded application with SuSE 7.2
> and Kernel 2.4.18-pre9 on a dual processor and always
> get segfaults at:
>
> #0 0x401b42f7 in memcpy () from /lib/libc.so.6
> #1 0x811b24e in basic_string<char, string_char_traits<char>,
> __default_alloc_template<true, 0> >::Rep::clone (this=0x812e548)
> at /usr/include/g++/stl_alloc.h:544
>
> On a machine with just one processor I don't have any problems.
>
> What's the problem?
>

Most likely you are accessing the same 'std::string' object
from multiple threads without proper locking.


Peter Gotink

unread,
Feb 21, 2002, 3:09:51 PM2/21/02
to
A std::string is a ref-counted container that contains a character pointer.
When you write s1 = s2; or s1.assign (s2); you copy the pointer and set the
ref count to 2. It is clear to see that in a MT environment this can lead
to problems if the ref-count becomes wrong. The last string deletes the
buffer.
Unfortunately there is (to my knowledge) no easy solution. Locking all
strings, programs tend to have a lot, is virtually impossible. We faced a
similar problem and found 2 solutions

1) in case of potential problem write s1.assign (s2.c_str(), s2.lenght());
This will force a copy to be taken.

2) Roll your own ie write a string class MyString with the same interface as
std::string but implement it in a tread safe way.

We opted for the first solution but after repeated problems (people
forgetting to do the copy thread-safe) went for solution 2.

Peter

"Daniel Etzold" <det...@gmx-ag.de> wrote in message

news:qf4d8.1$6h...@news.ecrc.de...


> Paul Pluzhnikov wrote:
>
> >
> > Most likely you are accessing the same 'std::string' object
> > from multiple threads without proper locking.
>

> It's not the same string object. It's something like this:
>
> void func1(std::string& s)
> {
> ...
> s.assign(local_string);
> }
>
> Now, a lot of Threads are accessing this function with
> a reference on their own string object.
>


Peter Gotink

unread,
Feb 21, 2002, 3:11:36 PM2/21/02
to
I forgot, you can easily see that std::string is actually refcounted

std::string s1 ("Toto");
std::string s2;

s2 = s1;
if (s1.c_str() == s2.c_str()) // compare the pointers
{
// ref counted
}


"Peter Gotink" <peter....@nais.be> wrote in message
news:3c7554d4$0$33499$ba62...@news.skynet.be...

Matthew Austern

unread,
Feb 21, 2002, 5:58:32 PM2/21/02
to
"Peter Gotink" <peter....@nais.be> writes:

> I forgot, you can easily see that std::string is actually refcounted
>
> std::string s1 ("Toto");
> std::string s2;
>
> s2 = s1;
> if (s1.c_str() == s2.c_str()) // compare the pointers
> {
> // ref counted
> }

Correction: you can easily see that it's refcounted in the
specific implementation that you're using. The C++ standard
does not require it to be reference counted, and there are
some popular implementations in which it is not.

(The main reason some implementations avoid reference counting
is that, in the presence of threads, it's much harder to get
things to work correctly if you use refcounting. As you've
found.)

Also, of course, the C++ standard doesn't mention threads.
If your library implementation claims to be thread safe,
however, you have found a bug and you should complain to
the vendor.


Alexander Terekhov

unread,
Feb 22, 2002, 4:56:07 AM2/22/02
to

Matthew Austern wrote:
[...]

> (The main reason some implementations avoid reference counting
> is that, in the presence of threads, it's much harder to get
> things to work correctly if you use refcounting. As you've
> found.)

Just a few ideas/food for thought:

immutable_string< ...,
class thread_sharing_policy_for_representation =
/* -pthread option: shared/private by default */ >

string< ...,
class thread_sharing_policy_for_representation =
/* -pthread option: shared/private by default */ >

http://groups.google.com/groups?threadm=3BC8463D.6E23002A%40web.de
(note that unref() needs to inject write/"release" mem.bars too IF
threads could unref() mutable objects INSIDE synchronized regions
for mutation/updates)

regards,
alexander.

0 new messages