aboutsummaryrefslogtreecommitdiff
path: root/gdbserver
AgeCommit message (Collapse)AuthorFilesLines
2022-06-14gdbserver: Add LoongArch/Linux supportYouling Tang3-0/+253
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-07Use subclasses of windows_process_infoTom Tromey2-56/+65
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-07Allow ASLR to be disabled on WindowsTom Tromey2-0/+6
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-07Introduce wrapper for CreateProcessTom Tromey1-4/+1
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-05-18Use aarch64_features to describe register features in target descriptions.John Baldwin5-21/+20
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-13Implement pid_to_exec_file for Windows in gdbserverTom Tromey2-0/+11
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-13Remove windows_process_info::idTom Tromey1-6/+5
I noticed that windows_process_info::id is only used by gdbserver, and not really necessary. This patch removes it.
2022-05-04Fix build failure for aarch64 gdbserverLuis Machado1-1/+1
We're missing an argument.
2022-05-04Fix GDBserver Aarch64 Linux regressionPedro Alves1-3/+3
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-03gdbserver: Fix build after adding tls feature to arm tdesc.John Baldwin1-1/+1
2022-05-03gdbserver: Read the tpidr register from NT_ARM_TLS on Linux.John Baldwin4-11/+42
2022-05-03Add an aarch64-tls feature which includes the tpidr register.John Baldwin2-2/+2
2022-05-03gdbserver: track current process as well as current threadPedro Alves5-11/+79
The recent commit 421490af33bf ("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-04-28Fix libinproctrace.so build on PPCTom Tromey1-1/+2
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-27Fix gdbserver build for x86-64 WindowsTom Tromey3-28/+36
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-22gdbserver/linux: free process_info_private and arch_process_info when ↵Simon Marchi2-11/+19
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-18gdbsupport: make gdb_abspath return an std::stringSimon Marchi1-10/+10
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-14gdbserver: Eliminate prepare_to_access_memoryPedro Alves5-235/+24
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-14gdbserver/linux: Access memory even if threads are runningPedro Alves2-157/+93
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-14gdbserver: special case target_write_memory len==0Pedro Alves1-2/+15
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-14gdbserver/qXfer::threads, prepare_to_access_memory=>target_pause_allPedro Alves1-35/+16
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-14Use GetThreadDescription on WindowsTom Tromey1-1/+1
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-14Implement thread_name for gdbserverTom Tromey2-0/+11
This changes gdbserver to implement thread_name method.
2022-04-14Share handle_ms_vc_exception with gdbserverTom Tromey1-9/+0
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-14Move target_read_string to target/target.cTom Tromey1-0/+2
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-14Let std::thread check pass even without pthreadsTom Tromey1-10/+9
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-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
2022-04-04Remove some globals from nat/windows-nat.cTom Tromey1-112/+133
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-03-31gdbserver/linux: set lwp !stopped when failing to resumeSimon Marchi1-2/+18
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-30Consolidate definition of current_directoryTom Tromey1-4/+0
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-22nat: Split out platform-independent aarch64 debug register support.John Baldwin2-5/+9
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-21gdbserver: Fixup previous patchPedro Alves1-1/+1
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-21gdbserver: Fix incorrect assertionPedro Alves1-4/+5
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-10Re-add zombie leader on exit, gdbserver/linuxPedro Alves1-38/+82
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-10gdbserver: Reindent check_zombie_leadersPedro Alves1-51/+50
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-10gdbserver: Reorganize linux_process_target::filter_eventPedro Alves1-36/+40
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-10Fix gdbserver/linux target_waitstatus logging assertPedro Alves1-2/+2
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-03Avoid conflict with gnulib open/close macros.Roland McGrath1-2/+2
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-02-22gdbserver linux-low: Convert linux_event_pipe to the event_pipe class.John Baldwin1-32/+11
Use event_pipe from gdbsupport in place of the existing file descriptor array.
2022-02-10gdb/linux: remove ptrace support check for exec, fork, vfork, vforkdone, ↵Simon Marchi1-5/+4
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-01-27gdb, gdbserver: update thread identifier in enable_btrace target methodMarkus Metzger5-10/+11
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-18gdbserver: introduce remote_debug_printfSimon Marchi5-97/+48
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-18gdbserver: introduce threads_debug_printf, THREADS_SCOPED_DEBUG_ENTER_EXITSimon Marchi13-798/+483
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-18gdbserver: turn debug_threads into a booleanSimon Marchi5-17/+11
debug_threads is always used as a boolean. Except in ax.cc and tracepoint.cc. These files have their own macros that use debug_threads, and have a concept of verbosity level. But they both have a single level, so it's just a boolean in the end. Remove this concept of level. If we ever want to re-introduce it, I think it will be better implemented in a more common location. Change debug_threads to bool and adjust some users that were treating it as an int. Change-Id: I137f596eaf763a08c977dd74417969cedfee9ecf
2022-01-13gdb: don't use -Wmissing-prototypes with g++Andrew Burgess3-1/+69
This commit aims to not make use of -Wmissing-prototypes when compiling with g++. Use of -Wmissing-prototypes was added with this commit: commit a0761e34f054767de6d6389929d27e9015fb299b Date: Wed Mar 11 15:15:12 2020 -0400 gdb: enable -Wmissing-prototypes warning Because clang can provide helpful warnings with this flag. Unfortunately, g++ doesn't accept this flag, and will give this warning: cc1plus: warning: command line option ‘-Wmissing-prototypes’ is valid for C/ObjC but not for C++ In theory the fact that this flag is not supported should be detected by the configure check in gdbsupport/warning.m4, but for users of ccache, this check doesn't work due to a long standing ccache issue: https://github.com/ccache/ccache/issues/738 The ccache problem is that -W... options are reordered on the command line, and so -Wmissing-prototypes is seen before -Werror. Usually this doesn't matter, but the above warning (about the flag not being valid) is issued before the -Werror flag is processed, and so is not fatal. There have been two previous attempts to fix this that I'm aware of. The first is: https://sourceware.org/pipermail/gdb-patches/2021-September/182148.html In this attempt, instead of just relying on a compile to check if a flag is valid, the proposal was to both compile and link. As linking doesn't go through ccache, we don't suffer from the argument reordering problem, and the link phase will correctly fail when using -Wmissing-prototypes with g++. The configure script will then disable the use of this flag. This approach was rejected, and the suggestion was to only add the -Wmissing-prototypes flag if we are compiling with gcc. The second attempt, attempts this approach, and can be found here: https://sourceware.org/pipermail/gdb-patches/2021-November/183076.html This attempt only adds the -Wmissing-prototypes flag is the value of GCC is not 'yes'. This feels like it is doing the right thing, unfortunately, the GCC flag is really a 'is gcc like' flag, not a strict, is gcc check. As such, GCC is set to 'yes' for clang, which would mean the flag was not included for clang or gcc. The entire point of the original commit was to add this flag for clang, so clearly the second attempt is not sufficient either. In this new attempt I have added gdbsupport/compiler-type.m4, this file defines AM_GDB_COMPILER_TYPE. This macro sets the variable GDB_COMPILER_TYPE to either 'gcc', 'clang', or 'unknown'. In future the list of values might be extended to cover other compilers, if this is ever useful. I've then modified gdbsupport/warning.m4 to only add the problematic -Wmissing-prototypes flag if GDB_COMPILER_TYPE is not 'gcc'. I've tested this with both gcc and clang and see the expected results, gcc no longer attempts to use the -Wmissing-prototypes flag, while clang continues to use it. When compiling using ccache, I am no longer seeing the warning.
2022-01-07Do not use CC_HAS_LONG_LONGTom Tromey1-1/+1
ax.cc checks CC_HAS_LONG_LONG, but nothing defines this. However, PRINTF_HAS_LONG_LONG is checked in configure. This patch removes the former and keeps the latter. This is PR remote/14976 (filed by me in 2012, lol). I'm checking this in. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=14976
2022-01-01Automatic Copyright Year update after running gdb/copyright.pyJoel Brobecker88-88/+88
This commit brings all the changes made by running gdb/copyright.py as per GDB's Start of New Year Procedure. For the avoidance of doubt, all changes in this commits were performed by the script.
2022-01-01Update Copyright Year in gdb, gdbserver and gdbreplay version outputJoel Brobecker2-2/+2
This commit changes the copyright year printed by gdb, gdbserver and gdbreplay when printing the tool's version.
2021-12-15New --enable-threading configure option to control use of threads in ↵Luis Machado1-1/+23
GDB/GDBserver Add the --enable-threading configure option so multithreading can be disabled at configure time. This is useful for statically-linked builds of GDB/GDBserver, since the thread library doesn't play well with that setup. If you try to run a statically-linked GDB built with threading, it will crash when setting up the number of worker threads. This new option is also convenient when debugging GDB in a system with lots of threads, where the thread discovery code in GDB will emit too many messages, like so: [New Thread 0xfffff74d3a50 (LWP 2625599)] If you have X threads, that message will be repeated X times. The default for --enable-threading is "yes".
2021-12-14gdbserver/tracepoint.cc: use snprintf in gdb_agent_socket_initSimon Marchi1-2/+2
If we modify tracepoint.cc to try to use a too long unix socket name, for example by modifying SOCK_DIR to be: #define SOCK_DIR "/tmp/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut/salut" ... trying to start an application with libinproctrace.so loaded crashes: $ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6:./libinproctrace.so /bin/ls /home/smarchi/src/binutils-gdb/gdbserver/../gdbsupport/common-utils.cc:69: A problem internal to GDBserver in-process agent has been detected. xsnprintf: Assertion `ret < size' failed. Looking at the rest of the socket initialization code, the intent seems to be that if something goes wrong, we warn but let the program execute. So crashing on this failed assertions seems against the intent. Commit 6cebaf6e1ae4 ("use xsnprintf instead of snprintf.") changed this code to use xsnprintf instead of snprintf, introducing this assertion. Before that, snprintf would return a value bigger that UNIX_PATH_MAX and the "if" after would catch it and emit a warning, which is exactly what we want. That change was done because LynxOS didn't have snprintf. Since LynxOS isn't supported anymore, we can simply revert to use snprintf there. With this patch, we get a warning (printed by the caller of gdb_agent_socket_init), but the program keeps executing: $ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6:./libinproctrace.so /bin/ls ipa: could not create sync socket ... Change-Id: I78bca52d5dc3145335abeae45a42052701e3f5dd