binutils-gdb/gdbserver
Simon Marchi 3ec3145c5d gdb: introduce scoped debug prints
I spent a lot of time reading infrun debug logs recently, and I think
they could be made much more readable by being indented, to clearly see
what operation is done as part of what other operation.  In the current
format, there are no visual cues to tell where things start and end,
it's just a big flat list.  It's also difficult to understand what
caused a given operation (e.g. a call to resume_1) to be done.

To help with this, I propose to add the new scoped_debug_start_end
structure, along with a bunch of macros to make it convenient to use.

The idea of scoped_debug_start_end is simply to print a start and end
message at construction and destruction.  It also increments/decrements
a depth counter in order to make debug statements printed during this
range use some indentation.  Some care is taken to handle the fact that
debug can be turned on or off in the middle of such a range.  For
example, a "set debug foo 1" command in a breakpoint command, or a
superior GDB manually changing the debug_foo variable.

Two macros are added in gdbsupport/common-debug.h, which are helpers to
define module-specific macros:

  - scoped_debug_start_end: takes a message that is printed both at
    construction / destruction, with "start: " and "end: " prefixes.
  - scoped_debug_enter_exit: prints hard-coded "enter" and "exit"
    messages, to denote the entry and exit of a function.

I added some examples in the infrun module to give an idea of how it can
be used and what the result looks like.  The macros are in capital
letters (INFRUN_SCOPED_DEBUG_START_END and
INFRUN_SCOPED_DEBUG_ENTER_EXIT) to mimic the existing SCOPE_EXIT, but
that can be changed if you prefer something else.

Here's an excerpt of the debug
statements printed when doing "continue", where a displaced step is
started:

    [infrun] proceed: enter
      [infrun] proceed: addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT
      [infrun] global_thread_step_over_chain_enqueue: enqueueing thread Thread 0x7ffff75a5640 (LWP 2289301) in global step over chain
      [infrun] start_step_over: enter
        [infrun] start_step_over: stealing global queue of threads to step, length = 1
        [infrun] start_step_over: resuming [Thread 0x7ffff75a5640 (LWP 2289301)] for step-over
        [infrun] resume_1: step=1, signal=GDB_SIGNAL_0, trap_expected=1, current thread [Thread 0x7ffff75a5640 (LWP 2289301)] at 0x5555555551bd
        [displaced] displaced_step_prepare_throw: displaced-stepping Thread 0x7ffff75a5640 (LWP 2289301) now
        [displaced] prepare: selected buffer at 0x5555555550c2
        [displaced] prepare: saved 0x5555555550c2: 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 f0 50
        [displaced] amd64_displaced_step_copy_insn: copy 0x5555555551bd->0x5555555550c2: c7 45 fc 00 00 00 00 eb 13 8b 05 d4 2e 00 00 83
        [displaced] displaced_step_prepare_throw: prepared successfully thread=Thread 0x7ffff75a5640 (LWP 2289301), original_pc=0x5555555551bd, displaced_pc=0x5555555550c2
        [displaced] resume_1: run 0x5555555550c2: c7 45 fc 00
        [infrun] infrun_async: enable=1
        [infrun] prepare_to_wait: prepare_to_wait
        [infrun] start_step_over: [Thread 0x7ffff75a5640 (LWP 2289301)] was resumed.
        [infrun] operator(): step-over queue now empty
      [infrun] start_step_over: exit
      [infrun] proceed: start: resuming threads, all-stop-on-top-of-non-stop
        [infrun] proceed: resuming Thread 0x7ffff7da7740 (LWP 2289296)
        [infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [Thread 0x7ffff7da7740 (LWP 2289296)] at 0x7ffff7f7d9b7
        [infrun] prepare_to_wait: prepare_to_wait
        [infrun] proceed: resuming Thread 0x7ffff7da6640 (LWP 2289300)
        [infrun] resume_1: thread Thread 0x7ffff7da6640 (LWP 2289300) has pending wait status status->kind = stopped, signal = GDB_SIGNAL_TRAP (currently_stepping=0).
        [infrun] prepare_to_wait: prepare_to_wait
        [infrun] proceed: [Thread 0x7ffff75a5640 (LWP 2289301)] resumed
        [infrun] proceed: resuming Thread 0x7ffff6da4640 (LWP 2289302)
        [infrun] resume_1: thread Thread 0x7ffff6da4640 (LWP 2289302) has pending wait status status->kind = stopped, signal = GDB_SIGNAL_TRAP (currently_stepping=0).
        [infrun] prepare_to_wait: prepare_to_wait
      [infrun] proceed: end: resuming threads, all-stop-on-top-of-non-stop
    [infrun] proceed: exit

We can easily see where the call to `proceed` starts and end.  We can
also see why there are a bunch of resume_1 calls, it's because we are
resuming threads, emulating all-stop on top of a non-stop target.

We also see that debug statements nest well with other modules that have
been migrated to use the "new" debug statement helpers (because they all
use debug_prefixed_vprintf in the end.  I think this is desirable, for
example we could see the debug statements about reading the DWARF info
of a library nested under the debug statements about loading that
library.

Of course, modules that haven't been migrated to use the "new" helpers
will still print without indentations.  This will be one good reason to
migrate them.

I think the runtime cost (when debug statements are disabled) of this is
reasonable, given the improvement in readability.  There is the cost of
the conditionals (like standard debug statements), one more condition
(if (m_must_decrement_print_depth)) and the cost of constructing a stack
object, which means copying a fews pointers.

Adding the print in fetch_inferior_event breaks some tests that use "set
debug infrun", because it prints a debug statement after the prompt.  I
adapted these tests to cope with it, by using the "-prompt" switch of
gdb_test_multiple to as if this debug statement is part of the expected
prompt.  It's unfortunate that we have to do this, but I think the debug
print is useful, and I don't want a few tests to get in the way of
adding good debug output.

gdbsupport/ChangeLog:

	* common-debug.h (debug_print_depth): New.
	(struct scoped_debug_start_end): New.
	(scoped_debug_start_end): New.
	(scoped_debug_enter_exit): New.
	* common-debug.cc (debug_prefixed_vprintf): Print indentation.

gdb/ChangeLog:

	* debug.c (debug_print_depth): New.
	* infrun.h (INFRUN_SCOPED_DEBUG_START_END): New.
	(INFRUN_SCOPED_DEBUG_ENTER_EXIT): New.
	* infrun.c (start_step_over): Use
	INFRUN_SCOPED_DEBUG_ENTER_EXIT.
	(proceed): Use INFRUN_SCOPED_DEBUG_ENTER_EXIT and
	INFRUN_SCOPED_DEBUG_START_END.
	(fetch_inferior_event): Use INFRUN_SCOPED_DEBUG_ENTER_EXIT.

gdbserver/ChangeLog:

	* debug.cc (debug_print_depth): New.

gdb/testsuite/ChangeLog:

        * gdb.base/ui-redirect.exp: Expect infrun debug print after
	prompt.
        * gdb.threads/ia64-sigill.exp: Likewise.
        * gdb.threads/watchthreads-reorder.exp: Likewise.

Change-Id: I7c3805e6487807aa63a1bae318876a0c69dce949
2021-01-04 12:00:54 -05:00
..
.dir-locals.el Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
.gitattributes
.gitignore
acinclude.m4 gdbserver: replace AC_TRY_COMPILE in acinclude.m4 2020-10-31 08:31:00 -04:00
aclocal.m4
ax.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
ax.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
ChangeLog gdb: introduce scoped debug prints 2021-01-04 12:00:54 -05:00
config.in gdbserver: re-generate configure 2020-10-24 12:44:19 -04:00
configure gdbserver: replace AC_TRY_COMPILE in acinclude.m4 2020-10-31 08:31:00 -04:00
configure.ac Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
configure.srv gdbserver: Add GNU/Linux support for ARC 2020-10-07 17:46:23 +02:00
debug.cc gdb: introduce scoped debug prints 2021-01-04 12:00:54 -05:00
debug.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
dll.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
dll.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
fork-child.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
gdb_proc_service.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
gdbreplay.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
gdbthread.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
hostio-errno.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
hostio.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
hostio.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
i387-fp.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
i387-fp.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
inferiors.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
inferiors.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-aarch32-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-aarch32-low.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-aarch32-tdesc.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-aarch32-tdesc.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-aarch64-ipa.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-aarch64-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-aarch64-tdesc.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-aarch64-tdesc.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-amd64-ipa.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-arc-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-arm-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-arm-tdesc.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-arm-tdesc.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-i386-ipa.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-ia64-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-low.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-m68k-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-mips-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-nios2-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-ppc-ipa.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-ppc-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-ppc-tdesc-init.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-riscv-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-s390-ipa.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-s390-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-s390-tdesc.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-sh-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-sparc-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-tic6x-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-x86-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-x86-tdesc.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-x86-tdesc.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
linux-xtensa-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
Makefile.in Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
mem-break.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
mem-break.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
netbsd-aarch64-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
netbsd-amd64-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
netbsd-i386-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
netbsd-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
netbsd-low.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
notif.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
notif.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
proc-service.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
proc-service.list Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
README gdbserver: small cleanup of README file 2020-06-12 16:01:35 -04:00
regcache.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
regcache.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
remote-utils.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
remote-utils.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
server.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
server.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
symbol.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
target.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
target.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
tdesc.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
tdesc.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
thread-db.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
tracepoint.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
tracepoint.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
utils.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
utils.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
win32-i386-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
win32-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
win32-low.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
x86-low.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
x86-low.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
x86-tdesc.h Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00
xtensa-xtregs.cc Update copyright year range in all GDB files 2021-01-01 12:12:21 +04:00

		   README for GDBserver & GDBreplay
		    by Stu Grossman and Fred Fish

Introduction:

This is GDBserver, a remote server for Un*x-like systems.  It can be used to
control the execution of a program on a target system from a GDB on a different
host.  GDB and GDBserver communicate using the standard remote serial protocol.
They communicate via either a serial line or a TCP connection.

For more information about GDBserver, see the GDB manual:

    https://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Protocol.html

Usage (server (target) side):

First, you need to have a copy of the program you want to debug put onto
the target system.  The program can be stripped to save space if needed, as
GDBserver doesn't care about symbols.  All symbol handling is taken care of by
the GDB running on the host system.

To use the server, you log on to the target system, and run the `gdbserver'
program.  You must tell it (a) how to communicate with GDB, (b) the name of
your program, and (c) its arguments.  The general syntax is:

	target> gdbserver COMM PROGRAM [ARGS ...]

For example, using a serial port, you might say:

	target> gdbserver /dev/com1 emacs foo.txt

This tells GDBserver to debug emacs with an argument of foo.txt, and to
communicate with GDB via /dev/com1.  GDBserver now waits patiently for the
host GDB to communicate with it.

To use a TCP connection, you could say:

	target> gdbserver host:2345 emacs foo.txt

This says pretty much the same thing as the last example, except that we are
going to communicate with the host GDB via TCP.  The `host:2345' argument means
that we are expecting to see a TCP connection to local TCP port 2345.
(Currently, the `host' part is ignored.)  You can choose any number you want for
the port number as long as it does not conflict with any existing TCP ports on
the target system.  This same port number must be used in the host GDB's
`target remote' command, which will be described shortly. Note that if you chose
a port number that conflicts with another service, GDBserver will print an error
message and exit.

On some targets, GDBserver can also attach to running programs.  This is
accomplished via the --attach argument.  The syntax is:

	target> gdbserver --attach COMM PID

PID is the process ID of a currently running process.  It isn't necessary
to point GDBserver at a binary for the running process.

Usage (host side):

You need an unstripped copy of the target program on your host system, since
GDB needs to examine it's symbol tables and such.  Start up GDB as you normally
would, with the target program as the first argument.  (You may need to use the
--baud option if the serial line is running at anything except 9600 baud.)
Ie: `gdb TARGET-PROG', or `gdb --baud BAUD TARGET-PROG'.  After that, the only
new command you need to know about is `target remote'.  It's argument is either
a device name (usually a serial device, like `/dev/ttyb'), or a HOST:PORT
descriptor.  For example:

	(gdb) target remote /dev/ttyb

communicates with the server via serial line /dev/ttyb, and:

	(gdb) target remote the-target:2345

communicates via a TCP connection to port 2345 on host `the-target', where
you previously started up GDBserver with the same port number.  Note that for
TCP connections, you must start up GDBserver prior to using the `target remote'
command, otherwise you may get an error that looks something like
`Connection refused'.

Building GDBserver:

See the `configure.srv` file for the list of host triplets you can build
GDBserver for.

Building GDBserver for your host is very straightforward.  If you build
GDB natively on a host which GDBserver supports, it will be built
automatically when you build GDB.  You can also build just GDBserver:

	% mkdir obj
	% cd obj
	% path-to-toplevel-sources/configure --disable-gdb
	% make all-gdbserver

(If you have a combined binutils+gdb tree, you may want to also
disable other directories when configuring, e.g., binutils, gas, gold,
gprof, and ld.)

If you prefer to cross-compile to your target, then you can also build
GDBserver that way.  For example:

	% export CC=your-cross-compiler
	% path-to-topevel-sources/configure --disable-gdb
	% make all-gdbserver

Using GDBreplay:

A special hacked down version of GDBserver can be used to replay remote
debug log files created by GDB.  Before using the GDB "target" command to
initiate a remote debug session, use "set remotelogfile <filename>" to tell
GDB that you want to make a recording of the serial or tcp session.  Note
that when replaying the session, GDB communicates with GDBreplay via tcp,
regardless of whether the original session was via a serial link or tcp.

Once you are done with the remote debug session, start GDBreplay and
tell it the name of the log file and the host and port number that GDB
should connect to (typically the same as the host running GDB):

	$ gdbreplay logfile host:port

Then start GDB (preferably in a different screen or window) and use the
"target" command to connect to GDBreplay:

	(gdb) target remote host:port

Repeat the same sequence of user commands to GDB that you gave in the
original debug session.  GDB should not be able to tell that it is talking
to GDBreplay rather than a real target, all other things being equal.  Note
that GDBreplay echos the command lines to stderr, as well as the contents of
the packets it sends and receives.  The last command echoed by GDBreplay is
the next command that needs to be typed to GDB to continue the session in
sync with the original session.