[Lldb-commits] [lldb] 52de49e - [lldb][debugserver][MacOSX] Work around sanitizer misaligned address errors when reading exception data (#132193)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Mar 21 04:21:32 PDT 2025
Author: Michael Buch
Date: 2025-03-21T11:21:29Z
New Revision: 52de49e4b9cd69957b7dc50a5fed061ecd0b0d77
URL: https://github.com/llvm/llvm-project/commit/52de49e4b9cd69957b7dc50a5fed061ecd0b0d77
DIFF: https://github.com/llvm/llvm-project/commit/52de49e4b9cd69957b7dc50a5fed061ecd0b0d77.diff
LOG: [lldb][debugserver][MacOSX] Work around sanitizer misaligned address errors when reading exception data (#132193)
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
---------
Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
Added:
Modified:
lldb/tools/debugserver/source/MacOSX/MachException.cpp
lldb/tools/debugserver/source/MacOSX/MachException.h
Removed:
################################################################################
diff --git a/lldb/tools/debugserver/source/MacOSX/MachException.cpp b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
index 659fb2ff8186d..40450c2c9d1ff 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;
More information about the lldb-commits
mailing list