Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions pyocd/gdbserver/gdbserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ def escape(data):
result.append(c)
return bytes(result)

def _parse_thread_id(value: bytes) -> int:
# Older GDB versions can send 32-bit thread IDs with bit 31 set as negative
# hexadecimal numbers. Recover the original unsigned ID so RTOS thread
# lookups succeed, while preserving the special selectors 0 and -1.
thread_id = int(value, 16)
if thread_id < -1:
thread_id += 0x100000000
return thread_id

class GDBClientSession(threading.Thread):
"""@brief GDB client session thread.

Expand Down Expand Up @@ -1010,7 +1019,7 @@ def breakpoint(self, client, data):

def set_thread(self, client, data):
op = data[0:1]
thread_id = int(data[1:-3], 16)
thread_id = _parse_thread_id(data[1:-3])
LOG.debug("Command: Set thread (threadId=%s, operation=%s)",
("0x%08x" % thread_id) if thread_id >= 0 else str(thread_id), to_str_safe(op))

Expand Down Expand Up @@ -1042,7 +1051,7 @@ def set_thread(self, client, data):
return self.create_rsp_packet(b'OK')

def is_thread_alive(self, client, data):
threadId = int(data[1:-3], 16)
threadId = _parse_thread_id(data[1:-3])

if self.is_threading_enabled():
isAlive = self.thread_provider.is_valid_thread_id(threadId)
Expand Down Expand Up @@ -1304,7 +1313,7 @@ def v_cont(self, client, cmd):
args = op.split(b':')
action = args[0]
if len(args) > 1:
thread_id = int(args[1], 16)
thread_id = _parse_thread_id(args[1])
if thread_id == -1 or thread_id == 0:
thread_id = currentThread
thread_actions[thread_id] = action
Expand Down
Loading