[Lldb-commits] [lldb] [lldb][debugserver][MacOSX] Work around sanitizer misaligned address errors when reading exception data (PR #132193)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Fri Mar 21 03:10:41 PDT 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/132193
>From 64d8c3e31c4b9d5b7c2cd87eb56eb067b2d01f25 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Thu, 20 Mar 2025 11:46:45 +0000
Subject: [PATCH 1/3] [lldb][debugserver][MacOSX] Work around sanitizer
misaligned address errors when reading exception data
We've been dealing with UBSAN issues around this code for some time now
(see `9c36859b33b386fbfa9599646de1e2ae01158180` and
`1a2122e9e9d1d495fdf337a4a9445b61ca56df6f`). On recent macOS versions, a
UBSAN-enabled debugserver will crash when performing a `memcpy` of the
input `mach_exception_data_t`. The pointer to the beginning of the
exception data may not be aligned on a doubleword boundary, leading to
UBSAN failures such as:
```
$ ./bin/debugserver 0.0.0.0:5555 /Volumes/SSD/llvm-builds/llvm-worktrees/clang-work/build-sanitized-release/tools/lldb/test/Shell/Recognizer/Output/verbose_trap.test.tmp.out
/Volumes/SSD/llvm-builds/llvm-worktrees/clang-work/lldb/tools/debugserver/source/MacOSX/MachException.cpp:35:12: runtime error: store to misaligned address 0x00016ddfa634 for type 'mach_exception_data_type_t *' (aka 'long long *'), which requires 8 byte alignment
0x00016ddfa634: note: pointer points here
02 00 00 00 03 00 01 00 00 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Volumes/SSD/llvm-builds/llvm-worktrees/clang-work/lldb/tools/debugserver/source/MacOSX/MachException.cpp:35:12
```
Work around these failures by pretending the input data is a `char*` buffer.
Drive-by changes:
* I factored out some duplicated code into a static `AppendExceptionData` and made the types consistent
---
.../source/MacOSX/MachException.cpp | 38 ++++++++++++-------
.../debugserver/source/MacOSX/MachException.h | 9 -----
2 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/lldb/tools/debugserver/source/MacOSX/MachException.cpp b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
index 659fb2ff8186d..10323767fc972 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachException.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
@@ -18,9 +18,25 @@
#include "PThreadMutex.h"
#include "SysSignal.h"
#include <cerrno>
+#include <inttypes.h>
#include <sys/ptrace.h>
#include <sys/types.h>
+static void AppendExceptionData(std::vector<mach_exception_data_type_t> &out,
+ mach_exception_data_t Data,
+ mach_msg_type_number_t Count) {
+ mach_exception_data_type_t Buf;
+ for (mach_msg_type_number_t i = 0; i < Count; ++i) {
+ // The input Data we receive need not be aligned correctly.
+ // Perform an unaligned copy by pretending we're dealing with
+ // a char* buffer. This is required to work around UBSAN/ASAN
+ // "misaligned address" errors.
+ auto * src = reinterpret_cast<char*>(Data + i);
+ memcpy(&Buf, src, sizeof(mach_exception_data_type_t));
+ out.push_back(Buf);
+ }
+}
+
// Routine mach_exception_raise
extern "C" kern_return_t
catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread,
@@ -95,20 +111,16 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
mach_exception_data_t exc_data,
mach_msg_type_number_t exc_data_count) {
if (DNBLogCheckLogBit(LOG_EXCEPTIONS)) {
- std::vector<uint64_t> exc_datas;
- uint64_t tmp;
- for (unsigned i = 0; i < exc_data_count; ++i) {
- // Perform an unaligned copy.
- memcpy(&tmp, &exc_data[i], sizeof(uint64_t));
- exc_datas.push_back(tmp);
- }
+ std::vector<mach_exception_data_type_t> exc_datas;
+ AppendExceptionData(exc_datas, exc_data, exc_data_count);
DNBLogThreaded("::%s ( exc_port = 0x%4.4x, thd_port = 0x%4.4x, tsk_port = "
- "0x%4.4x, exc_type = %d ( %s ), exc_data[%d] = { 0x%llx, "
- "0x%llx })",
+ "0x%4.4x, exc_type = %d ( %s ), exc_data[%d] = { 0x%" PRIx64
+ ", "
+ "0x%" PRIx64 " })",
__FUNCTION__, exc_port, thread_port, task_port, exc_type,
MachException::Name(exc_type), exc_data_count,
- (uint64_t)(exc_data_count > 0 ? exc_datas[0] : 0xBADDBADD),
- (uint64_t)(exc_data_count > 1 ? exc_datas[1] : 0xBADDBADD));
+ (exc_data_count > 0 ? exc_datas[0] : 0xBADDBADD),
+ (exc_data_count > 1 ? exc_datas[1] : 0xBADDBADD));
}
g_message->exc_type = 0;
g_message->exc_data.clear();
@@ -117,7 +129,7 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
g_message->task_port = task_port;
g_message->thread_port = thread_port;
g_message->exc_type = exc_type;
- g_message->AppendExceptionData(exc_data, exc_data_count);
+ AppendExceptionData(g_message->exc_data, exc_data, exc_data_count);
return KERN_SUCCESS;
} else if (!MachTask::IsValid(g_message->task_port)) {
// Our original exception port isn't valid anymore check for a SIGTRAP
@@ -129,7 +141,7 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
g_message->task_port = task_port;
g_message->thread_port = thread_port;
g_message->exc_type = exc_type;
- g_message->AppendExceptionData(exc_data, exc_data_count);
+ AppendExceptionData(g_message->exc_data, exc_data, exc_data_count);
return KERN_SUCCESS;
}
}
diff --git a/lldb/tools/debugserver/source/MacOSX/MachException.h b/lldb/tools/debugserver/source/MacOSX/MachException.h
index bf9771ef0bf93..573e84e991608 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachException.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachException.h
@@ -70,15 +70,6 @@ class MachException {
return (exc_type == EXC_BREAKPOINT ||
((exc_type == EXC_SOFTWARE) && exc_data[0] == 1));
}
- void AppendExceptionData(mach_exception_data_t Data,
- mach_msg_type_number_t Count) {
- mach_exception_data_type_t Buf;
- for (mach_msg_type_number_t i = 0; i < Count; ++i) {
- // Perform an unaligned copy.
- memcpy(&Buf, Data + i, sizeof(mach_exception_data_type_t));
- exc_data.push_back(Buf);
- }
- }
void Dump() const;
void DumpStopReason() const;
bool GetStopInfo(struct DNBThreadStopInfo *stop_info) const;
>From c3d01cb8a9e4bb470875310413ec81f7cabeb64d Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 21 Mar 2025 00:00:19 +0000
Subject: [PATCH 2/3] fixup! clang-format
---
lldb/tools/debugserver/source/MacOSX/MachException.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/tools/debugserver/source/MacOSX/MachException.cpp b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
index 10323767fc972..0b0e6d7f4b7b4 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachException.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
@@ -31,7 +31,7 @@ static void AppendExceptionData(std::vector<mach_exception_data_type_t> &out,
// Perform an unaligned copy by pretending we're dealing with
// a char* buffer. This is required to work around UBSAN/ASAN
// "misaligned address" errors.
- auto * src = reinterpret_cast<char*>(Data + i);
+ auto *src = reinterpret_cast<char *>(Data + i);
memcpy(&Buf, src, sizeof(mach_exception_data_type_t));
out.push_back(Buf);
}
>From 1ba7118cc4213d039004efdc74dc4bb35eea15cc Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 21 Mar 2025 10:10:32 +0000
Subject: [PATCH 3/3] Use LLDB style
Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
.../debugserver/source/MacOSX/MachException.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lldb/tools/debugserver/source/MacOSX/MachException.cpp b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
index 0b0e6d7f4b7b4..40450c2c9d1ff 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachException.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
@@ -23,17 +23,17 @@
#include <sys/types.h>
static void AppendExceptionData(std::vector<mach_exception_data_type_t> &out,
- mach_exception_data_t Data,
- mach_msg_type_number_t Count) {
- mach_exception_data_type_t Buf;
- for (mach_msg_type_number_t i = 0; i < Count; ++i) {
+ mach_exception_data_t data,
+ mach_msg_type_number_t count) {
+ mach_exception_data_type_t buf;
+ for (mach_msg_type_number_t i = 0; i < count; ++i) {
// The input Data we receive need not be aligned correctly.
// Perform an unaligned copy by pretending we're dealing with
// a char* buffer. This is required to work around UBSAN/ASAN
// "misaligned address" errors.
- auto *src = reinterpret_cast<char *>(Data + i);
- memcpy(&Buf, src, sizeof(mach_exception_data_type_t));
- out.push_back(Buf);
+ auto *src = reinterpret_cast<char *>(data + i);
+ memcpy(&buf, src, sizeof(mach_exception_data_type_t));
+ out.push_back(buf);
}
}
More information about the lldb-commits
mailing list