From 3552d8d6096394f43238ca1e2890b78d339d49a9 Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sat, 25 Jul 2026 15:47:06 -0400 Subject: [PATCH 01/12] working on handling thread exits as cleanly as possible, and allowing "one-last" chance to look at thread/process state before exit. This is important because it allows us to no longer need to store the module along with things like breakpoints/bookmarks/etc as the modules will still technically be loaded during this early exit event. --- plugins/DebuggerCore/unix/linux/DebuggerCore.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp index fe6b61e96..7d7110db9 100644 --- a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp +++ b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp @@ -413,7 +413,7 @@ long DebuggerCore::ptraceOptions() const { break; } -#if 0 +#if 1 // TODO(eteran): research this option for issue #46 options |= PTRACE_O_TRACEEXIT; #endif @@ -509,13 +509,16 @@ std::shared_ptr DebuggerCore::handleEvent(edb::tid_t tid, int statu // if this was the last thread, return nullptr // so we report it to the user. // if this wasn't, then we should silently - // procceed. + // proceed. if (!threads_.empty()) { return nullptr; } } if (is_exit_trace_event(status)) { + qDebug() << "Thread" << tid << "is exiting..."; + ptraceContinue(tid, resume_code(status)); + return nullptr; } // was it a thread create event? @@ -545,7 +548,7 @@ std::shared_ptr DebuggerCore::handleEvent(edb::tid_t tid, int statu * * We need to be very careful to avoid those future events causing the * active thread to be set, because we want it to remain set to the thread - * which recieved the initial signal. This is all so that later when the + * which received the initial signal. This is all so that later when the * user clicks resume, that the correct active thread gets (or doesn't) * get signaled, and the rest get resumed properly. * From 2c2ed20cac4328b4a3a0f2f72680751a5c17272d Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sat, 25 Jul 2026 15:55:25 -0400 Subject: [PATCH 02/12] rule of zero for the IDebugEvent:Message struct --- include/IDebugEvent.h | 5 -- .../unix/freebsd/PlatformEvent.cpp | 40 +++++---- .../DebuggerCore/unix/linux/DebuggerCore.cpp | 3 - .../DebuggerCore/unix/linux/PlatformEvent.cpp | 80 ++++++++++------- .../unix/openbsd/PlatformEvent.cpp | 40 +++++---- .../DebuggerCore/unix/osx/PlatformEvent.cpp | 40 +++++---- plugins/DebuggerCore/win32/PlatformEvent.cpp | 88 +++++++++++-------- 7 files changed, 172 insertions(+), 124 deletions(-) diff --git a/include/IDebugEvent.h b/include/IDebugEvent.h index d224a3c1e..b98996da5 100644 --- a/include/IDebugEvent.h +++ b/include/IDebugEvent.h @@ -25,11 +25,6 @@ class IDebugEvent { }; struct Message { - Message() = default; - Message(QString c, QString m, QString s) - : caption(std::move(c)), message(std::move(m)), statusMessage(std::move(s)) { - } - QString caption; QString message; QString statusMessage; diff --git a/plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp b/plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp index 68d0aaf87..d5cc7bb4e 100644 --- a/plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp +++ b/plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp @@ -53,60 +53,68 @@ IDebugEvent::Message PlatformEvent::error_description() const { switch (code()) { case SIGSEGV: - return Message( + return Message{ tr("Illegal Access Fault"), tr( "

The debugged application encountered a segmentation fault.
The address 0x%1 could not be accessed.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

") - .arg(edb::v1::format_pointer(fault_address))); + .arg(edb::v1::format_pointer(fault_address)), + }; case SIGILL: - return Message( + return Message{ tr("Illegal Instruction Fault"), tr( "

The debugged application attempted to execute an illegal instruction.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; case SIGFPE: switch (fault_code_) { case FPE_INTDIV: - return Message( + return Message{ tr("Divide By Zero"), tr( "

The debugged application tried to divide an integer value by an integer divisor of zero.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; default: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The debugged application encountered a floating-point exception.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; } case SIGABRT: - return Message( + return Message{ tr("Application Aborted"), tr( "

The debugged application has aborted.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; case SIGBUS: - return Message( + return Message{ tr("Bus Error"), tr( "

The debugged application tried to read or write data that is misaligned.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; #ifdef SIGSTKFLT case SIGSTKFLT: - return Message( + return Message{ tr("Stack Fault"), tr( "

The debugged application encountered a stack fault.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; #endif case SIGPIPE: - return Message( + return Message{ tr("Broken Pipe Fault"), tr( "

The debugged application encountered a broken pipe fault.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; default: return Message(); } diff --git a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp index 7d7110db9..42f26fa69 100644 --- a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp +++ b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp @@ -413,11 +413,8 @@ long DebuggerCore::ptraceOptions() const { break; } -#if 1 // TODO(eteran): research this option for issue #46 options |= PTRACE_O_TRACEEXIT; -#endif - return options; } diff --git a/plugins/DebuggerCore/unix/linux/PlatformEvent.cpp b/plugins/DebuggerCore/unix/linux/PlatformEvent.cpp index 57d0d6c4f..128a5a6d8 100644 --- a/plugins/DebuggerCore/unix/linux/PlatformEvent.cpp +++ b/plugins/DebuggerCore/unix/linux/PlatformEvent.cpp @@ -26,10 +26,11 @@ IDebugEvent *PlatformEvent::clone() const { * @return */ IDebugEvent::Message PlatformEvent::createUnexpectedSignalMessage(const QString &name, int number) { - return Message( + return Message{ tr("Unexpected Signal Encountered"), tr("

The debugged application encountered a %1 (%2).

").arg(name).arg(number), - tr("% received").arg(name)); + tr("% received").arg(name), + }; } /** @@ -51,104 +52,119 @@ IDebugEvent::Message PlatformEvent::errorDescription() const { case SIGSEGV: switch (siginfo_.si_code) { case SEGV_MAPERR: - message = Message( + message = Message{ tr("Illegal Access Fault"), tr("

The debugged application encountered a segmentation fault.
The address %1 does not appear to be mapped.

").arg(addressString), - tr("SIGSEGV: SEGV_MAPERR: Accessed address %1 not mapped").arg(addressString)); + tr("SIGSEGV: SEGV_MAPERR: Accessed address %1 not mapped").arg(addressString), + }; break; case SEGV_ACCERR: - message = Message( + message = Message{ tr("Illegal Access Fault"), tr("

The debugged application encountered a segmentation fault.
The address %1 could not be accessed.

").arg(addressString), - tr("SIGSEGV: SEGV_ACCERR: Access to address %1 not permitted").arg(addressString)); + tr("SIGSEGV: SEGV_ACCERR: Access to address %1 not permitted").arg(addressString), + }; break; default: - message = Message( + message = Message{ tr("Illegal Access Fault"), tr("

The debugged application encountered a segmentation fault.
The instruction could not be executed.

"), - tr("SIGSEGV: Segmentation fault")); + tr("SIGSEGV: Segmentation fault"), + }; break; } break; case SIGILL: - message = Message( + message = Message{ tr("Illegal Instruction Fault"), tr("

The debugged application attempted to execute an illegal instruction.

"), - tr("SIGILL: Illegal instruction")); + tr("SIGILL: Illegal instruction"), + }; break; case SIGFPE: switch (siginfo_.si_code) { case FPE_INTDIV: - message = Message( + message = Message{ tr("Divide By Zero"), tr("

The debugged application tried to divide an integer value by an integer divisor of zero or encountered integer division overflow.

"), - tr("SIGFPE: FPE_INTDIV: Integer division by zero or division overflow")); + tr("SIGFPE: FPE_INTDIV: Integer division by zero or division overflow"), + }; break; case FPE_FLTDIV: - message = Message( + message = Message{ tr("Divide By Zero"), tr("

The debugged application tried to divide an floating-point value by a floating-point divisor of zero.

"), - tr("SIGFPE: FPE_FLTDIV: Floating-point division by zero")); + tr("SIGFPE: FPE_FLTDIV: Floating-point division by zero"), + }; break; case FPE_FLTOVF: - message = Message( + message = Message{ tr("Numeric Overflow"), tr("

The debugged application encountered a numeric overflow while performing a floating-point computation.

"), - tr("SIGFPE: FPE_FLTOVF: Numeric overflow exception")); + tr("SIGFPE: FPE_FLTOVF: Numeric overflow exception"), + }; break; case FPE_FLTUND: - message = Message( + message = Message{ tr("Numeric Underflow"), tr("

The debugged application encountered a numeric underflow while performing a floating-point computation.

"), - tr("SIGFPE: FPE_FLTUND: Numeric underflow exception")); + tr("SIGFPE: FPE_FLTUND: Numeric underflow exception"), + }; break; case FPE_FLTRES: - message = Message( + message = Message{ tr("Inexact Result"), tr("

The debugged application encountered an inexact result of a floating-point computation it was performing.

"), - tr("SIGFPE: FPE_FLTRES: Inexact result exception")); + tr("SIGFPE: FPE_FLTRES: Inexact result exception"), + }; break; case FPE_FLTINV: - message = Message( + message = Message{ tr("Invalid Operation"), tr("

The debugged application attempted to perform an invalid floating-point operation.

"), - tr("SIGFPE: FPE_FLTINV: Invalid floating-point operation")); + tr("SIGFPE: FPE_FLTINV: Invalid floating-point operation"), + }; break; default: - message = Message( + message = Message{ tr("Floating Point Exception"), tr("

The debugged application encountered a floating-point exception.

"), - tr("SIGFPE: Floating-point exception")); + tr("SIGFPE: Floating-point exception"), + }; break; } break; case SIGABRT: - message = Message( + message = Message{ tr("Application Aborted"), tr("

The debugged application has aborted.

"), - tr("SIGABRT: Application aborted")); + tr("SIGABRT: Application aborted"), + }; break; case SIGBUS: - message = Message( + message = Message{ tr("Bus Error"), tr("

The debugged application received a bus error. Typically, this means that it tried to read or write data that is misaligned.

"), - tr("SIGBUS: Bus error")); + tr("SIGBUS: Bus error"), + }; break; #ifdef SIGSTKFLT case SIGSTKFLT: - message = Message( + message = Message{ tr("Stack Fault"), tr("

The debugged application encountered a stack fault.

"), - tr("SIGSTKFLT: Stack fault")); + tr("SIGSTKFLT: Stack fault"), + }; break; #endif case SIGPIPE: - message = Message( + message = Message{ tr("Broken Pipe Fault"), tr("

The debugged application encountered a broken pipe fault.

"), - tr("SIGPIPE: Pipe broken")); + tr("SIGPIPE: Pipe broken"), + }; break; #ifdef SIGHUP case SIGHUP: diff --git a/plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp b/plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp index 94cba52c6..803b1fc50 100644 --- a/plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp +++ b/plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp @@ -50,60 +50,68 @@ IDebugEvent::Message PlatformEvent::error_description() const { switch (code()) { case SIGSEGV: - return Message( + return Message{ tr("Illegal Access Fault"), tr( "

The debugged application encountered a segmentation fault.
The address 0x%1 could not be accessed.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

") - .arg(edb::v1::format_pointer(fault_address))); + .arg(edb::v1::format_pointer(fault_address)), + }; case SIGILL: - return Message( + return Message{ tr("Illegal Instruction Fault"), tr( "

The debugged application attempted to execute an illegal instruction.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; case SIGFPE: switch (fault_code_) { case FPE_INTDIV: - return Message( + return Message{ tr("Divide By Zero"), tr( "

The debugged application tried to divide an integer value by an integer divisor of zero.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; default: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The debugged application encountered a floating-point exception.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; } case SIGABRT: - return Message( + return Message{ tr("Application Aborted"), tr( "

The debugged application has aborted.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; case SIGBUS: - return Message( + return Message{ tr("Bus Error"), tr( "

The debugged application tried to read or write data that is misaligned.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; #ifdef SIGSTKFLT case SIGSTKFLT: - return Message( + return Message{ tr("Stack Fault"), tr( "

The debugged application encountered a stack fault.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; #endif case SIGPIPE: - return Message( + return Message{ tr("Broken Pipe Fault"), tr( "

The debugged application encountered a broken pipe fault.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; default: return Message(); } diff --git a/plugins/DebuggerCore/unix/osx/PlatformEvent.cpp b/plugins/DebuggerCore/unix/osx/PlatformEvent.cpp index ab2a47347..0e0fae7bc 100644 --- a/plugins/DebuggerCore/unix/osx/PlatformEvent.cpp +++ b/plugins/DebuggerCore/unix/osx/PlatformEvent.cpp @@ -40,61 +40,69 @@ IDebugEvent::Message PlatformEvent::error_description() const { switch (code()) { case SIGSEGV: - return Message( + return Message{ tr("Illegal Access Fault"), tr( "

The debugged application encountered a segmentation fault.
The address 0x%1 could not be accessed.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

") - .arg(edb::v1::format_pointer(fault_address))); + .arg(edb::v1::format_pointer(fault_address)), + }; case SIGILL: - return Message( + return Message{ tr("Illegal Instruction Fault"), tr( "

The debugged application attempted to execute an illegal instruction.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; case SIGFPE: // TODO: figure out the fault code for FPU stuff switch (0) { case FPE_INTDIV: - return Message( + return Message{ tr("Divide By Zero"), tr( "

The debugged application tried to divide an integer value by an integer divisor of zero.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; default: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The debugged application encountered a floating-point exception.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; } case SIGABRT: - return Message( + return Message{ tr("Application Aborted"), tr( "

The debugged application has aborted.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; case SIGBUS: - return Message( + return Message{ tr("Bus Error"), tr( "

The debugged application tried to read or write data that is misaligned.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; #ifdef SIGSTKFLT case SIGSTKFLT: - return Message( + return Message{ tr("Stack Fault"), tr( "

The debugged application encountered a stack fault.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; #endif case SIGPIPE: - return Message( + return Message{ tr("Broken Pipe Fault"), tr( "

The debugged application encountered a broken pipe fault.

" - "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

")); + "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), + }; default: return Message(); } diff --git a/plugins/DebuggerCore/win32/PlatformEvent.cpp b/plugins/DebuggerCore/win32/PlatformEvent.cpp index a7c004623..be7852a94 100644 --- a/plugins/DebuggerCore/win32/PlatformEvent.cpp +++ b/plugins/DebuggerCore/win32/PlatformEvent.cpp @@ -33,134 +33,150 @@ IDebugEvent::Message PlatformEvent::errorDescription() const { switch (code()) { case EXCEPTION_ACCESS_VIOLATION: - return Message( + return Message{ tr("Illegal Access Fault"), tr( "

The debugged application encountered a segmentation fault.
The address 0x%1 could not be accessed.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

") .arg(edb::v1::format_pointer(fault_address)), - tr("EXCEPTION_ACCESS_VIOLATION")); + tr("EXCEPTION_ACCESS_VIOLATION"), + }; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - return Message( + return Message{ tr("Array Bounds Error"), tr( "

The debugged application tried to access an out of bounds array element.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

") .arg(edb::v1::format_pointer(fault_address)), - tr("EXCEPTION_ARRAY_BOUNDS_EXCEEDED")); + }; case EXCEPTION_DATATYPE_MISALIGNMENT: - return Message( + return Message{ tr("Bus Error"), tr( "

The debugged application tried to read or write data that is misaligned.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_DATATYPE_MISALIGNMENT")); + }; case EXCEPTION_FLT_DENORMAL_OPERAND: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_FLT_DENORMAL_OPERAND")); + tr("EXCEPTION_FLT_DENORMAL_OPERAND"), + }; case EXCEPTION_FLT_DIVIDE_BY_ZERO: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The debugged application tried to divide a floating-point value by a floating-point divisor of zero.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_FLT_DIVIDE_BY_ZERO")); + tr("EXCEPTION_FLT_DIVIDE_BY_ZERO"), + }; case EXCEPTION_FLT_INEXACT_RESULT: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The result of a floating-point operation cannot be represented exactly as a decimal fraction.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPITION_FLT_INEXACT_RESULT")); + tr("EXCEPTION_FLT_INEXACT_RESULT"), + }; case EXCEPTION_FLT_INVALID_OPERATION: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The application attempted an invalid floating point operation.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_FLT_INVALID_OPERATION")); + tr("EXCEPTION_FLT_INVALID_OPERATION"), + }; case EXCEPTION_FLT_OVERFLOW: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_FLT_OVERFLOW")); + tr("EXCEPTION_FLT_OVERFLOW"), + }; case EXCEPTION_FLT_STACK_CHECK: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The stack overflowed or underflowed as the result of a floating-point operation.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_FLT_STACK_CHECK")); + tr("EXCEPTION_FLT_STACK_CHECK"), + }; case EXCEPTION_FLT_UNDERFLOW: - return Message( + return Message{ tr("Floating Point Exception"), tr( "

The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_FLT_UNDERFLOW")); + tr("EXCEPTION_FLT_UNDERFLOW"), + }; case EXCEPTION_ILLEGAL_INSTRUCTION: - return Message( + return Message{ tr("Illegal Instruction Fault"), tr( "

The debugged application attempted to execute an illegal instruction.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_ILLEGAL_INSTRUCTION")); + tr("EXCEPTION_ILLEGAL_INSTRUCTION"), + }; case EXCEPTION_IN_PAGE_ERROR: - return Message( + return Message{ tr("Page Error"), tr( "

The debugged application tried to access a page that was not present, and the system was unable to load the page.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_IN_PAGE_ERROR")); + tr("EXCEPTION_IN_PAGE_ERROR"), + }; case EXCEPTION_INT_DIVIDE_BY_ZERO: - return Message( + return Message{ tr("Divide By Zero"), tr( "

The debugged application tried to divide an integer value by an integer divisor of zero.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_INT_DIVIDE_BY_ZERO")); + tr("EXCEPTION_INT_DIVIDE_BY_ZERO"), + }; case EXCEPTION_INT_OVERFLOW: - return Message( + return Message{ tr("Integer Overflow"), tr( "

The result of an integer operation caused a carry out of the most significant bit of the result.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_INT_OVERFLOW")); + tr("EXCEPTION_INT_OVERFLOW"), + }; case EXCEPTION_INVALID_DISPOSITION: - return Message( + return Message{ tr("Invalid Disposition"), tr( "

An exception handler returned an invalid disposition to the exception dispatcher.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_INVALID_DISPOSITION")); + tr("EXCEPTION_INVALID_DISPOSITION"), + }; case EXCEPTION_NONCONTINUABLE_EXCEPTION: - return Message( + return Message{ tr("Non-Continuable Exception"), tr( "

The debugged application tried to continue execution after a non-continuable exception occurred.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_NONCONTINUABLE_EXCEPTION")); + tr("EXCEPTION_NONCONTINUABLE_EXCEPTION"), + }; case EXCEPTION_PRIV_INSTRUCTION: - return Message( + return Message{ tr("Privileged Instruction"), tr( "

The debugged application tried to execute an instruction whose operation is not allowed in the current machine mode.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_PRIV_INSTRUCTION")); + tr("EXCEPTION_PRIV_INSTRUCTION"), + }; case EXCEPTION_STACK_OVERFLOW: - return Message( + return Message{ tr("Stack Overflow"), tr( "

The debugged application has exhausted its stack.

" "

If you would like to pass this exception to the application press Shift+[F7/F8/F9]

"), - tr("EXCEPTION_STACK_OVERFLOW")); + tr("EXCEPTION_STACK_OVERFLOW"), + }; default: return Message(); } From 6bff1248041582ffff5e5f446335997226650f2d Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sat, 25 Jul 2026 23:56:14 -0400 Subject: [PATCH 03/12] remove redundant check --- plugins/HardwareBreakpoints/HardwareBreakpoints.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/HardwareBreakpoints/HardwareBreakpoints.cpp b/plugins/HardwareBreakpoints/HardwareBreakpoints.cpp index 759173b9a..935eae51c 100644 --- a/plugins/HardwareBreakpoints/HardwareBreakpoints.cpp +++ b/plugins/HardwareBreakpoints/HardwareBreakpoints.cpp @@ -218,7 +218,7 @@ void HardwareBreakpoints::showMenu() { */ edb::EventStatus HardwareBreakpoints::handleEvent(const std::shared_ptr &event) { - if (event->stopped() && event->isTrap()) { + if (event->isTrap()) { if (IProcess *process = edb::v1::debugger_core->process()) { if (std::shared_ptr thread = process->currentThread()) { From b296daca23ce4d38622d6476b396646fc3662483 Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sun, 26 Jul 2026 00:00:37 -0400 Subject: [PATCH 04/12] removing code that isn't really used --- include/IDebugEvent.h | 3 --- plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp | 9 --------- plugins/DebuggerCore/unix/linux/PlatformEvent.cpp | 9 --------- plugins/DebuggerCore/unix/linux/PlatformEvent.h | 3 --- plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp | 7 ------- plugins/DebuggerCore/unix/osx/PlatformEvent.cpp | 7 ------- plugins/DebuggerCore/win32/PlatformEvent.cpp | 9 --------- 7 files changed, 47 deletions(-) diff --git a/include/IDebugEvent.h b/include/IDebugEvent.h index b98996da5..990e45f76 100644 --- a/include/IDebugEvent.h +++ b/include/IDebugEvent.h @@ -33,9 +33,6 @@ class IDebugEvent { public: virtual ~IDebugEvent() = default; -public: - [[nodiscard]] virtual IDebugEvent *clone() const = 0; - public: [[nodiscard]] virtual Message errorDescription() const = 0; [[nodiscard]] virtual REASON reason() const = 0; diff --git a/plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp b/plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp index d5cc7bb4e..9b9f5d491 100644 --- a/plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp +++ b/plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp @@ -32,15 +32,6 @@ PlatformEvent::PlatformEvent() : status(0), pid(-1), tid(-1), fault_address_(0), fault_code_(0) { } -/** - * @brief Creates a new PlatformEvent instance that is a copy of the current instance. - * - * @return A pointer to the newly created PlatformEvent instance. - */ -PlatformEvent *PlatformEvent::clone() const { - return new PlatformEvent(*this); -} - /** * @brief Returns a user-friendly error message describing the reason for the debug event, if it is an error event. * diff --git a/plugins/DebuggerCore/unix/linux/PlatformEvent.cpp b/plugins/DebuggerCore/unix/linux/PlatformEvent.cpp index 128a5a6d8..e382fd7b9 100644 --- a/plugins/DebuggerCore/unix/linux/PlatformEvent.cpp +++ b/plugins/DebuggerCore/unix/linux/PlatformEvent.cpp @@ -9,15 +9,6 @@ namespace DebuggerCorePlugin { -/** - * @brief Creates and returns a heap-allocated copy of this event. - * - * @return - */ -IDebugEvent *PlatformEvent::clone() const { - return new PlatformEvent(*this); -} - /** * @brief Constructs a generic unexpected-signal Message with the given signal name and number. * diff --git a/plugins/DebuggerCore/unix/linux/PlatformEvent.h b/plugins/DebuggerCore/unix/linux/PlatformEvent.h index 61fc41300..85e5bfa1d 100644 --- a/plugins/DebuggerCore/unix/linux/PlatformEvent.h +++ b/plugins/DebuggerCore/unix/linux/PlatformEvent.h @@ -25,9 +25,6 @@ class PlatformEvent final : public IDebugEvent { PlatformEvent(const PlatformEvent &) = default; PlatformEvent &operator=(const PlatformEvent &) = default; -public: - [[nodiscard]] IDebugEvent *clone() const override; - public: [[nodiscard]] bool exited() const override; [[nodiscard]] bool isError() const override; diff --git a/plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp b/plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp index 803b1fc50..44f53b333 100644 --- a/plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp +++ b/plugins/DebuggerCore/unix/openbsd/PlatformEvent.cpp @@ -33,13 +33,6 @@ PlatformEvent::PlatformEvent() : status(0), pid(-1), tid(-1), fault_address_(0), fault_code_(0) { } -/** - * @brief - */ -PlatformEvent *PlatformEvent::clone() const { - return new PlatformEvent(*this); -} - /** * @brief */ diff --git a/plugins/DebuggerCore/unix/osx/PlatformEvent.cpp b/plugins/DebuggerCore/unix/osx/PlatformEvent.cpp index 0e0fae7bc..a82f94783 100644 --- a/plugins/DebuggerCore/unix/osx/PlatformEvent.cpp +++ b/plugins/DebuggerCore/unix/osx/PlatformEvent.cpp @@ -22,13 +22,6 @@ PlatformEvent::PlatformEvent() : status(0), pid(-1), tid(-1) { } -/** - * @brief - */ -PlatformEvent *PlatformEvent::clone() const { - return new PlatformEvent(*this); -} - /** * @brief */ diff --git a/plugins/DebuggerCore/win32/PlatformEvent.cpp b/plugins/DebuggerCore/win32/PlatformEvent.cpp index be7852a94..cb62a448a 100644 --- a/plugins/DebuggerCore/win32/PlatformEvent.cpp +++ b/plugins/DebuggerCore/win32/PlatformEvent.cpp @@ -9,15 +9,6 @@ namespace DebuggerCorePlugin { -/** - * @brief Clones the current PlatformEvent instance. - * - * @return A pointer to a new PlatformEvent instance that is a copy of the current instance. - */ -PlatformEvent *PlatformEvent::clone() const { - return new PlatformEvent(*this); -} - /** * @brief Gets the error description for the current PlatformEvent instance. * From 5581813ec5eb4cc86aac905e38ebc808a39aca44 Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sun, 26 Jul 2026 00:01:20 -0400 Subject: [PATCH 05/12] more unused code removal --- plugins/DebuggerCore/unix/linux/PlatformEvent.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/DebuggerCore/unix/linux/PlatformEvent.h b/plugins/DebuggerCore/unix/linux/PlatformEvent.h index 85e5bfa1d..d0faa5dce 100644 --- a/plugins/DebuggerCore/unix/linux/PlatformEvent.h +++ b/plugins/DebuggerCore/unix/linux/PlatformEvent.h @@ -21,10 +21,6 @@ class PlatformEvent final : public IDebugEvent { public: PlatformEvent() = default; -private: - PlatformEvent(const PlatformEvent &) = default; - PlatformEvent &operator=(const PlatformEvent &) = default; - public: [[nodiscard]] bool exited() const override; [[nodiscard]] bool isError() const override; From 1969c06c32445b8e6a019fda1d21e64291e3cd34 Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sun, 26 Jul 2026 00:08:10 -0400 Subject: [PATCH 06/12] a bunch of doc-string stuff while I'm in there --- .../DebuggerCore/unix/linux/DebuggerCore.cpp | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp index 42f26fa69..7def92222 100644 --- a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp +++ b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp @@ -490,9 +490,9 @@ std::shared_ptr DebuggerCore::handleThreadCreate(edb::tid_t tid, in /** * @brief Processes the waitpid status for the given thread and returns the corresponding debug event. * - * @param tid - * @param status - * @return + * @param tid The thread ID of the thread for which the event is being handled. + * @param status The waitpid status value for the thread. + * @return The corresponding IDebugEvent, or nullptr if no event should be reported. */ std::shared_ptr DebuggerCore::handleEvent(edb::tid_t tid, int status) { @@ -598,7 +598,7 @@ std::shared_ptr DebuggerCore::handleEvent(edb::tid_t tid, int statu /** * @brief Sends SIGSTOP to all running threads that have not yet been waited on. * - * @return + * @return A Status object indicating success or failure of the operation. If any thread fails to stop, the error message will contain details. */ Status DebuggerCore::stopThreads() { @@ -648,8 +648,8 @@ Status DebuggerCore::stopThreads() { /** * @brief Waits up to the given timeout for a debug event from any traced thread, returning the event or nullptr on timeout. * - * @param msecs - * @return nullptr if an error or timeout occurs + * @param msecs The maximum time to wait for a debug event, in milliseconds. + * @return The IDebugEvent if an event occurs, or nullptr if an error or timeout occurs. */ std::shared_ptr DebuggerCore::waitDebugEvent(std::chrono::milliseconds msecs) { @@ -670,7 +670,7 @@ std::shared_ptr DebuggerCore::waitDebugEvent(std::chrono::milliseco /** * @brief Attaches to the given thread via PTRACE_ATTACH and registers it in the thread map. * - * @param tid + * @param tid The thread ID of the thread to attach to. * @return 0 if successful, errno if failed */ int DebuggerCore::attachThread(edb::tid_t tid) { @@ -710,8 +710,8 @@ int DebuggerCore::attachThread(edb::tid_t tid) { /** * @brief Attaches to an already-running process, tracing all of its threads. * - * @param pid - * @return + * @param pid The process ID of the process to attach to. + * @return A Status object indicating success or failure of the attach operation. */ Status DebuggerCore::attach(edb::pid_t pid) { @@ -762,7 +762,7 @@ Status DebuggerCore::attach(edb::pid_t pid) { /** * @brief Detaches from the traced process, resuming all its threads. * - * @return + * @return A Status object indicating success or failure of the detach operation. If any thread fails to detach, the error message will contain details. */ Status DebuggerCore::detach() { @@ -873,11 +873,12 @@ void DebuggerCore::detectCpuMode() { /** * @brief Forks, optionally disables ASLR and lazy binding, and launches the specified process under ptrace. * - * @param path - * @param cwd - * @param args - * @param tty - * @return + * @param path The path to the executable to launch. + * @param cwd The working directory for the launched process. + * @param args The command-line arguments for the launched process. + * @param input The file to use as standard input for the launched process. + * @param output The file to use as standard output and standard error for the launched process. + * @return A Status object indicating success or failure of the launch operation. */ Status DebuggerCore::open(const QString &path, const QString &cwd, const QList &args, const QString &input, const QString &output) { @@ -1061,8 +1062,8 @@ QMap> DebuggerCore::enumerateProcesses() c /** * @brief Returns the parent process ID for the given PID by reading /proc/[pid]/stat. * - * @param pid - * @return + * @param pid The process ID for which to retrieve the parent PID. + * @return The parent process ID, or 0 if it cannot be determined. */ edb::pid_t DebuggerCore::parentPid(edb::pid_t pid) const { @@ -1097,7 +1098,7 @@ uint64_t DebuggerCore::cpuType() const { /** * @brief Returns the architecture-appropriate stack pointer register name. * - * @return + * @return The name of the stack pointer register for the current architecture. */ QString DebuggerCore::stackPointer() const { #if defined(EDB_X86) || defined(EDB_X86_64) @@ -1117,7 +1118,7 @@ QString DebuggerCore::stackPointer() const { /** * @brief Returns the architecture-appropriate frame pointer register name. * - * @return + * @return The name of the frame pointer register for the current architecture. */ QString DebuggerCore::framePointer() const { #if defined(EDB_X86) || defined(EDB_X86_64) @@ -1136,7 +1137,7 @@ QString DebuggerCore::framePointer() const { /** * @brief Returns the architecture-appropriate instruction pointer register name. * - * @return + * @return The name of the instruction pointer register for the current architecture. */ QString DebuggerCore::instructionPointer() const { #if defined(EDB_X86) || defined(EDB_X86_64) @@ -1155,7 +1156,7 @@ QString DebuggerCore::instructionPointer() const { /** * @brief Returns the architecture-appropriate flags/status register name. * - * @return the name of the flag register + * @return The name of the flag register for the current architecture. */ QString DebuggerCore::flagRegister() const { #if defined(EDB_X86) || defined(EDB_X86_64) @@ -1174,7 +1175,7 @@ QString DebuggerCore::flagRegister() const { /** * @brief Returns a raw pointer to the currently attached process, or nullptr if not attached. * - * @return + * @return A pointer to the IProcess representing the currently debugged process, or nullptr if no process is being debugged. */ IProcess *DebuggerCore::process() const { return process_.get(); @@ -1183,7 +1184,7 @@ IProcess *DebuggerCore::process() const { /** * @brief Stores the list of exception (signal) numbers that should be silently passed to the debuggee. * - * @param exceptions + * @param exceptions A list of signal numbers to ignore. */ void DebuggerCore::setIgnoredExceptions(const QList &exceptions) { ignoredExceptions_ = exceptions; @@ -1192,7 +1193,7 @@ void DebuggerCore::setIgnoredExceptions(const QList &exceptions) { /** * @brief Returns the map of Unix signal numbers and their names. * - * @return + * @return A map of Unix signal numbers to their corresponding names. */ QMap DebuggerCore::exceptions() const { return Unix::exceptions(); @@ -1201,8 +1202,8 @@ QMap DebuggerCore::exceptions() const { /** * @brief Returns the name string for the Unix signal with the given numeric value. * - * @param value - * @return + * @param value The numeric value of the Unix signal for which to retrieve the name. + * @return The name of the Unix signal corresponding to the given numeric value. */ QString DebuggerCore::exceptionName(qlonglong value) { return Unix::exception_name(value); @@ -1211,8 +1212,8 @@ QString DebuggerCore::exceptionName(qlonglong value) { /** * @brief Returns the numeric value for the Unix signal with the given name. * - * @param name - * @return + * @param name The name of the Unix signal for which to retrieve the numeric value. + * @return The numeric value of the Unix signal corresponding to the given name. */ qlonglong DebuggerCore::exceptionValue(const QString &name) { return Unix::exception_value(name); @@ -1221,7 +1222,7 @@ qlonglong DebuggerCore::exceptionValue(const QString &name) { /** * @brief Returns the byte value used to fill NOP-padded regions for the current architecture. * - * @return + * @return The byte value used to fill NOP-padded regions for the current architecture. */ uint8_t DebuggerCore::nopFillByte() const { #if defined(EDB_X86) || defined(EDB_X86_64) From 501a16d4fd511252421e9b1911ef0b1d93b59401 Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sun, 26 Jul 2026 00:13:21 -0400 Subject: [PATCH 07/12] formatting --- include/Comment.h | 2 +- include/IBreakpoint.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Comment.h b/include/Comment.h index 693340a07..da6ee2f76 100644 --- a/include/Comment.h +++ b/include/Comment.h @@ -2,8 +2,8 @@ #ifndef COMMENT_H_ #define COMMENT_H_ -#include "Types.h" #include "Module.h" +#include "Types.h" #include diff --git a/include/IBreakpoint.h b/include/IBreakpoint.h index 4ad076a69..fe84e67ba 100644 --- a/include/IBreakpoint.h +++ b/include/IBreakpoint.h @@ -7,8 +7,8 @@ #ifndef IBREAKPOINT_H_20060720_ #define IBREAKPOINT_H_20060720_ -#include "Types.h" #include "Module.h" +#include "Types.h" #include #include From 467fbe4a49cacf5af07e9c03648f98f26dad75da Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sun, 26 Jul 2026 00:31:41 -0400 Subject: [PATCH 08/12] adding "heapStart" to IProcess as it's useful for the Heap analyzer plugin. --- include/IProcess.h | 1 + plugins/DebuggerCore/unix/linux/PlatformProcess.cpp | 10 ++++++++++ plugins/DebuggerCore/unix/linux/PlatformProcess.h | 1 + plugins/HeapAnalyzer/DialogHeap.cpp | 8 +++++++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/IProcess.h b/include/IProcess.h index 9b96377d1..e1ae2baf9 100644 --- a/include/IProcess.h +++ b/include/IProcess.h @@ -39,6 +39,7 @@ class IProcess { [[nodiscard]] virtual edb::address_t codeAddress() const = 0; [[nodiscard]] virtual edb::address_t dataAddress() const = 0; [[nodiscard]] virtual edb::address_t entryPoint() const = 0; + [[nodiscard]] virtual edb::address_t heapStart() const = 0; [[nodiscard]] virtual QList> regions() const = 0; [[nodiscard]] virtual edb::uid_t uid() const = 0; [[nodiscard]] virtual QString user() const = 0; diff --git a/plugins/DebuggerCore/unix/linux/PlatformProcess.cpp b/plugins/DebuggerCore/unix/linux/PlatformProcess.cpp index f47a071f3..383e58979 100644 --- a/plugins/DebuggerCore/unix/linux/PlatformProcess.cpp +++ b/plugins/DebuggerCore/unix/linux/PlatformProcess.cpp @@ -573,6 +573,16 @@ edb::address_t PlatformProcess::dataAddress() const { return 0; } +[[nodiscard]] edb::address_t PlatformProcess::heapStart() const { + struct user_stat user_stat; + int n = get_user_stat(pid_, &user_stat); + if (n >= 47) { + return user_stat.start_brk; + } + return 0; + +} + /** * @brief Returns the list of all mapped memory regions by reading /proc/[pid]/maps. * diff --git a/plugins/DebuggerCore/unix/linux/PlatformProcess.h b/plugins/DebuggerCore/unix/linux/PlatformProcess.h index 421f3e811..2f4868405 100644 --- a/plugins/DebuggerCore/unix/linux/PlatformProcess.h +++ b/plugins/DebuggerCore/unix/linux/PlatformProcess.h @@ -31,6 +31,7 @@ class PlatformProcess final : public IProcess { [[nodiscard]] edb::address_t codeAddress() const override; [[nodiscard]] edb::address_t dataAddress() const override; [[nodiscard]] edb::address_t entryPoint() const override; + [[nodiscard]] edb::address_t heapStart() const override; [[nodiscard]] edb::pid_t pid() const override; [[nodiscard]] edb::uid_t uid() const override; [[nodiscard]] QDateTime startTime() const override; diff --git a/plugins/HeapAnalyzer/DialogHeap.cpp b/plugins/HeapAnalyzer/DialogHeap.cpp index 02ec0189c..afe073621 100644 --- a/plugins/HeapAnalyzer/DialogHeap.cpp +++ b/plugins/HeapAnalyzer/DialogHeap.cpp @@ -553,7 +553,13 @@ void DialogHeap::doFind() { if (heap_symbol_start != 0) { process->readBytes(heap_symbol_start, &start_address, edb::v1::pointer_size()); } else { - qDebug("[Heap Analyzer] __curbrk symbol not found in ld, falling back on heuristic! This may or may not work."); + + start_address = process->heapStart(); + if (start_address != 0) { + qDebug("[Heap Analyzer] __curbrk symbol not found in ld, falling back on process->heapStart() : %s", edb::v1::format_pointer(start_address).toUtf8().constData()); + } else { + qDebug("[Heap Analyzer] __curbrk symbol not found in ld, falling back on heuristic! This may or may not work."); + } } if (heap_symbol_end != 0) { From 55ee69789bea3f25867c1f6e6c168623eeec6f47 Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sun, 26 Jul 2026 00:33:55 -0400 Subject: [PATCH 09/12] formatting --- plugins/HeapAnalyzer/DialogHeap.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/HeapAnalyzer/DialogHeap.cpp b/plugins/HeapAnalyzer/DialogHeap.cpp index afe073621..e329abf30 100644 --- a/plugins/HeapAnalyzer/DialogHeap.cpp +++ b/plugins/HeapAnalyzer/DialogHeap.cpp @@ -547,8 +547,8 @@ void DialogHeap::doFind() { } } - qDebug() << "[Heap Analyzer] ld __curbrk symbol : " << edb::v1::format_pointer(heap_symbol_start); - qDebug() << "[Heap Analyzer] libc __curbrk symbol : " << edb::v1::format_pointer(heap_symbol_end); + qDebug() << "[Heap Analyzer] ld __curbrk symbol :" << edb::v1::format_pointer(heap_symbol_start); + qDebug() << "[Heap Analyzer] libc __curbrk symbol :" << edb::v1::format_pointer(heap_symbol_end); if (heap_symbol_start != 0) { process->readBytes(heap_symbol_start, &start_address, edb::v1::pointer_size()); @@ -556,7 +556,7 @@ void DialogHeap::doFind() { start_address = process->heapStart(); if (start_address != 0) { - qDebug("[Heap Analyzer] __curbrk symbol not found in ld, falling back on process->heapStart() : %s", edb::v1::format_pointer(start_address).toUtf8().constData()); + qDebug() << "[Heap Analyzer] __curbrk symbol not found in ld, falling back on process->heapStart() :" << edb::v1::format_pointer(start_address); } else { qDebug("[Heap Analyzer] __curbrk symbol not found in ld, falling back on heuristic! This may or may not work."); } From f643a2fbd4611c62c7fdebe854661d696a6f73fd Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Sun, 26 Jul 2026 00:57:24 -0400 Subject: [PATCH 10/12] some comments and formatting of logging --- plugins/DebuggerCore/unix/linux/DebuggerCore.cpp | 3 +++ plugins/DebuggerCore/unix/linux/PlatformProcess.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp index 7def92222..8e51a7d02 100644 --- a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp +++ b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp @@ -513,6 +513,9 @@ std::shared_ptr DebuggerCore::handleEvent(edb::tid_t tid, int statu } if (is_exit_trace_event(status)) { + // TODO(eteran): I think we're only really interested in the last thread exiting, but we should probably + // handle this more gracefully, and perhaps even report the exit of each thread to + // the caller. For now, we just ignore the event and continue the thread, which will result in a normal waitpid exit event. qDebug() << "Thread" << tid << "is exiting..."; ptraceContinue(tid, resume_code(status)); return nullptr; diff --git a/plugins/DebuggerCore/unix/linux/PlatformProcess.cpp b/plugins/DebuggerCore/unix/linux/PlatformProcess.cpp index 383e58979..0cb26dd61 100644 --- a/plugins/DebuggerCore/unix/linux/PlatformProcess.cpp +++ b/plugins/DebuggerCore/unix/linux/PlatformProcess.cpp @@ -1155,7 +1155,7 @@ edb::address_t PlatformProcess::calculateMain() const { if (address) { // TODO: make sure that this address resides in an executable region - qDebug() << "No main symbol found, calculated it to be " << edb::v1::format_pointer(address) << " using heuristic"; + qDebug() << "No main symbol found, calculated it to be" << edb::v1::format_pointer(address) << "using heuristic"; return address; } } @@ -1182,7 +1182,7 @@ edb::address_t PlatformProcess::calculateMain() const { std::memcpy(to, ba.data() + 1, sizeof(uint32_t)); // TODO: make sure that this address resides in an executable region - qDebug() << "No main symbol found, calculated it to be " << edb::v1::format_pointer(address) << " using heuristic"; + qDebug() << "No main symbol found, calculated it to be" << edb::v1::format_pointer(address) << "using heuristic"; return address; } } From 658169dd3ab6795c4be0858e0c4735284841e99e Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Mon, 10 Aug 2026 10:18:42 -0400 Subject: [PATCH 11/12] disabling tracving exit (for now) --- plugins/DebuggerCore/unix/linux/DebuggerCore.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp index 8e51a7d02..001eadea3 100644 --- a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp +++ b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp @@ -413,8 +413,10 @@ long DebuggerCore::ptraceOptions() const { break; } +#if 0 // TODO(eteran): research this option for issue #46 options |= PTRACE_O_TRACEEXIT; +#endif return options; } From 4753acc2c72c3bfc421b29982b321883cbba90b7 Mon Sep 17 00:00:00 2001 From: Evan Teran Date: Fri, 14 Aug 2026 10:13:58 -0400 Subject: [PATCH 12/12] stubbing out how we'll know it's the last thread --- plugins/DebuggerCore/unix/linux/DebuggerCore.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp index 001eadea3..c55338978 100644 --- a/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp +++ b/plugins/DebuggerCore/unix/linux/DebuggerCore.cpp @@ -520,6 +520,10 @@ std::shared_ptr DebuggerCore::handleEvent(edb::tid_t tid, int statu // the caller. For now, we just ignore the event and continue the thread, which will result in a normal waitpid exit event. qDebug() << "Thread" << tid << "is exiting..."; ptraceContinue(tid, resume_code(status)); + if (threads_.size() == 1) { + // if this was the last thread maybe report to the caller that the process is exiting? + // For now, we just return nullptr and let the normal waitpid exit event be reported. + } return nullptr; }