Commit Graph

335 Commits

Author SHA1 Message Date
Enze Li
cf6c1e710e gdbserver: remove unused variable
When building with clang 15, I got this error:

  CXX    server.o
server.cc:2985:10: error: variable 'new_argc' set but not used [-Werror,-Wunused-but-set-variable]
  int i, new_argc;
             ^
Remove the unused variable to eliminate the error.

Tested by rebuilding on x86_64-linux with clang 15.
2022-07-13 20:10:18 +08:00
Tiezhu Yang
3f6227c2f4 gdbserver: LoongArch: Add floating-point support
This commit adds floating-point support for LoongArch gdbserver.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-07-12 20:14:52 +08:00
Youling Tang
74baa6cd1c gdbserver: LoongArch: Add orig_a0 processing
Commit 736918239b ("gdb: LoongArch: add orig_a0 into register set")
introduced orig_a0, similar processing needs to be done in gdbserver.

At the same time, add orig_a0 related comments.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-07-10 17:27:55 +08:00
Youling Tang
3eba483364 gdbserver: LoongArch: Simplify code with register number macros
Move "enum loongarch_regnum" to gdb/arch/loongarch.h so that the
macro definitions can be used in gdbserver/linux-loongarch-low.cc
to simplify the code.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-07-10 17:27:50 +08:00
Pedro Alves
7e8621cf6d Fix GDBserver regression due to change to avoid reading shell registers
Simon reported that the recent change to make GDB and GDBserver avoid
reading shell registers caused a GDBserver regression, caught with
ASan while running gdb.server/non-existing-program.exp:

 $ /home/smarchi/build/binutils-gdb/gdb/testsuite/../../gdb/../gdbserver/gdbserver stdio non-existing-program
 =================================================================
 ==127719==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f0000000e9 at pc 0x55bcbfa301f4 bp 0x7ffd238a7320 sp 0x7ffd238a7310
 WRITE of size 1 at 0x60f0000000e9 thread T0
     #0 0x55bcbfa301f3 in scoped_restore_tmpl<bool>::~scoped_restore_tmpl() /home/smarchi/src/binutils-gdb/gdbserver/../gdbsupport/scoped_restore.h:86
     #1 0x55bcbfa2ffe9 in post_fork_inferior(int, char const*) /home/smarchi/src/binutils-gdb/gdbserver/fork-child.cc:120
     #2 0x55bcbf9c9199 in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:991
     #3 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941
     #4 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084
     #5 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
     #6 0x55bcbf8ef2bd in _start (/home/smarchi/build/binutils-gdb/gdbserver/gdbserver+0x1352bd)

 0x60f0000000e9 is located 169 bytes inside of 176-byte region [0x60f000000040,0x60f0000000f0)
 freed by thread T0 here:
     #0 0x7ff9d6c6f0c7 in operator delete(void*) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:160
     #1 0x55bcbf910d00 in remove_process(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/inferiors.cc:164
     #2 0x55bcbf9c4ac7 in linux_process_target::remove_linux_process(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:454
     #3 0x55bcbf9cdaa6 in linux_process_target::mourn(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:1599
     #4 0x55bcbf988dc4 in target_mourn_inferior(ptid_t) /home/smarchi/src/binutils-gdb/gdbserver/target.cc:205
     #5 0x55bcbfa32020 in startup_inferior(process_stratum_target*, int, int, target_waitstatus*, ptid_t*) /home/smarchi/src/binutils-gdb/gdbserver/../gdb/nat/fork-inferior.c:515
     #6 0x55bcbfa2fdeb in post_fork_inferior(int, char const*) /home/smarchi/src/binutils-gdb/gdbserver/fork-child.cc:111
     #7 0x55bcbf9c9199 in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:991
     #8 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941
     #9 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084
     #10 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)

 previously allocated by thread T0 here:
     #0 0x7ff9d6c6e5a7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
     #1 0x55bcbf910ad0 in add_process(int, int) /home/smarchi/src/binutils-gdb/gdbserver/inferiors.cc:144
     #2 0x55bcbf9c477d in linux_process_target::add_linux_process_no_mem_file(int, int) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:425
     #3 0x55bcbf9c8f4c in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:985
     #4 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941
     #5 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084
     #6 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)

Above we see that in the non-existing-program case, the process gets
deleted before the starting_up flag gets restored to false.

This happens because startup_inferior calls target_mourn_inferior
before throwing an error, and in GDBserver, unlike in GDB, mourning
deletes the process.

Fix this by not using a scoped_restore to manage the starting_up flag,
since we should only clear it when startup_inferior doesn't throw.

Change-Id: I67325d6f81c64de4e89e20e4ec4556f57eac7f6c
2022-06-29 19:32:07 +01:00
Pedro Alves
a9deee17d3 gdb+gdbserver/Linux: avoid reading registers while going through shell
For every stop, Linux GDB and GDBserver save the stopped thread's PC,
in lwp->stop_pc.  This is done in save_stop_reason, in both
gdb/linux-nat.c and gdbserver/linux-low.cc.  However, while we're
going through the shell after "run", in startup_inferior, we shouldn't
be reading registers, as we haven't yet determined the target's
architecture -- the shell's architecture may not even be the same as
the final inferior's.

In gdb/linux-nat.c, lwp->stop_pc is only needed when the thread has
stopped for a breakpoint, and since when going through the shell, no
breakpoint is going to hit, we could simply teach save_stop_reason to
only record the stop pc when the thread stopped for a breakpoint.

However, in gdbserver/linux-low.cc, lwp->stop_pc is used in more cases
than breakpoint hits (e.g., it's used in tracepoints & the
"while-stepping" feature).

So to avoid GDB vs GDBserver divergence, we apply the same approach to
both implementations.

We set a flag in the inferior (process in GDBserver) whenever it is
being nursed through the shell, and when that flag is set,
save_stop_reason bails out early.  While going through the shell,
we'll only ever get process exits (normal or signalled), random
signals, and exec events, so nothing is lost.

Change-Id: If0f01831514d3a74d17efd102875de7d2c6401ad
2022-06-28 18:11:29 +01:00
Pedro Alves
171fba11ab Make GDBserver abort on internal error in development mode
Currently, if GDBserver hits some internal assertion, it exits with
error status, instead of aborting.  This makes it harder to debug
GDBserver, as you can't just debug a core file if GDBserver fails an
assertion.  I've had to hack the code to make GDBserver abort to debug
something several times before.

I believe the reason it exits instead of aborting, is to prevent
potentially littering the filesystem of smaller embedded targets with
core files.  I think I recall Daniel Jacobowitz once saying that many
years ago, but I can't be sure.  Anyhow, that seems reasonable to me.

Since we nowadays have a distinction between development and release
modes, I propose to make GDBserver abort on internal error if in
development mode, while keeping the status quo when in release mode.

Thus, after this patch, in development mode, you get:

 $ ../gdbserver/gdbserver
 ../../src/gdbserver/server.cc:3711: A problem internal to GDBserver has been detected.
 captured_main: Assertion `0' failed.
 Aborted (core dumped)
 $

while in release mode, you'll continue to get:

 $ ../gdbserver/gdbserver
 ../../src/gdbserver/server.cc:3711: A problem internal to GDBserver has been detected.
 captured_main: Assertion `0' failed.
 $ echo $?
 1

I do not think that this requires a separate configure switch.

A "--target_board=native-extended-gdbserver" run on Ubuntu 20.04 ends
up with:

		 === gdb Summary ===

 # of unexpected core files      29
 ...

for me, of which 8 are GDBserver core dumps, 7 more than without this
patch.

Change-Id: I6861e08ad71f65a0332c91ec95ca001d130b0e9d
2022-06-27 13:55:36 +01:00
Youling Tang
e5ab6af52d gdbserver: Add LoongArch/Linux support
Implement LoongArch/Linux support, including XML target description
handling based on features determined, GPR regset support, and software
breakpoint handling.

In the Linux kernel code of LoongArch, ptrace implements PTRACE_POKEUSR
and PTRACE_PEEKUSR in the arch_ptrace function, so srv_linux_usrregs is
set to yes.

With this patch on LoongArch:

  $ make check-gdb TESTS="gdb.server/server-connect.exp"
  [...]
  # of expected passes		18
  [...]

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-06-14 22:21:43 +08:00
Tom Tromey
20489cca90 Use subclasses of windows_process_info
This changes windows_process_info to use virtual methods for its
callbacks, and then changes the two clients of this code to subclass
this class to implement the methods.

I considered using CRTP here, but that would require making the new
structures visible to the compilation of of nat/windows-nat.c.  This
seemed like a bit of a pain, so I didn't do it.

This change then lets us change all the per-inferior globals to be
members of the new subclass.  Note that there can still only be a
single inferior -- currently there's a single global of the new type.
This is just another step toward possibly implementing multi-inferior
for Windows.

It's possible this could be cleaned up further... ideally I'd like to
move more of the data into the base class.  However, because gdb
supports Cygwin and gdbserver does not, and because I don't have a way
to build or test Cygwin, larger refactorings are difficult.
2022-06-07 11:44:53 -06:00
Tom Tromey
bcb9251f02 Allow ASLR to be disabled on Windows
On Windows, it is possible to disable ASLR when creating a process.
This patch adds code to do this, and hooks it up to gdb's existing
disable-randomization feature.  Because the Windows documentation
cautions that this isn't available on all versions of Windows, the
CreateProcess wrapper function is updated to make the attempt, and
then fall back to the current approach if it fails.
2022-06-07 09:59:41 -06:00
Tom Tromey
8fea1a81c7 Introduce wrapper for CreateProcess
This is a small refactoring that introduces a wrapper for the Windows
CreateProcess function.  This is done to make the next patch a bit
simpler.
2022-06-07 09:59:40 -06:00
John Baldwin
0ee6b1c511 Use aarch64_features to describe register features in target descriptions.
Replace the sve bool member of aarch64_features with a vq member that
holds the vector quotient.  It is zero if SVE is not present.

Add std::hash<> specialization and operator== so that aarch64_features
can be used as a key with std::unordered_map<>.

Change the various functions that create or lookup aarch64 target
descriptions to accept a const aarch64_features object rather than a
growing number of arguments.

Replace the multi-dimension tdesc_aarch64_list arrays used to cache
target descriptions with unordered_maps indexed by aarch64_feature.
2022-05-18 13:32:04 -07:00
Tom Tromey
fcab58390f Implement pid_to_exec_file for Windows in gdbserver
I noticed that gdbserver did not implement pid_to_exec_file for
Windows, while gdb did implement it.  This patch moves the code to
nat/windows-nat.c, so that it can be shared.  This makes the gdbserver
implementation trivial.
2022-05-13 08:21:16 -06:00
Tom Tromey
4eab18b566 Remove windows_process_info::id
I noticed that windows_process_info::id is only used by gdbserver, and
not really necessary.  This patch removes it.
2022-05-13 08:21:16 -06:00
Luis Machado
d8a7353308 Fix build failure for aarch64 gdbserver
We're missing an argument.
2022-05-04 15:36:47 +01:00
Pedro Alves
5890af36e5 Fix GDBserver Aarch64 Linux regression
Luis noticed that the recent changes to gdbserver to make it track
process and threads independently regressed a few gdb.multi/*.exp
tests for aarch64-linux.

We started seeing the following internal error for
gdb.multi/multi-target-continue.exp for example:

 Starting program: binutils-gdb/gdb/testsuite/outputs/gdb.multi/multi-target-continue/multi-target-continue ^M
 Error in re-setting breakpoint 2: Remote connection closed^M
 ../../../repos/binutils-gdb/gdb/thread.c:85: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed.^M
 A problem internal to GDB has been detected,^M
 further debugging may prove unreliable.

A backtrace looks like:

 #0  thread_regcache_data (thread=thread@entry=0x0) at ../../../repos/binutils-gdb/gdbserver/inferiors.cc:120
 #1  0x0000aaaaaaabf0e8 in get_thread_regcache (thread=0x0, fetch=fetch@entry=0) at ../../../repos/binutils-gdb/gdbserver/regcache.cc:31
 #2  0x0000aaaaaaad785c in is_64bit_tdesc () at ../../../repos/binutils-gdb/gdbserver/linux-aarch64-low.cc:194
 #3  0x0000aaaaaaad8a48 in aarch64_target::sw_breakpoint_from_kind (this=<optimized out>, kind=4, size=0xffffffffef04) at ../../../repos/binutils-gdb/gdbserver/linux-aarch64-low.cc:3226
 #4  0x0000aaaaaaabe220 in bp_size (bp=0xaaaaaab6f3d0) at ../../../repos/binutils-gdb/gdbserver/mem-break.cc:226
 #5  check_mem_read (mem_addr=187649984471104, buf=buf@entry=0xaaaaaab625d0 "\006", mem_len=mem_len@entry=56) at ../../../repos/binutils-gdb/gdbserver/mem-break.cc:1862
 #6  0x0000aaaaaaacc660 in read_inferior_memory (memaddr=<optimized out>, myaddr=0xaaaaaab625d0 "\006", len=56) at ../../../repos/binutils-gdb/gdbserver/target.cc:93
 #7  0x0000aaaaaaac3d9c in gdb_read_memory (len=56, myaddr=0xaaaaaab625d0 "\006", memaddr=187649984471104) at ../../../repos/binutils-gdb/gdbserver/server.cc:1071
 #8  gdb_read_memory (memaddr=187649984471104, myaddr=0xaaaaaab625d0 "\006", len=56) at ../../../repos/binutils-gdb/gdbserver/server.cc:1048
 #9  0x0000aaaaaaac82a4 in process_serial_event () at ../../../repos/binutils-gdb/gdbserver/server.cc:4307
 #10 handle_serial_event (err=<optimized out>, client_data=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:4520
 #11 0x0000aaaaaaafbcd0 in gdb_wait_for_event (block=block@entry=1) at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:700
 #12 0x0000aaaaaaafc0b0 in gdb_wait_for_event (block=1) at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:596
 #13 gdb_do_one_event () at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:237
 #14 0x0000aaaaaaacacb0 in start_event_loop () at ../../../repos/binutils-gdb/gdbserver/server.cc:3518
 #15 captured_main (argc=4, argv=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:3998
 #16 0x0000aaaaaaab66dc in main (argc=<optimized out>, argv=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:4084

This sequence of functions is invoked due to a series of conditions:

 1 - The probe-based breakpoint mechanism failed (for some reason) so ...

 2 - ... gdbserver has to know what type of architecture it is dealing
     with so it can pick the right breakpoint kind, so it wants to
     check if we have a 64-bit target.

 3 - To determine the size of a register, we currently fetch the
     current thread's register cache, and the current thread pointer
     is now nullptr.

In #3, the current thread is nullptr because gdb_read_memory clears it
on purpose, via set_desired_process, exactly to expose code relying on
the current thread when it shouldn't.  It was always possible to end
up in this situation (when the current thread exits), but it was
harder to reproduce before.

This commit fixes it by tweaking is_64bit_tdesc to look at the current
process's tdesc instead of the current thread's tdesc.

Note that the thread's tdesc is itself filled from the process's
tdesc, so this should be equivalent:

 struct regcache *
 get_thread_regcache (struct thread_info *thread, int fetch)
 {
   struct regcache *regcache;

   regcache = thread_regcache_data (thread);

 ...
   if (regcache == NULL)
     {
       struct process_info *proc = get_thread_process (thread);

       gdb_assert (proc->tdesc != NULL);

       regcache = new_register_cache (proc->tdesc);
       set_thread_regcache_data (thread, regcache);
     }
 ...

Change-Id: Ibc809d7345e70a2f058b522bdc5cdbdca97e2cdc
2022-05-04 14:42:58 +01:00
John Baldwin
24ef0d41ac gdbserver: Fix build after adding tls feature to arm tdesc. 2022-05-03 21:38:12 -07:00
John Baldwin
9c27bc99e4 gdbserver: Read the tpidr register from NT_ARM_TLS on Linux. 2022-05-03 16:05:10 -07:00
John Baldwin
414d5848bb Add an aarch64-tls feature which includes the tpidr register. 2022-05-03 16:05:10 -07:00
Pedro Alves
7f8acedeeb gdbserver: track current process as well as current thread
The recent commit 421490af33 ("gdbserver/linux: Access memory even
if threads are running") caused a regression in
gdb.threads/access-mem-running-thread-exit.exp with gdbserver, which I
somehow missed.  Like so:

 (gdb) print global_var
 Cannot access memory at address 0x555555558010
 (gdb) FAIL: gdb.threads/access-mem-running-thread-exit.exp: non-stop: access mem (print global_var after writing, inf=2, iter=1)

The problem starts with GDB telling GDBserver to select a thread, via
the Hg packet, which GDBserver complies with, then that thread exits,
and GDB, without knowing the thread is gone, tries to write to memory,
through the context of the previously selected Hg thread.

GDBserver's GDB-facing memory access routines, gdb_read_memory and
gdb_write_memory, call set_desired_thread to make GDBserver re-select
the thread that GDB has selected with the Hg packet.  Since the thread
is gone, set_desired_thread returns false, and the memory access
fails.

Now, to access memory, it doesn't really matter which thread is
selected.  All we should need is the target process.  Even if the
thread that GDB previously selected is gone, and GDB does not yet know
about that exit, it shouldn't matter, GDBserver should still know
which process that thread belonged to.

Fix this by making GDBserver track the current process separately,
like GDB also does.  Add a new set_desired_process routine that is
similar to set_desired_thread, but just sets the current process,
leaving the current thread as NULL.  Use it in the GDB-facing memory
read and write routines, to avoid failing if the selected thread is
gone, but the process is still around.

Change-Id: I4ff97cb6f42558efbed224b30d5c71f6112d44cd
2022-05-03 15:10:22 +01:00
Tom Tromey
fc0b8a976d Fix libinproctrace.so build on PPC
The recent gnulib import caused a build failure of libinproctrace.so
on PPC:

    alloc.c:(.text+0x20): undefined reference to `rpl_malloc'
    alloc.c:(.text+0x70): undefined reference to `rpl_realloc'

This patch fixes the problem using the same workaround that was
previously used for free.
2022-04-28 12:47:11 -06:00
Tom Tromey
801eb70f9a Fix gdbserver build for x86-64 Windows
I broke the gdbserver build on x86-64 Windows a little while back.
Previously, I could not build this configuration, but today I found
out that if I configure with:

    --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32

using the Fedora 34 tools, it will in fact build.  I'm not certain,
but maybe the gnulib update helped with this.

This patch fixes the build.  I'm checking it in.
2022-04-27 10:45:10 -06:00
Simon Marchi
f551c8ef32 gdbserver/linux: free process_info_private and arch_process_info when failing to attach
Running

  $ ../gdbserver/gdbserver --once --attach :1234 539436

with ASan while /proc/sys/kernel/yama/ptrace_scope is set to 1 (prevents
attaching) shows that we fail to free some platform-specific objects
tied to the process_info (process_info_private and arch_process_info):

    Direct leak of 32 byte(s) in 1 object(s) allocated from:
        #0 0x7f6b558b3fb9 in __interceptor_calloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x562eaf15d04a in xcalloc /home/simark/src/binutils-gdb/gdbserver/../gdb/alloc.c:100
        #2 0x562eaf251548 in xcnew<process_info_private> /home/simark/src/binutils-gdb/gdbserver/../gdbsupport/poison.h:122
        #3 0x562eaf22810c in linux_process_target::add_linux_process_no_mem_file(int, int) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:426
        #4 0x562eaf22d33f in linux_process_target::attach(unsigned long) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:1132
        #5 0x562eaf1a7222 in attach_inferior /home/simark/src/binutils-gdb/gdbserver/server.cc:308
        #6 0x562eaf1c1016 in captured_main /home/simark/src/binutils-gdb/gdbserver/server.cc:3949
        #7 0x562eaf1c1d60 in main /home/simark/src/binutils-gdb/gdbserver/server.cc:4084
        #8 0x7f6b552f630f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)

    Indirect leak of 56 byte(s) in 1 object(s) allocated from:
        #0 0x7f6b558b3fb9 in __interceptor_calloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x562eaf15d04a in xcalloc /home/simark/src/binutils-gdb/gdbserver/../gdb/alloc.c:100
        #2 0x562eaf2a0d79 in xcnew<arch_process_info> /home/simark/src/binutils-gdb/gdbserver/../gdbsupport/poison.h:122
        #3 0x562eaf295e2c in x86_target::low_new_process() /home/simark/src/binutils-gdb/gdbserver/linux-x86-low.cc:723
        #4 0x562eaf22819b in linux_process_target::add_linux_process_no_mem_file(int, int) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:428
        #5 0x562eaf22d33f in linux_process_target::attach(unsigned long) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:1132
        #6 0x562eaf1a7222 in attach_inferior /home/simark/src/binutils-gdb/gdbserver/server.cc:308
        #7 0x562eaf1c1016 in captured_main /home/simark/src/binutils-gdb/gdbserver/server.cc:3949
        #8 0x562eaf1c1d60 in main /home/simark/src/binutils-gdb/gdbserver/server.cc:4084
        #9 0x7f6b552f630f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)

Those objects are deleted by linux_process_target::mourn, but that is
not called if we fail to attach, we only call remove_process.  I
initially fixed this by making linux_process_target::attach call
linux_process_target::mourn on failure (before calling error).  But this
isn't done anywhere else (including in GDB) so it would just be
confusing to do things differently here.

Instead, add a linux_process_target::remove_linux_process helper method
(which calls remove_process), and call that instead of remove_process in
the Linux target.  Move the free-ing of the extra data from the mourn
method to that new method.

Change-Id: I277059a69d5f08087a7f3ef0b8f1792a1fcf7a85
2022-04-22 14:04:36 -04:00
Simon Marchi
7ab2607f97 gdbsupport: make gdb_abspath return an std::string
I'm trying to switch these functions to use std::string instead of char
arrays, as much as possible.  Some callers benefit from it (can avoid
doing a copy of the result), while others suffer (have to make one more
copy).

Change-Id: Iced49b8ee2f189744c5072a3b217aab5af17a993
2022-04-18 15:48:03 -04:00
Pedro Alves
8e347faf8f gdbserver: Eliminate prepare_to_access_memory
Given:

 - The prepare_to_access_memory machinery was added for non-stop mode.

 - Only Linux supports non-stop.

 - Linux no longer needs the prepare_to_access_memory machinery.  In
   fact, after the previous patch,
   linux_process_target::prepare_to_access_memory became a nop.

Thus, prepare_to_access_memory can go away, simplifying core GDBserver
code.

Change-Id: I93ac8bfe66bd61c3d1c4a0e7d419335163120ecf
2022-04-14 20:22:56 +01:00
Pedro Alves
421490af33 gdbserver/linux: Access memory even if threads are running
Similarly to how the native Linux target was changed
and subsequently reworked in these commits:

 05c06f318f Linux: Access memory even if threads are running
 8a89ddbda2 Avoid /proc/pid/mem races (PR 28065)

... teach GDBserver to access memory even when the current thread is
running, by always accessing memory via /proc/PID/mem.

The existing comment:

  /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
     running LWP.  */

... is incorrect for /proc/PID/mem does allow that.

Actually, from GDB's perspective, GDBserver could already access
memory while threads were running, but at the expense of pausing all
threads for the duration of the memory access, via
prepare_to_access_memory.  This new implementation does not require
pausing any thread, thus
linux_process_target::prepare_to_access_memory /
linux_process_target::done_accessing_memory become nops.  A subsequent
patch will remove the whole prepare_to_access_memory infrastructure
completely.

The GDBserver linux-low.cc implementation is simpler than GDB's
linux-nat.c's, because GDBserver always adds the unfollowed vfork/fork
children to the process list immediately when the fork/vfork event is
seen out of ptrace.  I.e., there's no need to keep the file descriptor
stored on a side map, we can store it directly in the process
structure.

Change-Id: I0abfd782ceaa4ddce8d3e5f3e2dfc5928862ef61
2022-04-14 20:22:56 +01:00
Pedro Alves
366e3746c5 gdbserver: special case target_write_memory len==0
The next patch in this series adds a common helper routine for both
memory reads and writes, like this:

 static int
 proc_xfer_memory (CORE_ADDR memaddr, unsigned char *readbuf,
		  const gdb_byte *writebuf, int len)
 {
   gdb_assert ((readbuf == nullptr) != (writebuf == nullptr));
   ...
 }

 int
 linux_process_target::read_memory (CORE_ADDR memaddr,
                                    unsigned char *myaddr, int len)
 {
   return proc_xfer_memory (memaddr, myaddr, nullptr, len);
 }

 linux_process_target::write_memory (CORE_ADDR memaddr,
                                    const unsigned char *myaddr, int len)
 {
   return proc_xfer_memory (memaddr, nullptr, myaddr, len);
 }

Surprisingly, the assertion fails.  That happens because it can happen
that target_write_memory is called with LEN==0, due to this in
gdb/remote.c:

 /* Determine whether the remote target supports binary downloading.
    This is accomplished by sending a no-op memory write of zero length
    to the target at the specified address. (...) */

 void
 remote_target::check_binary_download (CORE_ADDR addr)
 {
 ...
       p = rs->buf.data ();
       *p++ = 'X';
       p += hexnumstr (p, (ULONGEST) addr);
       *p++ = ',';
       p += hexnumstr (p, (ULONGEST) 0);
       *p++ = ':';
       *p = '\0';

In this scenario, in gdbserver's target_write_memory, the "myaddr"
argument of the_target->write_memory is passed the data() of a local
gdb::byte_vector (which is a specialized std::vector).  It's valid for
std::vector::data() to return NULL when the vector is empty.

This commit adds an early return to target_write_memory to avoid
target backends having to care about this.  For good measure, do the
same on the read side, in read_inferior_memory.

Change-Id: Iac8f04fcf99014c624ef4036bd318ca1771ad491
2022-04-14 20:22:42 +01:00
Pedro Alves
330d63093c gdbserver/qXfer::threads, prepare_to_access_memory=>target_pause_all
handle_qxfer_threads_proper needs to pause all threads even if the
target can read memory when threads are running, so use
target_pause_all instead, which is what the Linux implementation of
prepare_to_access_memory uses.  (Only Linux implements this hook.)

A following patch will make the Linux backend be able to access memory
when threads are running, and thus will also make
prepare_to_access_memory do nothing, which would cause testsuite
regressions without this change.

Change-Id: I127fec7246b7c45b60dfa7341e781606bf54b5da
2022-04-14 20:21:11 +01:00
Tom Tromey
8bbdbd6985 Use GetThreadDescription on Windows
Windows 10 introduced SetThreadDescription and GetThreadDescription, a
simpler way to set a thread's name.  This changes gdb and gdbserver to
use this convention when it is available.

This is part of PR win32/29050.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29050
2022-04-14 12:12:35 -06:00
Tom Tromey
42a5971407 Implement thread_name for gdbserver
This changes gdbserver to implement thread_name method.
2022-04-14 12:12:34 -06:00
Tom Tromey
44ac251ad2 Share handle_ms_vc_exception with gdbserver
Currently, gdb's native Windows target implements the exception-based
approach for setting thread names, but gdbserver does not.  This patch
moves handle_ms_vc_exception to the shared nat/windows-nat.c code, as
preparation for adding this support to gdbserver.
2022-04-14 12:12:34 -06:00
Tom Tromey
b17c7ab380 Move target_read_string to target/target.c
This moves the two overloads of target_read_string to a new file,
target/target.c, and updates both gdb and gdbserver to build this.
2022-04-14 12:12:34 -06:00
Tom Tromey
c560a5fbae Let std::thread check pass even without pthreads
Currently, the configure check for std::thread relies on pthreads
existing.  However, this means that if std::thread is implemented for
a non-pthreads host, then the check will yield the wrong answer.  This
happened in AdaCore internal builds.  Here, we have this GCC patch:

    https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html

... which adds mingw support to GCC's gthreads implementation, and
also to std::thread.

This configure change fixes this problem and enables threading for
gdb.
2022-04-14 09:28:56 -06:00
Simon Marchi
e88cf517e9 gdbserver: report correct status in thread stop race condition
The test introduced by the following patch would sometimes fail in this
configuration:

    FAIL: gdb.threads/next-fork-other-thread.exp: fork_func=vfork: target-non-stop=on: non-stop=off: displaced-stepping=auto: i=14: next to for loop

The test has multiple threads constantly forking or vforking while the
main thread keep doing "next"s.

(After writing the commit message, I realized this also fixes a similar
failure in gdb.threads/forking-threads-plus-breakpoint.exp with the
native-gdbserver and native-extended-gdbserver boards.)

As stop_all_threads is called, because the main thread finished its
"next", it inevitably happens at some point that we ask the remote
target to stop a thread and wait() reports that this thread stopped with
a fork or vfork event, instead of the SIGSTOP we sent to try to stop it.

While running this test, I attached to GDBserver and stopped at
linux-low.cc:3626.  We can see that the status pulled from the kernel
for 2742805 is indeed a vfork event:

    (gdb) p/x w
    $3 = 0x2057f
    (gdb) p WIFSTOPPED(w)
    $4 = true
    (gdb) p WSTOPSIG(w)
    $5 = 5
    (gdb) p/x (w >> 8) & (PTRACE_EVENT_VFORK << 8)
    $6 = 0x200

However, the statement at line 3626 overrides that:

    ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w)));

OURSTATUS becomes "stopped by a SIGTRAP".  The information about the
fork or vfork is lost.

It's then all downhill from there, stop_all_threads eventually asks for
a thread list update.  That thread list includes the child of that
forgotten fork or vfork, the remote target goes "oh cool, a new process,
let's attach to it!", when in fact that vfork child's destiny was to be
detached.

My reverse-engineered understanding of the code around there is that the
if/else between lines 3562 and 3583 (in the original code) makes sure
OURSTATUS is always initialized (not "ignore").  Either the details are
already in event_child->waitstatus (in the case of fork/vfork, for
example), in which case we just copy event_child->waitstatus to
ourstatus.  Or, if the event is a plain "stopped by a signal" or a
syscall event, OURSTATUS is set to "stopped", but without a signal
number.  Lines 3601 to 3629 (in the original code) serve to fill in that
last bit of information.

The problem is that when `w` holds the vfork status, the code wrongfully
takes this branch, because WSTOPSIG(w) returns SIGTRAP:

  else if (current_thread->last_resume_kind == resume_stop
       && WSTOPSIG (w) != SIGSTOP)

The intent of this branch is, for example, when we sent SIGSTOP to try
to stop a thread, but wait() reports that it stopped with another signal
(that it must have received from somewhere else simultaneously), say
SIGWINCH.  In that case, we want to report the SIGWINCH.  But in our
fork/vfork case, we don't want to take this branch, as the thread didn't
really stop because it received a signal.  For the non "stopped by a
signal" and non "syscall signal" cases, we would ideally skip over all
that snippet that fills in the signal or syscall number.

The fix I propose is to move this snipppet of the else branch of the
if/else above.  In addition to moving the code, the last two "else if"
branches:

  else if (current_thread->last_resume_kind == resume_stop
	   && WSTOPSIG (w) != SIGSTOP)
    {
      /* A thread that has been requested to stop by GDB with vCont;t,
	 but, it stopped for other reasons.  */
      ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w)));
    }
  else if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
    ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w)));

are changed into a single else:

  else
    ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w)));

This is the default path we take if:

 - W is not a syscall status
 - W does not represent a SIGSTOP that have sent to stop the thread and
   therefore want to suppress it

Change-Id: If2dc1f0537a549c293f7fa3c53efd00e3e194e79
2022-04-04 22:11:53 -04:00
Tom Tromey
0578e87f93 Remove some globals from nat/windows-nat.c
nat/windows-nat.c has a number of globals that it uses to communicate
with its clients (gdb and gdbserver).  However, if we ever want the
Windows ports to be multi-inferior, globals won't work.

This patch takes a step toward that by moving most nat/windows-nat.c
globals into a new struct windows_process_info.  Many functions are
converted to be methods on this object.

A couple of globals remain, as they are needed to truly be global due
to the way that the Windows debugging APIs work.

The clients still have a global for the current process.  That is,
this patch is a step toward the end goal, but doesn't implement the
goal itself.
2022-04-04 13:58:37 -06:00
Simon Marchi
20471e00e2 gdbserver/linux: set lwp !stopped when failing to resume
I see some failures, at least in gdb.multi/multi-re-run.exp and
gdb.threads/interrupted-hand-call.exp.  Running `stress -C $(nproc)` at
the same time as the test makes those tests relatively frequent.

Let's take gdb.multi/multi-re-run.exp as an example.  The failure looks
like this, an unexpected "no resumed":

    continue
    Continuing.
    No unwaited-for children left.
    (gdb) FAIL: gdb.multi/multi-re-run.exp: re_run_inf=2: iter=1: continue until exit

The situation is:

 - Inferior 1 is stopped somewhere, it won't really play a role here.
 - Inferior 2 has 2 threads, both stopped.
 - We resume inferior 2, the leader thread is expected to exit, making
   the process exit.

From GDB's perspective, a failing run looks like this:

    [infrun] fetch_inferior_event: enter
      [infrun] scoped_disable_commit_resumed: reason=handling event
      [infrun] do_target_wait: Found 2 inferiors, starting at #1
      [infrun] random_pending_event_thread: None found.
      [remote] wait: enter
        [remote] Packet received: T0506:20dcffffff7f0000;07:20dcffffff7f0000;10:9551555555550000;thread:pae4cd.ae4cd;core:e;
      [remote] wait: exit
      [infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) =
      [infrun] print_target_wait_results:   713933.713933.0 [Thread 713933.713933],
      [infrun] print_target_wait_results:   status->kind = STOPPED, sig = GDB_SIGNAL_TRAP
      [infrun] handle_inferior_event: status->kind = STOPPED, sig = GDB_SIGNAL_TRAP
      [infrun] clear_step_over_info: clearing step over info
      [infrun] context_switch: Switching context from 0.0.0 to 713933.713933.0
      [infrun] handle_signal_stop: stop_pc=0x555555555195
      [infrun] start_step_over: enter
        [infrun] start_step_over: stealing global queue of threads to step, length = 0
        [infrun] operator(): step-over queue now empty
      [infrun] start_step_over: exit
      [infrun] process_event_stop_test: no stepping, continue
      [remote] Sending packet: $Z0,555555555194,1#8e
      [remote] Packet received: OK
      [infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [713933.713933.0] at 0x555555555195
      [remote] Sending packet: $QPassSignals:e;10;14;17;1a;1b;1c;21;24;25;2c;4c;97;#0a
      [remote] Packet received: OK
      [remote] Sending packet: $vCont;c:pae4cd.-1#9f
      [infrun] prepare_to_wait: prepare_to_wait
      [infrun] reset: reason=handling event
      [infrun] maybe_set_commit_resumed_all_targets: enabling commit-resumed for target extended-remote
      [infrun] maybe_call_commit_resumed_all_targets: calling commit_resumed for target extended-remote
      [infrun] maybe_call_commit_resumed_all_targets: calling commit_resumed for target extended-remote
    [infrun] fetch_inferior_event: exit
    [infrun] fetch_inferior_event: enter
      [infrun] scoped_disable_commit_resumed: reason=handling event
      [infrun] do_target_wait: Found 2 inferiors, starting at #0
      [infrun] random_pending_event_thread: None found.
      [remote] wait: enter
        [remote] Packet received: N
      [remote] wait: exit
      [infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) =
      [infrun] print_target_wait_results:   -1.0.0 [process -1],
      [infrun] print_target_wait_results:   status->kind = NO_RESUMED
      [infrun] handle_inferior_event: status->kind = NO_RESUMED
      [remote] Sending packet: $Hgp0.0#ad
      [remote] Packet received: OK
      [remote] Sending packet: $qXfer:threads:read::0,1000#92
      [remote] Packet received: l<threads>\n<thread id="pae4cb.ae4cb" core="3" name="multi-re-run-1" handle="40c7c6f7ff7f0000"/>\n<thread id="pae4cb.ae4cc" core="2" name="multi-re-run-1" handle="40b6c6f7ff7f0000"/>\n<thread id="pae4cd.ae4ce" core="1" name="multi-re-run-2" handle="40b6c6f7ff7f0000"/>\n</threads>\n
      [infrun] stop_waiting: stop_waiting
      [remote] Sending packet: $qXfer:threads:read::0,1000#92
      [remote] Packet received: l<threads>\n<thread id="pae4cb.ae4cb" core="3" name="multi-re-run-1" handle="40c7c6f7ff7f0000"/>\n<thread id="pae4cb.ae4cc" core="2" name="multi-re-run-1" handle="40b6c6f7ff7f0000"/>\n<thread id="pae4cd.ae4ce" core="1" name="multi-re-run-2" handle="40b6c6f7ff7f0000"/>\n</threads>\n
      [infrun] infrun_async: enable=0
      [infrun] reset: reason=handling event
      [infrun] maybe_set_commit_resumed_all_targets: enabling commit-resumed for target extended-remote
      [infrun] maybe_call_commit_resumed_all_targets: calling commit_resumed for target extended-remote
      [infrun] maybe_call_commit_resumed_all_targets: calling commit_resumed for target extended-remote
    [infrun] fetch_inferior_event: exit

We can see that we resume the inferior with vCont;c, but got NO_RESUMED.
When the test passes, we get an EXITED status to indicate the process
has exited.

From GDBserver's point of view, it looks like this.  The logs contain
some logging I added and that are part of this patch.

    [remote] getpkt: getpkt ("vCont;c:pae4cf.-1");  [no ack sent]
    [threads] resume: enter
      [threads] thread_needs_step_over: Need step over [LWP 713931]? Ignoring, should remain stopped
      [threads] thread_needs_step_over: Need step over [LWP 713932]? Ignoring, should remain stopped
      [threads] get_pc: pc is 0x555555555195
      [threads] thread_needs_step_over: Need step over [LWP 713935]? No, no breakpoint found at 0x555555555195
      [threads] get_pc: pc is 0x7ffff7d35a95
      [threads] thread_needs_step_over: Need step over [LWP 713936]? No, no breakpoint found at 0x7ffff7d35a95
      [threads] resume: Resuming, no pending status or step over needed
      [threads] resume_one_thread: resuming LWP 713935
      [threads] proceed_one_lwp: lwp 713935
      [threads] resume_one_lwp_throw:   continue from pc 0x555555555195
      [threads] resume_one_lwp_throw: Resuming lwp 713935 (continue, signal 0, stop not expected)
      [threads] resume_one_lwp_throw: NOW ptid=713935.713935.0 stopped=0 resumed=0
      [threads] resume_one_thread: resuming LWP 713936
      [threads] proceed_one_lwp: lwp 713936
      [threads] resume_one_lwp_throw:   continue from pc 0x7ffff7d35a95
      [threads] resume_one_lwp_throw: Resuming lwp 713936 (continue, signal 0, stop not expected)
      [threads] resume_one_lwp_throw: ptrace errno = 3 (No such process)
    [threads] resume: exit
    [threads] wait_1: enter
      [threads] wait_1: [<all threads>]
      [threads] wait_for_event_filtered: waitpid(-1, ...) returned 0, ERRNO-OK
      [threads] resume_stopped_resumed_lwps: resuming stopped-resumed LWP LWP 713935.713936 at 7ffff7d35a95: step=0
      [threads] resume_one_lwp_throw:   continue from pc 0x7ffff7d35a95
      [threads] resume_one_lwp_throw: Resuming lwp 713936 (continue, signal 0, stop not expected)
      [threads] resume_one_lwp_throw: ptrace errno = 3 (No such process)
      [threads] operator(): check_zombie_leaders: leader_pid=713931, leader_lp!=NULL=1, num_lwps=2, zombie=0
      [threads] operator(): check_zombie_leaders: leader_pid=713935, leader_lp!=NULL=1, num_lwps=2, zombie=1
      [threads] operator(): Thread group leader 713935 zombie (it exited, or another thread execd).
      [threads] delete_lwp: deleting 713935
      [threads] wait_for_event_filtered: exit (no unwaited-for LWP)
    sigchld_handler
      [threads] wait_1: ret = null_ptid, TARGET_WAITKIND_NO_RESUMED
    [threads] wait_1: exit

What happens is:

 - We resume the leader (713935) successfully.
 - The leader exits.
 - We resume the secondary thread (713936), we get ESRCH.  This is
   expected this the leader has exited.
 - resume_one_lwp_throw throws, it's caught by resume_one_lwp.
 - resume_one_lwp checks with check_ptrace_stopped_lwp_gone that the
   failure can be explained by the LWP becoming zombie, and swallows the
   error.
 - Note that this means that the secondary lwp still has stopped==1.
 - wait_1 is called, probably because linux_process_target::resume marks
   the async pipe at the end.
 - The exit event isn't ready yet, probably because the machine is under
   load, so waitpid returns nothing.
 - check_zombie_leaders detects that the leader is zombie and deletes
 - We try to find a resumed (non-stopped) LWP to get an event from,
   there's none since the leader (that was resumed) is now deleted, and
   the secondary thread is still marked stopped.
   wait_for_event_filtered returns -1, causing wait_1 to return
   NO_RESUMED.

What I notice here is that there is some kind of race between the
availability of the process' exit notification and the call to wait_1
that results from marking the async pipe at the end of resume.

I think what we want from this wait_1 invocation is to keep waiting, as
we will eventually get thread exit notifications for both of our
threads.

The fix I came up with is to mark the secondary thread as !stopped (or
resumed) when we fail to resume it.  This makes wait_1 see that there is
at least one resume lwp, so it won't return NO_RESUMED.  I think this
makes sense to consider it resumed, because we are going to receive an
exit event for it.  Here's the GDBserver logs with the fix applied:

    [threads] resume: enter
      [threads] thread_needs_step_over: Need step over [LWP 724595]? Ignoring, should remain stopped
      [threads] thread_needs_step_over: Need step over [LWP 724596]? Ignoring, should remain stopped
      [threads] get_pc: pc is 0x555555555195
      [threads] thread_needs_step_over: Need step over [LWP 724597]? No, no breakpoint found at 0x555555555195
      [threads] get_pc: pc is 0x7ffff7d35a95
      [threads] thread_needs_step_over: Need step over [LWP 724598]? No, no breakpoint found at 0x7ffff7d35a95
      [threads] resume: Resuming, no pending status or step over needed
      [threads] resume_one_thread: resuming LWP 724597
      [threads] proceed_one_lwp: lwp 724597
      [threads] resume_one_lwp_throw:   continue from pc 0x555555555195
      [threads] resume_one_lwp_throw: Resuming lwp 724597 (continue, signal 0, stop not expected)
      [threads] resume_one_lwp_throw: NOW ptid=724597.724597.0 stopped=0 resumed=0
      [threads] resume_one_thread: resuming LWP 724598
      [threads] proceed_one_lwp: lwp 724598
      [threads] resume_one_lwp_throw:   continue from pc 0x7ffff7d35a95
      [threads] resume_one_lwp_throw: Resuming lwp 724598 (continue, signal 0, stop not expected)
      [threads] resume_one_lwp_throw: ptrace errno = 3 (No such process)
    [threads] resume: exit
    [threads] wait_1: enter
      [threads] wait_1: [<all threads>]
    sigchld_handler
      [threads] wait_for_event_filtered: waitpid(-1, ...) returned 0, ERRNO-OK
      [threads] operator(): check_zombie_leaders: leader_pid=724595, leader_lp!=NULL=1, num_lwps=2, zombie=0
      [threads] operator(): check_zombie_leaders: leader_pid=724597, leader_lp!=NULL=1, num_lwps=2, zombie=1
      [threads] operator(): Thread group leader 724597 zombie (it exited, or another thread execd).
      [threads] delete_lwp: deleting 724597
      [threads] wait_for_event_filtered: sigsuspend'ing
    sigchld_handler
      [threads] wait_for_event_filtered: waitpid(-1, ...) returned 724598, ERRNO-OK
      [threads] wait_for_event_filtered: waitpid 724598 received 0 (exited)
      [threads] filter_event: 724598 exited
      [threads] wait_for_event_filtered: waitpid(-1, ...) returned 724597, ERRNO-OK
      [threads] wait_for_event_filtered: waitpid 724597 received 0 (exited)
      [threads] wait_for_event_filtered: waitpid(-1, ...) returned 0, ERRNO-OK
    sigchld_handler
      [threads] wait_1: ret = LWP 724597.724598, exited with retcode 0
    [threads] wait_1: exit

Change-Id: Idf0bdb4cb0313f1b49e4864071650cc83fb3c100
2022-03-31 13:04:22 -04:00
Tom Tromey
c50e54825b Consolidate definition of current_directory
I noticed that both gdbserver and gdb define current_directory.
However, as it is referenced by gdbsupport, it seemed better to define
it there as well.  This patch also moves the declaration to
pathstuff.h.  Tested by rebuilding.
2022-03-30 09:08:48 -06:00
John Baldwin
4bd817e71e nat: Split out platform-independent aarch64 debug register support.
Move non-Linux-specific support for hardware break/watchpoints from
nat/aarch64-linux-hw-point.c to nat/aarch64-hw-point.c.  Changes
beyond a simple split of the code are:

- aarch64_linux_region_ok_for_watchpoint and
  aarch64_linux_any_set_debug_regs_state renamed to drop linux_ as
  they are not platform specific.

- Platforms must implement the aarch64_notify_debug_reg_change
  function which is invoked from the platform-independent code when a
  debug register changes for a given debug register state.  This does
  not use the indirection of a 'low' structure as is done for x86.

- The handling for kernel_supports_any_contiguous_range is not
  pristine.  For non-Linux it is simply defined to true.  Some uses of
  this could perhaps be implemented as new 'low' routines for the
  various places that check it instead?

- Pass down ptid into aarch64_handle_breakpoint and
  aarch64_handle_watchpoint rather than using current_lwp_ptid which
  is only defined on Linux.  In addition, pass the ptid on to
  aarch64_notify_debug_reg_change instead of the unused state
  argument.
2022-03-22 12:05:43 -07:00
Pedro Alves
4414150d33 gdbserver: Fixup previous patch
The previous prepare_resume_reply change missed updating the 'buf'
reference that overwrites the 'T', so if 'buf' was advanced, we'd
still overwrite the wrong character.  This fixes it.

Change-Id: Ia8ce433366b85af4e268c1c49e7b447da3130a4d
2022-03-21 17:01:49 +00:00
Pedro Alves
04f0c03a22 gdbserver: Fix incorrect assertion
While playing with adding a new event kind, I noticed that
prepare_resume_reply TARGET_WAITKIND_FORKED, etc. advance 'buf', so if
we force-disable the T packet, we'd fail the *buf == 'T' assertion.

Fix it by tweaking the assertion to always look at the beginning of
the buffer.

Change-Id: I8c38e32353db115edcde418b3b1e8ba12343c22b
2022-03-21 16:45:49 +00:00
Pedro Alves
8a841a3579 Re-add zombie leader on exit, gdbserver/linux
Same as the previous patch, but for GDBserver.

In summary, the current zombie leader detection code in linux-low.cc
has a race -- if a multi-threaded inferior exits just before
check_zombie_leaders finds that the leader is now zombie via checking
/proc/PID/status, check_zombie_leaders deletes the leader, assuming we
won't get an event for that exit (which we won't in some scenarios,
but not in this one), which is a false-positive scenario, where the
whole process is simply exiting.  Later when we see the last LWP in
our list exit, we report that LWP's exit status as exit code, even
though for the (real) parent process, the exit code that counts is the
child's leader thread's exit code.

Like for GDB, the solution here is to:

   - only report whole-process exit events for the leader.
   - re-add the leader back to the LWP list when we finally see it
     exit.

Change-Id: Id2d7bbb51a415534e1294fff1d555b7ecaa87f1d
2022-03-10 11:35:54 +00:00
Pedro Alves
aa40a989ef gdbserver: Reindent check_zombie_leaders
This fixes the indentation of
linux_process_target::check_zombie_leaders, which will help with
keeping its comments in sync with the gdb/linux-nat.c counterpart.

Change-Id: I37332343bd80423d934249e3de2d04feefad1891
2022-03-10 11:35:53 +00:00
Pedro Alves
5406bc3f1b gdbserver: Reorganize linux_process_target::filter_event
Reorganize linux-low.cc:linux_process_target::filter_event such that
all the handling for events for LWPs not in the LWP list is together.
This helps make a following patch clearer.  The comments and debug
messages have also been tweaked to have them synchronized with the GDB
counterpart.

Change-Id: If9019635f63a846607cfda44b454b4254a404019
2022-03-10 11:35:53 +00:00
Pedro Alves
e48359eaa8 Fix gdbserver/linux target_waitstatus logging assert
Turning on debug output in gdbserver leads to an assertion failure if
gdbserver reports a non-signal event:

    [threads] wait_1: LWP 3273770: extended event with waitstatus status->kind = EXECD, execd_pathname = gdb.threads/non-ldr-exc-1/non-ldr-exc-1
    [threads] wait_1: Hit a non-gdbserver trap event.
  ../../src/gdbserver/../gdb/target/waitstatus.h:365: A problem internal to GDBserver has been detected.
  sig: Assertion `m_kind == TARGET_WAITKIND_STOPPED || m_kind == TARGET_WAITKIND_SIGNALLED' failed.

Fix it in the obvious way, using target_waitstatus::to_string(),
resulting in, for example:

  [threads] wait_1: ret = LWP 1542412.1542412, status->kind = STOPPED, sig = GDB_SIGNAL_TRAP

Change-Id: Ia4832f9b4fa39f4af67fcaf21fd4d909a285a645
2022-03-10 11:35:53 +00:00
Roland McGrath
8674f082e3 Avoid conflict with gnulib open/close macros.
On some systems, the gnulib configuration will decide to define open
and/or close as macros to replace the POSIX C functions.  This
interferes with using those names in C++ class or namespace scopes.

gdbsupport/
	* event-pipe.cc (event_pipe::open): Renamed to ...
	(event_pipe::open_pipe): ... this.
	(event_pipe::close): Renamed to ...
	(event_pipe::close_pipe): ... this.
	* event-pipe.h (class event_pipe): Updated.
gdb/
	* inf-ptrace.h (async_file_open, async_file_close): Updated.
gdbserver/
	* gdbserver/linux-low.cc (linux_process_target::async): Likewise.
2022-03-03 11:21:36 -08:00
John Baldwin
cdc8e9b285 gdbserver linux-low: Convert linux_event_pipe to the event_pipe class.
Use event_pipe from gdbsupport in place of the existing file
descriptor array.
2022-02-22 11:22:14 -08:00
Simon Marchi
a288518611 gdb/linux: remove ptrace support check for exec, fork, vfork, vforkdone, clone, sysgood
I think it's safe to remove checking support for these ptrace features,
they have all been added in what is now ancient times (around the
beginning of Linux 2.6).  This allows removing a bit of complexity in
linux-nat.c and nat/linux-ptrace.c.

It also allows saving one extra fork every time we start debugging on
Linux: linux_check_ptrace_features forks a child process to test if some
ptrace features are supported.  That child process forks a grand-child,
to test whether ptrace reports an event for the fork by the child.  This
is no longer needed, if we assume the kernel supports reporting forks.

PTRACE_O_TRACEVFORKDONE was introduced in Linux in this change, in 2003:

  https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=45c1a159b85b3b30afd26a77b4be312226bba416

PTRACE_O_TRACESYSGOOD was supported at least as of this change, in 2002:

  https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=acc7088569c8eef04eeed0eff51d23bb5bcff964

PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK, PTRACE_O_TRACEEXEC and
PTRACE_O_TRACECLONE were introduced in this change, in 2002:

  https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=a0691b116f6a4473f0fa264210ab9b95771a2b46

Change-Id: Iffb906549a89cc6b619427f976ec044706ab1e8d
2022-02-10 20:10:12 -05:00
Markus Metzger
696c0d5ef2 gdb, gdbserver: update thread identifier in enable_btrace target method
The enable_btrace target method takes a ptid_t to identify the thread on
which tracing shall be enabled.

Change this to thread_info * to avoid translating back and forth between
the two.  This will be used in a subsequent patch.
2022-01-27 13:31:20 +01:00
Simon Marchi
91f94053dd gdbserver: introduce remote_debug_printf
Add remote_debug_printf, and use it for all debug messages controlled by
remote_debug.

Change remote_debug to be a bool, which is trivial in this case.

Change-Id: I90de13cb892faec3830047b571661822b126d6e8
2022-01-18 13:44:38 -05:00
Simon Marchi
c058728c31 gdbserver: introduce threads_debug_printf, THREADS_SCOPED_DEBUG_ENTER_EXIT
Add the threads_debug_printf and THREADS_SCOPED_DEBUG_ENTER_EXIT, which
use the logging infrastructure from gdbsupport/common-debug.h.  Replace
all debug_print uses that are predicated by debug_threads with
threads_dethreads_debug_printf.  Replace uses of the debug_enter and
debug_exit macros with THREADS_SCOPED_DEBUG_ENTER_EXIT, which serves
essentially the same purpose, but allows showing what comes between the
enter and the exit in an indented form.

Note that "threads" debug is currently used for a bit of everything in
GDBserver, not only threads related stuff.  It should ideally be cleaned
up and separated logically as is done in GDB, but that's out of the
scope of this patch.

Change-Id: I2d4546464462cb4c16f7f1168c5cec5a89f2289a
2022-01-18 13:44:32 -05:00