diff --git a/src/plugins/debugger/gdb/symbian.cpp b/src/plugins/debugger/gdb/symbian.cpp index f7d6b62f2827f9320fa4440f5dddb3aa96959409..4cae2ce81bc522c498b1a55c4ea680f69a5ec625 100644 --- a/src/plugins/debugger/gdb/symbian.cpp +++ b/src/plugins/debugger/gdb/symbian.cpp @@ -418,9 +418,9 @@ static void gdbAppendRegister(QByteArray *ba, uint regno, uint value) ba->append(';'); } -QByteArray Snapshot::gdbStopMessage(uint threadId, bool reportThreadId) const +QByteArray Snapshot::gdbStopMessage(uint threadId, int signalNumber, bool reportThreadId) const { - QByteArray ba = "T05"; + QByteArray ba = ('T' + trk::hexNumber(signalNumber, 2)); if (reportThreadId) { ba += "thread:"; ba += trk::hexNumber(threadId, 3); diff --git a/src/plugins/debugger/gdb/symbian.h b/src/plugins/debugger/gdb/symbian.h index 30012183c5377bd2888f5534c00acad2f978b3e3..ec34462e47a258804df514bf9daef5cc95049c92 100644 --- a/src/plugins/debugger/gdb/symbian.h +++ b/src/plugins/debugger/gdb/symbian.h @@ -73,6 +73,12 @@ struct MemoryRange QDebug operator<<(QDebug d, const MemoryRange &range); +// Signals to be passed to gdb server as stop reason (2 digit hex) +enum GdbServerStopReason { + gdbServerSignalTrap = 5, // Trap/Breakpoint, etc. + gdbServerSignalSegfault = 11 // Segfault +}; + namespace Symbian { enum CodeMode @@ -135,7 +141,7 @@ struct Snapshot QByteArray gdbQsThreadInfo() const; QByteArray gdbQThreadExtraInfo(const QByteArray &cmd) const; // Format a gdb T05 stop message with thread and register set - QByteArray gdbStopMessage(uint threadId, bool reportThreadId) const; + QByteArray gdbStopMessage(uint threadId, int signalNumber, bool reportThreadId) const; // Format a log message for memory access with some smartness about registers QByteArray memoryReadLogMessage(uint addr, uint threadId, bool verbose, const QByteArray &ba) const; // Gdb command parse helpers: 'salnext' diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp index cad69ff297eefbb6ea6c3f52cbf447cbc8f593cd..1169da30f0a1a85c5d35e4ab92b17518811458de 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp @@ -113,6 +113,7 @@ static inline QString startMsg(const trk::Session &session) TcfTrkGdbAdapter::TcfTrkGdbAdapter(GdbEngine *engine) : AbstractGdbAdapter(engine), m_running(false), + m_stopReason(0), m_trkDevice(new TcfTrkDevice(this)), m_gdbAckMode(true), m_uid(0), @@ -325,6 +326,9 @@ void TcfTrkGdbAdapter::tcftrkEvent(const TcfTrkEvent &e) m_snapshot.setThreadState(threadId, reason); // Update registers first, then report stopped m_running = false; + m_stopReason = reason.contains(QLatin1String("exception"), Qt::CaseInsensitive) + || reason.contains(QLatin1String("panic"), Qt::CaseInsensitive) ? + gdbServerSignalSegfault : gdbServerSignalTrap; m_trkDevice->sendRegistersGetMRangeCommand( TcfTrkCallback(this, &TcfTrkGdbAdapter::handleAndReportReadRegistersAfterStop), currentThreadContextId(), 0, @@ -688,7 +692,7 @@ void TcfTrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) } else { //qDebug() << "Fetching single register"; m_trkDevice->sendRegistersGetMRangeCommand( - TcfTrkCallback(this, &TcfTrkGdbAdapter::handleAndReportReadRegistersAfterStop), + TcfTrkCallback(this, &TcfTrkGdbAdapter::handleAndReportReadRegister), currentThreadContextId(), registerNumber, 1); } } @@ -1304,7 +1308,7 @@ void TcfTrkGdbAdapter::handleAndReportReadRegistersAfterStop(const TcfTrkCommand handleReadRegisters(result); handleReadRegisters(result); const bool reportThread = m_session.tid != m_session.mainTid; - sendGdbServerMessage(m_snapshot.gdbStopMessage(m_session.tid, reportThread), stopMessage()); + sendGdbServerMessage(m_snapshot.gdbStopMessage(m_session.tid, m_stopReason, reportThread), stopMessage()); } void TcfTrkGdbAdapter::handleAndReportSetBreakpoint(const TcfTrkCommandResult &result) diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.h b/src/plugins/debugger/gdb/tcftrkgdbadapter.h index ab69c13f256a4d6e73dc3fdea870ff305a47741c..71becf8e248962f581aceba24f5cf9db8ea638a3 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.h +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.h @@ -137,6 +137,7 @@ private: QString m_gdbServerName; // 127.0.0.1:(2222+uid) bool m_running; + int m_stopReason; tcftrk::TcfTrkDevice *m_trkDevice; QSharedPointer<QIODevice> m_trkIODevice; diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 1961ab61cf44f67f78ac4f66a0d74672c6086618..1e32fcb26fd0ab4c91f328db6cdc838ad4aa0b49 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -963,10 +963,12 @@ void TrkGdbAdapter::handleTrkResult(const TrkResult &result) # if 1 // We almost always need register values, so get them // now before informing gdb about the stop.s - //qDebug() << "Auto-fetching registers"; + const int signalNumber = reason.contains(QLatin1String("exception"), Qt::CaseInsensitive) + || reason.contains(QLatin1String("panic"), Qt::CaseInsensitive) ? + gdbServerSignalSegfault : gdbServerSignalTrap; sendTrkMessage(0x12, TrkCB(handleAndReportReadRegistersAfterStop), - Launcher::readRegistersMessage(m_session.pid, m_session.tid)); + Launcher::readRegistersMessage(m_session.pid, m_session.tid), signalNumber); # else // As a source-line step typically consists of // several instruction steps, better avoid the multiple @@ -1181,7 +1183,8 @@ void TrkGdbAdapter::handleAndReportReadRegistersAfterStop(const TrkResult &resul { handleReadRegisters(result); const bool reportThread = m_session.tid != m_session.mainTid; - sendGdbServerMessage(m_snapshot.gdbStopMessage(m_session.tid, reportThread), + const int signalNumber = result.cookie.isValid() ? result.cookie.toInt() : int(gdbServerSignalTrap); + sendGdbServerMessage(m_snapshot.gdbStopMessage(m_session.tid, signalNumber, reportThread), "Stopped with registers in thread " + QByteArray::number(m_session.tid, 16)); }