开发者

Segfault on set::insert [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 11 years ago.

I experience a segfault after the following line:

this->my_set.insert(my_string);

The se开发者_高级运维t has been initialized and it contains std::string. The inserting string is not referring to a dandling pointer and it's null-terminated. All the other strings contained in the set are not null and terminate with '\0'.

This is the backtrace:

#0  0xb7076bdb in std::_Rb_tree_insert_and_rebalance () from /usr/lib/libstdc++.so.6
#1  0xb7480795 in std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_insert_ (
    this=0x97bf918, __x=0x0, __p=0x980aa78, __v=@0xaabfc1c4) at /usr/include/c++/4.3/bits/stl_tree.h:854<br/>
#2  0xb7480b96 in std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_insert_unique (this=0x97bf918, __v=@0xaabfc1c4) at /usr/include/c++/4.3/bits/stl_tree.h:1148
#3  0xb74fab2d in std::set<std::string, std::less<std::string>, std::allocator<std::string> >::insert (this=0x97bf918, __x=@0xaabfc1c4)
    at /usr/include/c++/4.3/bits/stl_set.h:381

Any idea?


Edit

More code:

set<string> dangerous_messages; //placed in header file

            qpid::client::Message msg;
            msg = (*mylocal_queues)[queue]->get(10*1e9);
            string msgUID = msg.getHeaders().getAsString("UID");
            if(this->dangerous_messages.count(msgUID))
            {
                       warning("(read_local_queue) Duplicate message \""+msgUID+"\" discarded");
           }
           else
           {
                        msg.getHeaders().setString("BID", bid);
                        this->dangerous_messages.insert(msgUID);
            }

Printing with gdb, I've not noticed any corruption in the set or in the string.


it is also possible that the problem is located somewhere else. An overflow at some other point in your program may lead to a segfault just whenever you insert into the set. The insertion is just the point in time where the error is recognized but is not necessarily related to the error at all.

Consider this made-up example:

vector<MyObj*> ptrs;
if/for/while (...)
{
    MyObj o;
    ptrs.push_back(&o);
}  // end of scopre for o
// Your heap is corrupted, but no segfault has to occur right away
...
// Your insertion occurs somewhere later
// No the program segfaults because of the problem you created earlier


Since you stated that the code is multi-threaded without locks, this is probably the result of a race condition. (At least a race condition may result in the exact same stack trace.)

Use proper locks to ensure correct execution. For example, if you are using OpenMP, then change the code you’ve shown us to:

#pragma omp critical
{
    if(this->dangerous_messages.count(msgUID))
    {
        warning("(read_local_queue) Duplicate message \""+msgUID+"\" discarded");
    }
    else
    {
        msg.getHeaders().setString("BID", bid);
        this->dangerous_messages.insert(msgUID);
    }
}

But in general, your code logic is fundamentally flawed if such an error can occur. You must not share state between threads without a clean cross-thread interface. Use predefined cross-thread communication structures to share state between threads, or use read-only state. Cross-thread writes are almost never OK.


Your heap could be corrupted, your string or set instances could be busted.


Wild guess: The object that contains my_set has already gone out of scope/been destroyed.

You really have to post more code if you want more precise answers.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜