diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-05-06 00:22:26 +0300 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-05-06 15:08:25 +0300 |
| commit | 29335d26ddba21afcac7655dc7249ede6aae0c09 (patch) | |
| tree | 8fea0a4d0aab5a3b7dc334f5dcbb698872332f5f /indra | |
| parent | 709dbea75e1f0749ec8fe9c8f46f077578a7fc82 (diff) | |
#5232 Crash in handleMessage #2
LLSD are thread unsafe, don't pass them across threads.
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/lleventpoll.cpp | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index f1b46f0533..a18fdf74c1 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -328,26 +328,51 @@ namespace Details { // LLSD is too smart for it's own good and may act like a smart // pointer for the content of (*i), so instead of passing (*i) - // pass a prepared name and move ownership of "body", - // as we are not going to need "body" anywhere else. + // pass a prepared name and copy the body std::string msg_name = (*i)["message"].asString(); - // WARNING: This is a shallow copy! - // If something still retains the data (like in httpAdapter?) this might still - // result in a crash, if it does appear to be the case, make a deep copy or - // convert data to string and pass that string. - const LLSD body = (*i)["body"]; - (*i)["body"].clear(); - work = [this, msg_name, body]() + // Create a deep copy using binary serialization + try { - handleMessage(msg_name, body); - }; + std::stringstream body_stream; + LLSDSerialize::toBinary((*i)["body"], body_stream); + std::string body_str = body_stream.str(); + (*i)["body"].clear(); + work = [this, msg_name, body_str]() + { + try + { + LLSD body; + std::istringstream istr(body_str); + LLSDSerialize::fromBinary(body, istr, body_str.size()); + handleMessage(msg_name, body); + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Bad memory allocation in handleMessage() for " << msg_name << LL_ENDL; + } + }; + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Bad memory allocation in eventPollCoro for " << msg_name << LL_ENDL; + } } main_queue->post(work); } else { - handleMessage(*i); + try + { + handleMessage(*i); + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Bad memory allocation in handleMessage() for " << (*i)["message"].asString() << LL_ENDL; + } } } } |
