summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-05-06 00:22:26 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-05-06 15:08:25 +0300
commit29335d26ddba21afcac7655dc7249ede6aae0c09 (patch)
tree8fea0a4d0aab5a3b7dc334f5dcbb698872332f5f /indra
parent709dbea75e1f0749ec8fe9c8f46f077578a7fc82 (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.cpp49
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;
+ }
}
}
}