[PATCH v3 0/7] Per-inferior/Inferior-qualified thread IDs

Pedro Alves
2016-01-06T13:03:42Z

v3:
- now split in a 7 patches series
- thread id parsing simplified someewhat and split to separate file
- test Breakpoint.thread with global thread ID
- minor cleanups throughout

v2:
- thread id range parsing implemented

v1:
- initial draft

I've pushed this to the users/palves/thread-ids-per-inferior branch.

~~~~~~~~~~~~~~~~~~~~~~~~

Currently, if you're debugging multiple inferiors, because all threads
of all inferiors share the same global number space, things get quite
confusing. For example, with:

(gdb) info inferiors
Num Description Executable
1 process 6022 /home/pedro/gdb/tests/threads
* 2 process 6037 /home/pedro/gdb/tests/threads
(gdb)
1 Thread 0x7ffff7fc2740 (LWP 6022) "threads" (running)
3 Thread 0x7ffff77c0700 (LWP 6028) "threads" (running)
7 Thread 0x7ffff7fc2740 (LWP 6032) "threads" (running)
11 Thread 0x7ffff7fc1700 (LWP 6037) "threads" (running)
12 Thread 0x7ffff77c0700 (LWP 6038) "threads" (running)
* 13 Thread 0x7ffff7fc2740 (LWP 6039) "threads" (running)
(gdb)

... there's no way to tell which threads in that list belong to each
process.

This series changes GDB to track thread numbers per-inferior. Then,
if you're debugging multiple inferiors, GDB displays
"inferior-num.thread-num" instead of just "thread-num" whenever it
needs to display a thread ID. The result is this:

(gdb) info inferiors
Num Description Executable
1 process 8155 /home/pedro/gdb/tests/threads
* 2 process 8156 /home/pedro/gdb/tests/threads
(gdb) info threads
Id Target Id Frame
1.1 Thread 0x7ffff7fc2740 (LWP 8155) "threads" (running)
1.2 Thread 0x7ffff7fc1700 (LWP 8168) "threads" (running)
1.3 Thread 0x7ffff77c0700 (LWP 8172) "threads" (running)
2.1 Thread 0x7ffff7fc2740 (LWP 8156) "threads" (running)
* 3.1 Thread 0x7ffff7fc2740 (LWP 8157) "threads" (running)
3.2 Thread 0x7ffff7fc1700 (LWP 8165) "threads" (running)
3.3 Thread 0x7ffff77c0700 (LWP 8171) "threads" (running)
(gdb)

And:

(gdb) thread 1.1
[Switching to thread 1.1 (Thread 0x7ffff7fc2740 (LWP 8155))](running)
(gdb)

etc.

You can still use "thread NUM" -- in that case GDB infers you're
referring to thread NUM of the current inferior.

This raises the question of what to do with MI thread IDs. At least
Eclipse assumes that MI thread IDs are integers rather than text, so
we can't just simply start reporting "1.2" etc. as MI thread IDs.

To address this, we keep giving threads a global identifier, _in
addition_ to the per-inferior number, and make MI always refer to the
global thread IDs.

A similar problem exists with Python and Guile's API, and also with
the $_thread convenience variable. Instead of leaving the APIs and
CLI stuck with a confusing detail forever, we rebind $_thread and
Python's InferiorThread.num to the new per-inferior thread number.
It's a backward compatibility break that only matters when debugging
multiple inferiors, so I think worth doing.

Likewise, Python's Breakpoint.thread attribute and Guile's
breakpoint-thread/set-breakpoint-thread breakpoint methods need to
work with a single integer, so they are left referring to global
thread ids.

With all this in mind, this series:

- adds a new $_inferior convenience variable, that is like $_thread,
but holds the current inferior number.

- makes $_thread refer to the per-inferior thread number.

- adds a new $_gthread convenience variable, that is like $_thread,
but holds the current thread's global thread id.

- adds a new InferiorThread.inferior attribute, so a script can
easily get at the thread's inferior number.

- adds a new Python InferiorThread.global_num attribute. This can be
used to pass the correct thread ID to Breakpoint.thread.

- makes global thread IDs visible with "info thread -gid":

(gdb) info threads -gid
Id GId Target Id Frame
1.1 1 Thread 0x7ffff7fc1740 (LWP 15190) "threads" (running)
1.2 3 Thread 0x7ffff7fc0700 (LWP 15249) "threads" (running)
1.3 4 Thread 0x7ffff77bf700 (LWP 15251) "threads" (running)
2.1 2 Thread 0x7ffff7fc1740 (LWP 15194) "threads" (running)
2.2 5 Thread 0x7ffff7fc0700 (LWP 15250) "threads" (running)
* 2.3 6 Thread 0x7ffff77bf700 (LWP 15252) "threads" (running)
(gdb)

To avoid potencially confusing users (which sneakily also avoids
updating the testsuite!), if there's only one inferior and its ID is
"1", IOW, the user hasn't done anything multi-process/inferior
related, then the "INF." part of thread IDs is not shown. E.g,.:

(gdb) info inferiors
Num Description Executable
* 1 process 15275 /home/pedro/gdb/tests/threads
(gdb) info threads
Id Target Id Frame
* 1 Thread 0x7ffff7fc1740 (LWP 15275) "threads" main () at threads.c:40
(gdb) add-inferior
Added inferior 2
(gdb) info threads
Id Target Id Frame
* 1.1 Thread 0x7ffff7fc1740 (LWP 15275) "threads" main () at threads.c:40
(gdb)

No regressions on x86_64 Fedora 20.

Pedro Alves (7):
Add a new $_inferior convenience variable
Add Python InferiorThread.inferior attribute
Centralize thread ID printing
Per-inferior/Inferior-qualified thread IDs
InferiorThread.global_num
Implement "info threads -gid"
Add $_gthread convenience variable

gdb/Makefile.in | 7 +-
gdb/NEWS | 49 +++
gdb/ada-tasks.c | 2 +-
gdb/breakpoint.c | 69 ++--
gdb/btrace.c | 15 +-
gdb/cli/cli-utils.c | 11 +-
gdb/cli/cli-utils.h | 15 +-
gdb/common/print-utils.c | 71 +++--
gdb/common/print-utils.h | 8 +
gdb/doc/gdb.texinfo | 242 +++++++++-----
gdb/doc/guile.texi | 11 +-
gdb/doc/python.texi | 20 +-
gdb/dummy-frame.c | 2 +-
gdb/elfread.c | 2 +-
gdb/gdbthread.h | 96 +++++-
gdb/guile/scm-breakpoint.c | 8 +-
gdb/infcmd.c | 24 +-
gdb/inferior.c | 25 +-
gdb/inferior.h | 3 +
gdb/infrun.c | 8 +-
gdb/mi/mi-cmd-var.c | 2 +-
gdb/mi/mi-interp.c | 16 +-
gdb/mi/mi-main.c | 6 +-
gdb/python/py-breakpoint.c | 2 +-
gdb/python/py-finishbreakpoint.c | 2 +-
gdb/python/py-infthread.c | 35 +-
gdb/record-btrace.c | 16 +-
gdb/remote.c | 4 +-
gdb/target.c | 2 +
gdb/testsuite/gdb.base/break.exp | 2 +-
gdb/testsuite/gdb.base/default.exp | 2 +
gdb/testsuite/gdb.base/hbreak2.exp | 2 +-
gdb/testsuite/gdb.base/sepdebug.exp | 2 +-
gdb/testsuite/gdb.base/watch_thread_num.exp | 2 +-
gdb/testsuite/gdb.linespec/keywords.exp | 8 +-
gdb/testsuite/gdb.multi/base.exp | 4 +
gdb/testsuite/gdb.multi/info-threads.exp | 2 +-
gdb/testsuite/gdb.multi/tids.c | 52 +++
gdb/testsuite/gdb.multi/tids.exp | 322 +++++++++++++++++++
gdb/testsuite/gdb.python/py-infthread.exp | 4 +
gdb/testsuite/gdb.threads/thread-find.exp | 4 +-
gdb/testsuite/gdb.threads/thread-specific.exp | 5 +
gdb/thread.c | 438 ++++++++++++++++++--------
gdb/tid-parse.c | 267 ++++++++++++++++
gdb/tid-parse.h | 148 +++++++++
gdb/varobj.c | 9 +-
46 files changed, 1657 insertions(+), 389 deletions(-)
create mode 100644 gdb/testsuite/gdb.multi/tids.c
create mode 100644 gdb/testsuite/gdb.multi/tids.exp
create mode 100644 gdb/tid-parse.c
create mode 100644 gdb/tid-parse.h

--
1.9.3