Author: Yao Qi
Date: 2026-08-16T11:25:30+01:00
New Revision: ee7f9bcf43f0f1adc7d98f23fe56e4331b508454

URL: 
https://github.com/llvm/llvm-project/commit/ee7f9bcf43f0f1adc7d98f23fe56e4331b508454
DIFF: 
https://github.com/llvm/llvm-project/commit/ee7f9bcf43f0f1adc7d98f23fe56e4331b508454.diff

LOG: [lldb] Fix invalid UTF-8 in JSON log message (#216185)

Enabling the JSON packet log part way through a session aborts an
assertions build:

```
(lldb) b f
(lldb) run
(lldb) log enable -j -f /tmp/pk.json gdb-remote packets
(lldb) next
Assertion failed: (false && "Invalid UTF-8 in value used as JSON"), function 
Value, file JSON.h, line 333.
```

`Log::EmitJSONMessage` passed the message straight to
`llvm::json::Value`,
which asserts on ill-formed UTF-8 and only then falls back to `fixUTF8`.
So a release build repairs the message while an assertions build dies.

The bytes come from the saved packets.  Once logging is turned on,
`GDBRemoteCommunicationHistory::Dump` replays them verbatim, and the
reply
to an `x` (binary memory read) is binary:

```
history[80] tid=0x5c0f <  18> send packet: $x16fdfea00,200#f3
history[81] tid=0x5c0f < 516> read packet: $<binary>
```

The normal live packet path escapes binary before logging it, so this is
usually only seen when logging is enabled mid-session.

Added: 
    

Modified: 
    lldb/source/Utility/Log.cpp
    lldb/unittests/Utility/LogTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Utility/Log.cpp b/lldb/source/Utility/Log.cpp
index dd813efb90f90..62693dc314758 100644
--- a/lldb/source/Utility/Log.cpp
+++ b/lldb/source/Utility/Log.cpp
@@ -438,7 +438,11 @@ void Log::EmitJSONMessage(llvm::StringRef file, 
llvm::StringRef function,
                           llvm::StringRef message) {
   llvm::json::Object obj;
   WriteJSONHeader(obj, file, function);
-  obj["message"] = message;
+  // Log messages can carry arbitrary bytes; JSON strings must be valid UTF-8.
+  if (llvm::json::isUTF8(message))
+    obj["message"] = message;
+  else
+    obj["message"] = llvm::json::fixUTF8(message);
   std::string out;
   llvm::raw_string_ostream os(out);
   os << llvm::json::Value(std::move(obj)) << "\n";

diff  --git a/lldb/unittests/Utility/LogTest.cpp 
b/lldb/unittests/Utility/LogTest.cpp
index 6eaa318dfe34c..8cfcef6d504c0 100644
--- a/lldb/unittests/Utility/LogTest.cpp
+++ b/lldb/unittests/Utility/LogTest.cpp
@@ -387,6 +387,35 @@ TEST_F(LogChannelEnabledTest, JSONLOutput) {
   EXPECT_EQ(Obj->getString("function").value_or(""), "logAndTakeOutput");
 }
 
+TEST_F(LogChannelEnabledTest, JSONLOutputInvalidUTF8) {
+  // Arbitrary bytes must not abort the JSON writer.
+  EXPECT_THAT_ERROR(Log::EnableLogChannel(getLogHandler(),
+                                          /*log_options=*/LLDB_LOG_OPTION_JSON,
+                                          "chan", {}),
+                    llvm::Succeeded());
+
+  auto CheckMessage = [](llvm::StringRef Msg) {
+    llvm::Expected<llvm::json::Value> Parsed = llvm::json::parse(Msg);
+    ASSERT_TRUE(static_cast<bool>(Parsed))
+        << llvm::toString(Parsed.takeError());
+    llvm::json::Object *Obj = Parsed->getAsObject();
+    ASSERT_NE(Obj, nullptr);
+    std::optional<llvm::StringRef> Message = Obj->getString("message");
+    ASSERT_TRUE(Message.has_value());
+    EXPECT_TRUE(llvm::json::isUTF8(*Message));
+    EXPECT_TRUE(Message->contains("before"));
+    EXPECT_TRUE(Message->contains("after"));
+  };
+
+  // Check both entry points: Format and PutString.
+  CheckMessage(logAndTakeOutput("before\xff\xfe"
+                                "after"));
+
+  getLog()->PutString("before\xff\xfe"
+                      "after");
+  CheckMessage(takeOutput());
+}
+
 TEST_F(LogChannelEnabledTest, LLDB_LOG_ERROR) {
   LLDB_LOG_ERROR(getLog(), llvm::Error::success(), "Foo failed: {0}");
   ASSERT_EQ("", takeOutput());


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to