aboutsummaryrefslogtreecommitdiff
path: root/gdbserver/linux-low.cc
AgeCommit message (Collapse)AuthorFilesLines
11 daysgdbserver: remove pidof(process)Simon Marchi1-1/+1
This function doesn't seem so useful, use `process_info::pid` directly instead. Change-Id: I55d592f38b32a197957ed4c569993cd23a818cb4 Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
11 daysgdbserver: remove pid_of(thread)Simon Marchi1-6/+5
This function doesn't seem so useful, use `thread_info::id::pid` directly instead. Change-Id: I7450c4223e5b0bf66788eeb5b070ab6f5287f798 Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
11 daysgdbserver: remove lwpid_of(thread)Simon Marchi1-100/+94
This function doesn't seem so useful. Use `thread_info::id::lwp` directly. Change-Id: Ib4a86eeeee6c1342bc1c092f083589ce28009be1 Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
11 daysgdbserver: remove ptid_of(thread)Simon Marchi1-38/+37
This function doesn't seem so useful. Use `thread_info::id` directly. Change-Id: I158cd06a752badd30f68424e329aa42d275e43b7 Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
11 daysgdbserver: remove current_ptid macroSimon Marchi1-1/+1
I think it just makes things more obscure. Use `thread_info::id` directly instead. Change-Id: I141d5fb08ebf45c13cc32c4bba62773249fcb356 Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
11 daysgdbserver: remove get_thread_processSimon Marchi1-14/+8
Remove the `get_thread_process` function, use `thread_info::process` instead. In `server.cc`, use `current_process ()` instead of going through the current thread. Change-Id: Ifc61d65852e392d154b854a45d45df584ab3922e Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
11 daysgdbserver: make remove_thread a method of process_infoSimon Marchi1-2/+2
Same idea as the previous patch, but for `remove_thread`. Change-Id: I7e227655be5fcf29a3256e8389eb32051f27882d Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
11 daysgdbserver: make add_thread a method of process_infoSimon Marchi1-1/+1
Since thread_info objects are now basically children of process_info objects, I think that makes sense. Change-Id: I7f0a67b921b468e512851cb2f36015d1003412d7 Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
11 daysgdbserver: remove for_each_thread(pid, func)Simon Marchi1-7/+7
Remove this overload, prefer to use `process_info::for_each_thread`. In many instances, the `process_info` is already available, so this saves a map lookup. In other instances, add the `process_info` lookup at the call site. In `linux-arm-low.cc` and `win32-i386-low.cc`, use `current_process ()` instead of `current_thread->id.pid ()`. I presume that if `current_process ()` and `current_thread` don't match, it's a bug orthogonal to this change. Change-Id: I751ed497cb1f313cf937b35125151bee9316fc51 Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
2024-09-24btrace: Enable event tracing on Linux for Intel PT.Felix Willgerodt1-0/+2
Event tracing allows GDB to show information about interesting asynchronous events when tracing with Intel PT. Subsequent patches will add support for displaying each type of event. Enabling event-tracing unconditionally would result in rather noisy output, as breakpoints themselves result in interrupt events. Which is why this patch adds a set/show command to allow the user to enable/disable event-tracing before starting a recording. The event-tracing setting has no effect on an already active recording. The default setting is off. As event tracing will use the auxiliary infrastructure added by ptwrite, the user can still disable printing events, even when event-tracing was enabled, by using the /a switch for the record instruction-history/function-call-history commands. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Markus Metzger <markus.t.metzger@intel.com>
2024-08-14btrace, gdbserver: Add ptwrite to btrace_config_pt.Felix Willgerodt1-0/+3
This enables gdb and gdbserver to communicate about ptwrite support. If ptwrite support would be enabled unconditionally, GDBs with older libipt versions would break. Approved-By: Markus Metzger <markus.t.metzger@intel.com> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-06-14gdb: move have_ptrace_getregset declaration into gdb/nat directoryAndrew Burgess1-1/+1
In a later commit I want to access have_ptrace_getregset from a .c file in the nat/ directory. To achieve this I need access to the declaration of have_ptrace_getregset. Currently have_ptrace_getregset is declared (and defined) twice, once in GDB and once in gdbserver. This commit moves the declaration into nat/linux-nat.h, but leaves the two definitions where they are. Now, in my later commit, I can pull in the declaration from nat/linux-nat.h. There should be no user visible changes after this commit. Approved-By: Felix Willgerodt <felix.willgerodt@intel.com>
2024-05-07gdbserver: convert have_ptrace_getregset to a triboolAndrew Burgess1-1/+1
Convert the have_ptrace_getregset global within gdbserver to a tribool. This brings the flag into alignment with the corresponding flag in GDB. The gdbserver have_ptrace_getregset variable is already used as a tribool, it just doesn't have the tribool type. In a future commit I plan to share more code between GDB and gdbserver, and having this variable be the same type in both code bases will make the sharing much easier. There should be no user visible changes after this commit. Approved-By: John Baldwin <jhb@FreeBSD.org> Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
2024-04-17gdb+gdbserver/Linux: Remove USE_SIGTRAP_SIGINFO fallbackPedro Alves1-37/+2
It's been over 9 years (since commit faf09f0119da) since Linux GDB and GDBserver started relying on SIGTRAP si_code to tell whether a breakpoint triggered, which is important for non-stop mode. When that then-new code was added, I had left the then-old code as fallback, in case some architectured still needed it. Given AFAIK there haven't been complaints since, this commit finally removes the fallback code, along with USE_SIGTRAP_SIGINFO. Change-Id: I140a5333a9fe70e90dbd186aca1f081549b2e63d
2024-03-26gdb, gdbserver, gdbsupport: remove includes of early headersSimon Marchi1-1/+0
Now that defs.h, server.h and common-defs.h are included via the `-include` option, it is no longer necessary for source files to include them. Remove all the inclusions of these files I could find. Update the generation scripts where relevant. Change-Id: Ia026cff269c1b7ae7386dd3619bc9bb6a5332837 Approved-By: Pedro Alves <pedro@palves.net>
2024-03-26Revert "gdbserver: convert have_ptrace_getregset to a tribool"Andrew Burgess1-1/+1
This reverts commit 5920765d7513aaae9241a1850d62d73e0477f81c.
2024-03-25gdbserver: convert have_ptrace_getregset to a triboolAndrew Burgess1-1/+1
Convert the have_ptrace_getregset global within gdbserver to a tribool. This brings the flag into alignment with the corresponding flag in GDB. The gdbserver have_ptrace_getregset variable is already used as a tribool, it just doesn't have the tribool type. In a future commit I plan to share more code between GDB and gdbserver, and having this variable be the same type in both code bases will make the sharing much easier. There should be no user visible changes after this commit. Approved-By: John Baldwin <jhb@FreeBSD.org>
2024-02-09Fix crash in aarch64-linux gdbserverPedro Alves1-6/+15
Since commit 393a6b5947d0 ("Thread options & clone events (Linux GDBserver)"), aarch64-linux gdbserver crashes when the inferior vforks. This happens in aarch64_get_debug_reg_state: struct process_info *proc = find_process_pid (pid); return &proc->priv->arch_private->debug_reg_state; Here, find_process_pid returns nullptr -- the new inferior hasn't yet been created in linux_process_target::handle_extended_wait. This patch fixes the problem by having linux_process_target::handle_extended_wait create the child process earlier, before the child LWP is created. This is what the function did before it was reorganized by the commit referred above. Change-Id: Ib8b3a2e6048c3ad2b91a92ea4430da507db03c50 Co-Authored-By: Tom Tromey <tromey@adacore.com>
2024-01-12Update copyright year range in header of all files managed by GDBAndrew Burgess1-1/+1
This commit is the result of the following actions: - Running gdb/copyright.py to update all of the copyright headers to include 2024, - Manually updating a few files the copyright.py script told me to update, these files had copyright headers embedded within the file, - Regenerating gdbsupport/Makefile.in to refresh it's copyright date, - Using grep to find other files that still mentioned 2023. If these files were updated last year from 2022 to 2023 then I've updated them this year to 2024. I'm sure I've probably missed some dates. Feel free to fix them up as you spot them.
2024-01-09Fix two bugs in gdbserver thread name handlingTom Tromey1-3/+6
Simon pointed out that my earlier patch to gdbserver's thread name code: commit 07b3255c3bae7126a0d679f957788560351eb236 Author: Tom Tromey <tom@tromey.com> Date: Thu Jul 13 17:28:48 2023 -0600 Filter invalid encodings from Linux thread names ... introduced a regression. This bug was that the iconv output was not \0-terminated. Looking at it, I found another bug as well -- replace_non_ascii would not \0-terminate, and also would return the wrong pointer This patch fixes both of them. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31153
2023-12-01Bail out of "attach" if a thread cannot be tracedTom Tromey1-2/+13
On Linux, threads are treated much like separate processes by the kernel. In particular, it's possible to ptrace just a single thread. If gdb tries to attach to a multi-threaded inferior, where a non-main thread is already being traced (e.g., by strace), then gdb will get into an infinite loop attempting to attach. This patch fixes this problem by having the attach fail if ptrace fails to attach to any thread of the inferior.
2023-11-14Filter invalid encodings from Linux thread namesTom Tromey1-2/+57
On Linux, a thread can only be 16 bytes (including the trailing \0). A user sent in a test case where this causes a truncated UTF-8 sequence, causing gdbserver to create invalid XML. I went back and forth about different ways to solve this, and in the end decided to fix it in gdbserver, with the reason being that it seems important to generate correct XML for the <thread> response. I am not totally sure whether the call to setlocale could have unplanned consequences. This is needed, though, for nl_langinfo to return the correct result. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30618
2023-11-13Report thread exit event for leader if reporting thread exit eventsPedro Alves1-10/+65
If GDB sets the GDB_THREAD_OPTION_EXIT option on a thread, then if the thread disappears from the thread list, GDB expects to shortly see a thread exit event for it. See e.g., here, in remote_target::update_thread_list(): /* Do not remove the thread if we've requested to be notified of its exit. For example, the thread may be displaced stepping, infrun will need to handle the exit event, and displaced stepping info is recorded in the thread object. If we deleted the thread now, we'd lose that info. */ if ((tp->thread_options () & GDB_THREAD_OPTION_EXIT) != 0) continue; There's one scenario that is deleting a thread from the remote/gdbserver thread list without ever reporting a corresponding thread exit event though -- check_zombie_leaders. This can lead to GDB getting confused. For example, with a following patch that enables GDB_THREAD_OPTION_EXIT whenever schedlock is enabled, we'd see this regression: $ make check RUNTESTFLAGS="--target_board=native-extended-gdbserver" TESTS="gdb.threads/no-unwaited-for-left.exp" ... Running src/gdb/testsuite/gdb.threads/no-unwaited-for-left.exp ... FAIL: gdb.threads/no-unwaited-for-left.exp: continue stops when the main thread exits (timeout) ... some more cascading FAILs ... gdb.log shows: (gdb) continue Continuing. FAIL: gdb.threads/no-unwaited-for-left.exp: continue stops when the main thread exits (timeout) A passing run would have resulted in: (gdb) continue Continuing. No unwaited-for children left. (gdb) PASS: gdb.threads/no-unwaited-for-left.exp: continue stops when the main thread exits note how the leader thread is not listed in the remote-reported XML thread list below: (gdb) set debug remote 1 (gdb) set debug infrun 1 (gdb) info threads Id Target Id Frame * 1 Thread 1163850.1163850 "no-unwaited-for" main () at /home/pedro/rocm/gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.threads/no-unwaited-for-left.c:65 3 Thread 1163850.1164130 "no-unwaited-for" [remote] Sending packet: $Hgp11c24a.11c362#39 (gdb) c Continuing. [infrun] clear_proceed_status_thread: 1163850.1163850.0 ... [infrun] resume_1: step=1, signal=GDB_SIGNAL_0, trap_expected=1, current thread [1163850.1163850.0] at 0x55555555534f [remote] Sending packet: $QPassSignals:#f3 [remote] Packet received: OK [remote] Sending packet: $QThreadOptions;3:p11c24a.11c24a#f3 [remote] Packet received: OK ... [infrun] target_set_thread_options: [options for Thread 1163850.1163850 are now 0x3] ... [infrun] do_target_resume: resume_ptid=1163850.1163850.0, step=0, sig=GDB_SIGNAL_0 [remote] Sending packet: $vCont;c:p11c24a.11c24a#98 [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] fetch_inferior_event: exit [infrun] fetch_inferior_event: enter [infrun] scoped_disable_commit_resumed: reason=handling event [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="p11c24a.11c362" core="0" name="no-unwaited-for" handle="0097d8f7ff7f0000"/>\n</threads>\n [infrun] handle_no_resumed: TARGET_WAITKIND_NO_RESUMED (ignoring: found resumed) ... ... however, infrun decided there was a resumed thread still, so ignored the TARGET_WAITKIND_NO_RESUMED event. Debugging GDB, we see that the "found resumed" thread that GDB finds, is the leader thread. Even though that thread is not on the remote-reported thread list, it is still on the GDB thread list, due to the special case in remote.c mentioned above. This commit addresses the issue by fixing GDBserver to report a thread exit event for the zombie leader too, i.e., making GDBserver respect the "if thread has GDB_THREAD_OPTION_EXIT set, report a thread exit" invariant. To do that, it takes a bit more code than one would imagine off hand, due to the fact that we currently always report LWP exit pending events as TARGET_WAITKIND_EXITED, and then decide whether to convert it to TARGET_WAITKIND_THREAD_EXITED just before reporting the event to GDBserver core. For the zombie leader scenario described, we need to record early on that we want to report a THREAD_EXITED event, and then make sure that decision isn't lost along the way to reporting the event to GDBserver core. Reviewed-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I1e68fccdbc9534434dee07163d3fd19744c8403b
2023-11-13gdbserver: Queue no-resumed event after thread exitPedro Alves1-19/+28
Normally, if the last resumed thread on the target exits, the server sends a no-resumed event to GDB. If however, GDB enables the GDB_THREAD_OPTION_EXIT option on a thread, and, that thread exits, the server sends a thread exit event for that thread instead. In all-stop RSP mode, since events can only be forwarded to GDB one at a time, and the whole target stops whenever an event is reported, GDB resumes the target again after getting a THREAD_EXITED event, and then the server finally reports back a no-resumed event if/when appropriate. For non-stop RSP though, events are asynchronous, and if the server sends a thread-exit event for the last resumed thread, the no-resumed event is never sent. This patch makes sure that in non-stop mode, the server queues a no-resumed event after the thread-exit event if it was the last resumed thread that exited. Without this, we'd see failures in step-over-thread-exit testcases added later in the series, like so: continue Continuing. - No unwaited-for children left. - (gdb) PASS: gdb.threads/step-over-thread-exit.exp: displaced-stepping=off: non-stop=on: target-non-stop=on: schedlock=off: ns_stop_all=1: continue stops when thread exits + FAIL: gdb.threads/step-over-thread-exit.exp: displaced-stepping=off: non-stop=on: target-non-stop=on: schedlock=off: ns_stop_all=1: continue stops when thread exits (timeout) (and other similar ones) Reviewed-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I927d78b30f88236dbd5634b051a716f72420e7c7
2023-11-13Implement GDB_THREAD_OPTION_EXIT support for Linux GDBserverPedro Alves1-13/+25
This implements support for the new GDB_THREAD_OPTION_EXIT thread option for Linux GDBserver. Reviewed-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I96b719fdf7fee94709e98bb3a90751d8134f3a38 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27338
2023-11-13gdbserver/linux-low.cc: Ignore event_ptid if TARGET_WAITKIND_IGNOREPedro Alves1-1/+0
gdbserver's linux_process_target::wait loops if: - called in sync mode, and, - wait_1 returns TARGET_WAITKIND_IGNORE, _and_, - wait_1 also returns null_ptid. The null_ptid check fails however when this path is taken: ptid_t linux_process_target::filter_exit_event (lwp_info *event_child, target_waitstatus *ourstatus) { ... if (!is_leader (thread)) { if (report_exit_events_for (thread)) ourstatus->set_thread_exited (0); else ourstatus->set_ignore (); <<<<<<< delete_lwp (event_child); } return ptid; } This makes linux_process_target::wait return TARGET_WAITKIND_IGNORE in sync mode, which is unexpected by the core and fails an assertion. This commit fixes it by just making linux_process_target::wait loop if it got a TARGET_WAITKIND_IGNORE, irrespective of event_ptid. Change-Id: I39776908a6c75cbd68aa04139ffcf7be334868cf
2023-11-13gdbserver: Hide and don't detach pending clone childrenPedro Alves1-2/+3
This commit extends the logic added by these two commits from a while ago: #1 7b961964f866 (gdbserver: hide fork child threads from GDB), #2 df5ad102009c (gdb, gdbserver: detach fork child when detaching from fork parent) ... to handle thread clone events, which are very similar to (v)fork events. For #1, we want to hide clone children as well, so just update the comments. For #2, unlike (v)fork children, pending clone children aren't full processes, they're just threads, so don't detach them in handle_detach. linux-low.cc will take care of detaching them along with all other threads of the process, there's nothing special that needs to be done. Reviewed-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I7f5901d07efda576a2522d03e183994e071b8ffc
2023-11-13Thread options & clone events (Linux GDBserver)Pedro Alves1-118/+135
This patch teaches the Linux GDBserver backend to report clone events to GDB, when GDB has requested them with the GDB_THREAD_OPTION_CLONE thread option, via the new QThreadOptions packet. This shuffles code in linux_process_target::handle_extended_wait around to a more logical order when we now have to handle and potentially report all of fork/vfork/clone. Raname lwp_info::fork_relative -> lwp_info::relative as the field is no longer only about (v)fork. With this, gdb.threads/stepi-over-clone.exp now cleanly passes against GDBserver, so remove the native-target-only requirement from that testcase. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=19675 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27830 Reviewed-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I3a19bc98801ec31e5c6fdbe1ebe17df855142bb2
2023-08-30gdbserver, linux-low: add a couple of nullptr assertions.Willgerodt, Felix1-0/+4
This safeguards a couple of places that may theoretically return NULL but must not in this specific context. These were found by a static analysis tool. Approved-By: Tom Tromey <tom@tromey.com>
2023-08-11gdbserver: Reinstall software single-step breakpoints in ↵Kevin Buettner1-1/+6
resume_stopped_resumed_lwps At the moment, while performing a software single-step, gdbserver fails to reinsert software single-step breakpoints for a LWP when interrupted by a signal in another thread. This commit fixes this problem by reinstalling software single-step breakpoints in linux_process_target::resume_stopped_resumed_lwps in gdbserver/linux-low.cc. This bug was discovered due to a failing assert in maybe_hw_step() in gdbserver/linux-low.cc. Looking at the backtrace revealed that the caller was linux_process_target::resume_stopped_resumed_lwps. I was uncertain whether the assert should still be valid when called from that method, so I tried hoisting the assert from maybe_hw_step to all callers except resume_stopped_resumed_lwps. But running the new test case, described below, showed that merely eliminating the assert for this case was NOT a good fix - a study of the log file for the test showed that the single-step operation failed to occur. Instead GDB (via gdbserver) stopped at the next breakpoint that was hit. Zhiyong Yan had proposed a fix which resinserted software single-step breakpoints, albeit at a different location in linux-low.cc. Testing revealed that, while running gdb.threads/pending-fork-event-detach, the executable associated with that test would die due to a SIGTRAP after the test program was detached. Examination of the core file(s) showed that a breakpoint instruction had been left in program memory. Test results were otherwise very good, so Zhiyong was definitely on the right track! This commit causes software single-step breakpoint(s) to be inserted before the call to maybe_hw_step in resume_stopped_resumed_lwps. This will cause 'has_single_step_breakpoints (thread)' to be true, so that the assert in maybe_hw_step... /* GDBserver must insert single-step breakpoint for software single step. */ gdb_assert (has_single_step_breakpoints (thread)); ...will no longer fail. And better still, the single-step breakpoints are reinstalled, so that stepping will actually work, even when interrupted. The C code for the test case was loosely adapted from the reproducer provided in Zhiyong's bug report for this problem. The .exp file was copied from next-fork-other-thread.exp and then tweaked slightly. As noted in a comment in next-fork-exec-other-thread.exp, I had to remove "on" from the loop for non-stop as it was failing on all architectures (including x86-64) that I tested. I have a feeling that it ought to work, but this can be investigated separately and (re)enabled once it works. I also increased the number of iterations for the loop running the "next" commands. I've had some test runs which don't show the bug until the loop counter exceeded 100 iterations. The C file for the new test uses shorter delays than next-fork-other-thread.c though, so it doesn't take overly long (IMO) to run this new test. Running the new test on a Raspberry Pi w/ a 32-bit (Arm) kernel and userland using a gdbserver build without the fix in this commit shows the following results: FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=fork: target-non-stop=auto: non-stop=off: displaced-stepping=auto: i=12: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=fork: target-non-stop=auto: non-stop=off: displaced-stepping=on: i=9: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=fork: target-non-stop=auto: non-stop=off: displaced-stepping=off: i=18: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=fork: target-non-stop=off: non-stop=off: displaced-stepping=auto: i=3: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=fork: target-non-stop=off: non-stop=off: displaced-stepping=on: i=11: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=fork: target-non-stop=off: non-stop=off: displaced-stepping=off: i=1: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=auto: non-stop=off: displaced-stepping=auto: i=1: next to break here FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=auto: non-stop=off: displaced-stepping=on: i=3: next to break here FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=auto: non-stop=off: displaced-stepping=off: i=1: next to break here FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=on: non-stop=off: displaced-stepping=auto: i=47: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=on: non-stop=off: displaced-stepping=on: i=57: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=off: non-stop=off: displaced-stepping=auto: i=1: next to break here FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=off: non-stop=off: displaced-stepping=on: i=10: next to break here FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=off: non-stop=off: displaced-stepping=off: i=1: next to break here === gdb Summary === # of unexpected core files 12 # of expected passes 3011 # of unexpected failures 14 Each of the 12 core files were caused by the failed assertion in maybe_hw_step in linux-low.c. These correspond to 12 of the unexpected failures. When the tests are run using a gdbserver build which includes the fix in this commit, the results are significantly better, but not perfect: FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=on: non-stop=off: displaced-stepping=auto: i=143: next to other line FAIL: gdb.threads/next-fork-exec-other-thread.exp: fork_func=vfork: target-non-stop=on: non-stop=off: displaced-stepping=on: i=25: next to other line === gdb Summary === # of expected passes 10178 # of unexpected failures 2 I think that the two remaining failures are due to some different problem. They are also racy - I've seen runs with no failures or only one failure, but never more than two. Also, those runs were conducted with the loop count in next-fork-exec-other-thread.exp set to 200. During his testing of this fix and the new test case, Luis Machado found that this test was taking a long time and asked about ways to speed it up. I then conducted additional tests in which I gradually reduced the loop count, timing each one, also noting the number of failures. With the loop count set to 30, I found that I could still reliably reproduce the failures that Zhiyong reported (in which, with the proper settings, core files are created). But, with the loop count set to 30, the other failures noted above were much less likely to show up. Anyone wishing to investigate those other failures should set the loop count back up to 200. Running the new test on x86-64 and aarch64, both native and native-gdbserver shows no failures. Also, I see no regressions when running the entire test suite for armv7l-unknown-linux-gnueabihf (i.e. the Raspberry Pi w/ 32-bit kernel+userland) with --target_board=native-gdbserver. Additionally, using --target_board=native-gdbserver, I also see no regressions for the entire test suite for x86-64 and aarch64 running Fedora 38. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30387 Co-Authored-By: Zhiyong Yan <zhiyong.yan@windriver.com> Tested-By: Zhiyong Yan <zhiyong.yan@windriver.com> Tested-By: Luis Machado <luis.machado@arm.com>
2023-07-06Linux: Avoid pread64/pwrite64 for high memory addresses (PR gdb/30525)Pedro Alves1-12/+17
Since commit 05c06f318fd9 ("Linux: Access memory even if threads are running"), GDB prefers pread64/pwrite64 to access inferior memory instead of ptrace. That change broke reading shared libraries on SPARC64 Linux, as reported by PR gdb/30525 ("gdb cannot read shared libraries on SPARC64"). On SPARC64 Linux, surprisingly (to me), userspace shared libraries are mapped at high 64-bit addresses: (gdb) info sharedlibrary Cannot access memory at address 0xfff80001002011e0 Cannot access memory at address 0xfff80001002011d8 Cannot access memory at address 0xfff80001002011d8 From To Syms Read Shared Object Library 0xfff80001000010a0 0xfff8000100021f80 Yes (*) /lib64/ld-linux.so.2 (*): Shared library is missing debugging information. Those addresses are 64-bit addresses with the high bits set. When interpreted as signed, they're negative. The Linux kernel rejects pread64/pwrite64 if the offset argument of type off_t (a signed type) is negative, which happens if the memory address we're accessing has its high bit set. See linux/fs/read_write.c sys_pread64 and sys_pwrite64 in Linux. Thankfully, lseek does not fail in that situation. So the fix is to use the 'lseek + read|write' path if the offset would be negative. Fix this in both native GDB and GDBserver. Tested on a SPARC64 GNU/Linux and x86-64 GNU/Linux. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30525 Change-Id: I79c724f918037ea67b7396fadb521bc9d1b10dc5
2023-06-05[gdb] Fix more typosTom de Vries1-1/+1
Fix some more typos: - distinquish -> distinguish - actualy -> actually - singe -> single - frash -> frame - chid -> child - dissassembler -> disassembler - uninitalized -> uninitialized - precontidion -> precondition - regsiters -> registers - marge -> merge - sate -> state - garanteed -> guaranteed - explictly -> explicitly - prefices (nonstandard plural) -> prefixes - bondary -> boundary - formated -> formatted - ithe -> the - arrav -> array - coresponding -> corresponding - owend -> owned - fials -> fails - diasm -> disasm - ture -> true - tpye -> type There's one code change, the name of macro SIG_CODE_BONDARY_FAULT changed to SIG_CODE_BOUNDARY_FAULT. Tested on x86_64-linux.
2023-03-09gdb, gdbserver, gdbsupport: fix whitespace issuesSimon Marchi1-1/+1
Replace spaces with tabs in a bunch of places. Change-Id: If0f87180f1d13028dc178e5a8af7882a067868b0
2023-03-01Fix btrace regressionTom Tromey1-1/+1
Tom de Vries pointed out that my earlier patch: commit 873a185be258ad2552b9579005852815b4da5baf Date: Fri Dec 16 07:56:57 2022 -0700 Don't use struct buffer in handle_qxfer_btrace regressed gdb.btrace/reconnect.exp. I didn't notice this because I did not have libipt installed. This patch fixes the bug. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30169 Tested-By: Bruno Larsen <blarsen@redhat.com>
2023-02-24gdbserver/linux-low.cc: Fix a typo in ternary operatorKhem Raj1-1/+1
Signed-off-by: Khem Raj <raj.khem@gmail.com>
2023-02-24Don't use struct buffer in handle_qxfer_btraceTom Tromey1-36/+36
This changes handle_qxfer_btrace and handle_qxfer_btrace_conf, in gdbserver, to use std::string rather than struct buffer.
2023-02-01gdbserver: Add PID parameter to linux_get_auxv and linux_get_hwcapThiago Jung Bauermann1-9/+9
This patch doesn't change gdbserver behaviour, but after later changes are made it avoids a null pointer dereference when HWCAP needs to be obtained for a specific process while current_thread is nullptr. Fixing linux_read_auxv, linux_get_hwcap and linux_get_hwcap2 to take a PID parameter seems more correct than setting current_thread in one particular code path. Changes are propagated to allow passing the new parameter through the call chain. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-01-01Update copyright year range in header of all files managed by GDBJoel Brobecker1-1/+1
This commit is the result of running the gdb/copyright.py script, which automated the update of the copyright year range for all source files managed by the GDB project to be updated to include year 2023.
2022-12-15gdbsupport: change xml_escape_text_append's parameter from pointer to referenceSimon Marchi1-1/+1
The passed in string can't be nullptr, it makes more sense to pass in a reference. Change-Id: Idc8bd38abe1d6d9b44aa227d7856956848c233b3
2022-11-27[gdb/server] Emit warning for SIGINT failureTom de Vries1-1/+4
Consider the executable from test-case gdb.base/interrupt-daemon.exp. When starting it using gdbserver: ... $ ./build/gdbserver/gdbserver localhost:2345 \ ./outputs/gdb.base/interrupt-daemon/interrupt-daemon ... and connecting to it using gdb: ... $ gdb -q -ex "target remote localhost:2345" \ -ex "set follow-fork-mode child" \ -ex "break daemon_main" -ex cont ... we are setup to do the same as in the test-case: interrupt a running inferior using ^C. So let's try: ... (gdb) continue Continuing. ^C ... After pressing ^C, nothing happens. This a known problem, filed as PR remote/18772. The problem is that in linux_process_target::request_interrupt, a kill is used to send a SIGINT, but it fails. And it fails silently. Make the failure verbose by adding a warning, such that the gdbserver output becomes more helpful: ... Process interrupt-daemon created; pid = 15068 Listening on port 2345 Remote debugging from host ::1, port 35148 Detaching from process 15068 Detaching from process 15085 gdbserver: Sending SIGINT to process group of pid 15068 failed: \ No such process ... Note that the failure can easily be reproduced using the test-case and target board native-gdbserver: ... (gdb) continue^M Continuing.^M PASS: gdb.base/interrupt-daemon.exp: fg: continue ^CFAIL: gdb.base/interrupt-daemon.exp: fg: ctrl-c stops process (timeout) ... as reported in PR server/23382. Tested on x86_64-linux. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2022-11-18gdbserver/linux: take condition out of callback in find_lwp_pidSimon Marchi1-2/+2
Just a small optimization, it's not necessary to recompute lwp at each iteration. While at it, change the variable type to long, as ptid_t::lwp returns a long. Reviewed-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I181670ce1f90b59cb09ea4899367750be2ad9105
2022-11-09gdbserver: do not report btrace support if target does not announce itTankut Baris Aktemur1-0/+6
Gdbserver unconditionally reports support for btrace packets. Do not report the support, if the underlying target does not say it supports it. Otherwise GDB would query the server with btrace-related packets unnecessarily.
2022-10-19internal_error: remove need to pass __FILE__/__LINE__Pedro Alves1-13/+7
Currently, every internal_error call must be passed __FILE__/__LINE__ explicitly, like: internal_error (__FILE__, __LINE__, "foo %d", var); The need to pass in explicit __FILE__/__LINE__ is there probably because the function predates widespread and portable variadic macros availability. We can use variadic macros nowadays, and in fact, we already use them in several places, including the related gdb_assert_not_reached. So this patch renames the internal_error function to something else, and then reimplements internal_error as a variadic macro that expands __FILE__/__LINE__ itself. The result is that we now should call internal_error like so: internal_error ("foo %d", var); Likewise for internal_warning. The patch adjusts all calls sites. 99% of the adjustments were done with a perl/sed script. The non-mechanical changes are in gdbsupport/errors.h, gdbsupport/gdb_assert.h, and gdb/gdbarch.py. Approved-By: Simon Marchi <simon.marchi@efficios.com> Change-Id: Ia6f372c11550ca876829e8fd85048f4502bdcf06
2022-10-18gdb, gdbserver: extend RSP to support namespacesMarkus Metzger1-9/+17
Introduce a new qXfer:libraries-svr4:read annex key/value pair lmid=<namespace identifier> to be used together with start and prev to provide the namespace of start and prev to gdbserver. Unknown key/value pairs are ignored by gdbserver so no new supports check is needed. Introduce a new library-list-svr4 library attribute lmid to provide the namespace of a library entry to GDB. This implementation uses the address of a namespace's r_debug object as namespace identifier. This should have incremented the minor version but since unknown XML attributes are ignored, anyway, and since changing the version results in a warning from GDB, the version is left at 1.0.
2022-10-18gdbserver: move main_lm handling into callerMarkus Metzger1-48/+48
When listing SVR4 shared libraries, special care has to be taken about the first library in the default namespace as that refers to the main executable. The load map address of this main executable is provided in an attribute of the library-list-svr4 element. Move that code from where we enumerate libraries inside a single namespace to where we generate the rest of the library-list-svr4 element. This allows us to complete the library-list-svr4 element inside one function. There should be no functional change.
2022-10-18gdb, gdbserver: support dlmopen()Markus Metzger1-94/+153
In glibc, the r_debug structure contains (amongst others) the following fields: int r_version: Version number for this protocol. It should be greater than 0. If r_version is 2, struct r_debug is extended to struct r_debug_extended with one additional field: struct r_debug_extended *r_next; Link to the next r_debug_extended structure. Each r_debug_extended structure represents a different namespace. The first r_debug_extended structure is for the default namespace. 1. Change solib_svr4_r_map argument to take the debug base. 2. Add solib_svr4_r_next to find the link map in the next namespace from the r_next field. 3. Update svr4_current_sos_direct to get the link map in the next namespace from the r_next field. 4. Don't check shared libraries in other namespaces when updating shared libraries in a new namespace. 5. Update svr4_same to check the load offset in addition to the name 6. Update svr4_default_sos to also set l_addr_inferior 7. Change the flat solib_list into a per-namespace list using the namespace's r_debug address to identify the namespace. Add gdb.base/dlmopen.exp to test this. To remain backwards compatible with older gdbserver, we reserve the namespace zero for a flat list of solibs from all namespaces. Subsequent patches will extend RSP to allow listing libraries grouped by namespace. This fixes PR 11839. Co-authored-by: Lu, Hongjiu <hongjiu.lu@intel.com>
2022-06-28gdb+gdbserver/Linux: avoid reading registers while going through shellPedro Alves1-4/+12
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-04-22gdbserver/linux: free process_info_private and arch_process_info when ↵Simon Marchi1-11/+16
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-14gdbserver/linux: Access memory even if threads are runningPedro Alves1-153/+86
Similarly to how the native Linux target was changed and subsequently reworked in these commits: 05c06f318fd9 Linux: Access memory even if threads are running 8a89ddbda2ec 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-04gdbserver: report correct status in thread stop race conditionSimon Marchi1-32/+28
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