[CPU/XThread] Add DWARF .eh_frame unwind info for JIT code on Linux
Generate per-function CIE+FDE records and register them via __register_frame so the C++ exception unwinder can propagate through JIT frames. Replace setjmp/longjmp fiber reentry with throw/catch on Linux to ensure destructors and RAII guards run during fiber stack switches.
This commit is contained in:
@@ -11,14 +11,17 @@
|
||||
#define XENIA_KERNEL_XTHREAD_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <csetjmp>
|
||||
#include <string>
|
||||
|
||||
#include "xenia/base/mutex.h"
|
||||
#if XE_PLATFORM_LINUX
|
||||
#include <condition_variable>
|
||||
#include <csignal>
|
||||
#include <mutex>
|
||||
#endif
|
||||
#if XE_PLATFORM_WIN32
|
||||
#include <csetjmp>
|
||||
#endif
|
||||
#include "xenia/base/threading.h"
|
||||
#include "xenia/cpu/thread.h"
|
||||
#include "xenia/cpu/thread_state.h"
|
||||
@@ -340,6 +343,15 @@ struct X_KTHREAD {
|
||||
};
|
||||
static_assert_size(X_KTHREAD, 0xAB0);
|
||||
|
||||
#if XE_PLATFORM_LINUX
|
||||
// Exception thrown by XThread::Reenter() to unwind through JIT frames.
|
||||
// C++ exception unwinding uses DWARF .eh_frame info registered for JIT code,
|
||||
// ensuring destructors and RAII guards in host C++ frames are properly called.
|
||||
struct FiberReentryException {
|
||||
uint32_t address;
|
||||
};
|
||||
#endif
|
||||
|
||||
class XThread : public XObject, public cpu::Thread {
|
||||
public:
|
||||
static const XObject::Type kObjectType = XObject::Type::Thread;
|
||||
@@ -484,9 +496,14 @@ class XThread : public XObject, public cpu::Thread {
|
||||
std::condition_variable suspend_cv_;
|
||||
#endif
|
||||
|
||||
// Reentry context for setjmp/longjmp based stack unwinding
|
||||
// Reentry mechanism for fiber-based stack switching.
|
||||
// On Linux, C++ exceptions are used instead of setjmp/longjmp so that
|
||||
// destructors and RAII guards in host C++ frames are properly unwound.
|
||||
// JIT code has DWARF .eh_frame unwind info registered via __register_frame.
|
||||
#if XE_PLATFORM_WIN32
|
||||
std::jmp_buf reentry_jmp_buf_;
|
||||
uint32_t reentry_address_ = 0;
|
||||
#endif
|
||||
|
||||
std::mutex thread_lock_;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user