summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/docs/lldb-gdb-remote.txt50
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp36
2 files changed, 86 insertions, 0 deletions
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt
index f9537719c90..5c4a10c82b4 100644
--- a/lldb/docs/lldb-gdb-remote.txt
+++ b/lldb/docs/lldb-gdb-remote.txt
@@ -191,6 +191,24 @@ read packet: OK
This packet must be sent _prior_ to sending a "A" packet.
//----------------------------------------------------------------------
+// QListThreadsInStopReply
+//
+// BRIEF
+// Enable the threads: and thread-pcs: data in the question-mark packet
+// ("T packet") responses when the stub reports that a program has
+// stopped executing.
+//
+// PRIORITY TO IMPLEMENT
+// Performance. This is a performance benefit to lldb if the thread id's
+// and thread pc values are provided to lldb in the T stop packet -- if
+// they are not provided to lldb, lldb will likely need to send one to
+// two packets per thread to fetch the data at every private stop.
+//----------------------------------------------------------------------
+
+send packet: QListThreadsInStopReply
+read packet: OK
+
+//----------------------------------------------------------------------
// "qRegisterInfo<hex-reg-id>"
//
// BRIEF
@@ -201,6 +219,12 @@ This packet must be sent _prior_ to sending a "A" packet.
// This means if new registers are ever added to a remote target, they
// will get picked up automatically, and allows registers to change
// depending on the actual CPU type that is used.
+//
+// NB: As of summer 2015, lldb can get register information from the
+// "qXfer:features:read:target.xml" FSF gdb standard register packet
+// where the stub provides register definitions in an XML file.
+// If qXfer:features:read:target.xml is supported, qRegisterInfo does
+// not need to be implemented.
//----------------------------------------------------------------------
With LLDB, for register information, remote GDB servers can add
@@ -1117,6 +1141,32 @@ for this region.
// if none of the key/value pairs are enough to
// describe why something stopped.
//
+// "threads" comma-sep-base16 A list of thread ids for all threads (including
+// the thread that we're reporting as stopped) that
+// are live in the process right now. lldb may
+// request that this be included in the T packet via
+// the QListThreadsInStopReply packet earlier in
+// the debug session.
+//
+// Example:
+// threads:63387,633b2,63424,63462,63486;
+//
+// "thread-pcs" comma-sep-base16 A list of pc values for all threads that currently
+// exist in the process, including the thread that
+// this T packet is reporting as stopped.
+// This key-value pair will only be emitted when the
+// "threads" key is already included in the T packet.
+// The pc values correspond to the threads reported
+// in the "threads" list. The number of pcs in the
+// "thread-pcs" list will be the same as the number of
+// threads in the "threads" list.
+// lldb may request that this be included in the T
+// packet via the QListThreadsInStopReply packet
+// earlier in the debug session.
+//
+// Example:
+// thread-pcs:dec14,2cf872b0,2cf8681c,2d02d68c,2cf716a8;
+//
// BEST PRACTICES:
// Since register values can be supplied with this packet, it is often useful
// to return the PC, SP, FP, LR (if any), and FLAGS registers so that separate
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 0c2c742f9f3..dadf479ce81 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -2743,6 +2743,7 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
const nub_size_t numthreads = DNBProcessGetNumThreads (pid);
if (numthreads > 0)
{
+ std::vector<uint64_t> pc_values;
ostrm << std::hex << "threads:";
for (nub_size_t i = 0; i < numthreads; ++i)
{
@@ -2750,8 +2751,43 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
if (i > 0)
ostrm << ',';
ostrm << std::hex << th;
+ DNBRegisterValue pc_regval;
+ if (DNBThreadGetRegisterValueByID (pid, th, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_regval))
+ {
+ uint64_t pc = INVALID_NUB_ADDRESS;
+ if (pc_regval.value.uint64 != INVALID_NUB_ADDRESS)
+ {
+ if (pc_regval.info.size == 4)
+ {
+ pc = pc_regval.value.uint32;
+ }
+ else if (pc_regval.info.size == 8)
+ {
+ pc = pc_regval.value.uint64;
+ }
+ if (pc != INVALID_NUB_ADDRESS)
+ {
+ pc_values.push_back (pc);
+ }
+ }
+ }
}
ostrm << ';';
+
+ // If we failed to get any of the thread pc values, the size of our vector will not
+ // be the same as the # of threads. Don't provide any expedited thread pc values in
+ // that case. This should not happen.
+ if (pc_values.size() == numthreads)
+ {
+ ostrm << std::hex << "thread-pcs:";
+ for (nub_size_t i = 0; i < numthreads; ++i)
+ {
+ if (i > 0)
+ ostrm << ',';
+ ostrm << std::hex << pc_values[i];
+ }
+ ostrm << ';';
+ }
}
// Include JSON info that describes the stop reason for any threads
OpenPOWER on IntegriCloud