Skip to content
Open
2 changes: 1 addition & 1 deletion include/Comment.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#ifndef COMMENT_H_
#define COMMENT_H_

#include "Types.h"
#include "Module.h"
#include "Types.h"

#include <QString>

Expand Down
2 changes: 1 addition & 1 deletion include/IBreakpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#ifndef IBREAKPOINT_H_20060720_
#define IBREAKPOINT_H_20060720_

#include "Types.h"
#include "Module.h"
#include "Types.h"

#include <QString>
#include <exception>
Expand Down
8 changes: 0 additions & 8 deletions include/IDebugEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,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;
Expand Down
1 change: 1 addition & 0 deletions include/IProcess.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::shared_ptr<IRegion>> regions() const = 0;
[[nodiscard]] virtual edb::uid_t uid() const = 0;
[[nodiscard]] virtual QString user() const = 0;
Expand Down
49 changes: 24 additions & 25 deletions plugins/DebuggerCore/unix/freebsd/PlatformEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -53,60 +44,68 @@ IDebugEvent::Message PlatformEvent::error_description() const {

switch (code()) {
case SIGSEGV:
return Message(
return Message{
tr("Illegal Access Fault"),
tr(
"<p>The debugged application encountered a segmentation fault.<br />The address <strong>0x%1</strong> could not be accessed.</p>"
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>")
.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(
"<p>The debugged application attempted to execute an illegal instruction.</p>"
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"));
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"),
};
case SIGFPE:
switch (fault_code_) {
case FPE_INTDIV:
return Message(
return Message{
tr("Divide By Zero"),
tr(
"<p>The debugged application tried to divide an integer value by an integer divisor of zero.</p>"
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"));
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"),
};
default:
return Message(
return Message{
tr("Floating Point Exception"),
tr(
"<p>The debugged application encountered a floating-point exception.</p>"
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"));
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"),
};
}

case SIGABRT:
return Message(
return Message{
tr("Application Aborted"),
tr(
"<p>The debugged application has aborted.</p>"
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"));
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"),
};
case SIGBUS:
return Message(
return Message{
tr("Bus Error"),
tr(
"<p>The debugged application tried to read or write data that is misaligned.</p>"
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"));
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"),
};
#ifdef SIGSTKFLT
case SIGSTKFLT:
return Message(
return Message{
tr("Stack Fault"),
tr(
"<p>The debugged application encountered a stack fault.</p>"
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"));
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"),
};
#endif
case SIGPIPE:
return Message(
return Message{
tr("Broken Pipe Fault"),
tr(
"<p>The debugged application encountered a broken pipe fault.</p>"
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"));
"<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>"),
};
default:
return Message();
}
Expand Down
74 changes: 42 additions & 32 deletions plugins/DebuggerCore/unix/linux/DebuggerCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,6 @@ long DebuggerCore::ptraceOptions() const {
// TODO(eteran): research this option for issue #46
options |= PTRACE_O_TRACEEXIT;
#endif

return options;
}

Expand Down Expand Up @@ -493,9 +492,9 @@ std::shared_ptr<IDebugEvent> 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<IDebugEvent> DebuggerCore::handleEvent(edb::tid_t tid, int status) {

Expand All @@ -509,13 +508,23 @@ std::shared_ptr<IDebugEvent> 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)) {
// 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));
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;
}

// was it a thread create event?
Expand Down Expand Up @@ -545,7 +554,7 @@ std::shared_ptr<IDebugEvent> 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.
*
Expand Down Expand Up @@ -598,7 +607,7 @@ std::shared_ptr<IDebugEvent> 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() {

Expand Down Expand Up @@ -648,8 +657,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<IDebugEvent> DebuggerCore::waitDebugEvent(std::chrono::milliseconds msecs) {

Expand All @@ -670,7 +679,7 @@ std::shared_ptr<IDebugEvent> 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) {
Expand Down Expand Up @@ -710,8 +719,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) {

Expand Down Expand Up @@ -762,7 +771,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() {

Expand Down Expand Up @@ -873,11 +882,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<QByteArray> &args, const QString &input, const QString &output) {

Expand Down Expand Up @@ -1061,8 +1071,8 @@ QMap<edb::pid_t, std::shared_ptr<IProcess>> 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 {

Expand Down Expand Up @@ -1097,7 +1107,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)
Expand All @@ -1117,7 +1127,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)
Expand All @@ -1136,7 +1146,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)
Expand All @@ -1155,7 +1165,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)
Expand All @@ -1174,7 +1184,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();
Expand All @@ -1183,7 +1193,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<qlonglong> &exceptions) {
ignoredExceptions_ = exceptions;
Expand All @@ -1192,7 +1202,7 @@ void DebuggerCore::setIgnoredExceptions(const QList<qlonglong> &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<qlonglong, QString> DebuggerCore::exceptions() const {
return Unix::exceptions();
Expand All @@ -1201,8 +1211,8 @@ QMap<qlonglong, QString> 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);
Expand All @@ -1211,8 +1221,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);
Expand All @@ -1221,7 +1231,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)
Expand Down
Loading