aboutsummaryrefslogtreecommitdiff
path: root/gdb/target.c
AgeCommit message (Collapse)AuthorFilesLines
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-09-21gdbsupport: convert FILEIO_* macros to an enumSimon Marchi1-23/+23
Converting from free-form macros to an enum gives a bit of type-safety. This caught places where we would assign host error numbers to what should contain a target fileio error number, for instance in target_fileio_pread. I added the FILEIO_SUCCESS enumerator, because remote.c:remote_hostio_parse_result initializes the remote_errno output variable to 0. It seems better to have an explicit enumerator than to assign a value for which there is no enumerator. I considered initializing this variable to FILEIO_EUNKNOWN instead, such that if the remote side replies with an error and omits the errno value, we'll get an errno that represents an error instead of 0 (which reprensents no error). But it's not clear what the consequences of that change would be, so I prefer to err on the side of caution and just keep the existing behavior (there is no intended change in behavior with this patch). Note that remote_hostio_parse_resul still reads blindly what the remote side sends as a target errno into this variable, so we can still end up with a nonsensical value here. It's not good, but out of the scope of this patch. Convert host_to_fileio_error and fileio_errno_to_host to return / accept a fileio_error instead of an int, and cascade the change in the whole chain that uses that. Change-Id: I454b0e3fcf0732447bc872252fa8e57d138b0e03
2022-09-21gdbsupport: move include/gdb/fileio.h contents to fileio.hSimon Marchi1-1/+1
I don't see why include/gdb/fileio.h is placed there. It's not installed by "make install", and it's not included by anything outside of gdb/gdbserver/gdbsupport. Move its content back to gdbsupport/fileio.h. I have omitted the bits inside an `#if 0`, since it's obviously not used, as well as the "limits" constants, which are also unused. Change-Id: I6fbc2ea10fbe4cfcf15f9f76006b31b99c20e5a9
2022-07-22Change target_ops::async to accept boolTom Tromey1-2/+2
This changes the parameter of target_ops::async from int to bool. Regression tested on x86-64 Fedora 34.
2022-05-13Constify target_pid_to_exec_fileTom Tromey1-1/+1
This changes target_pid_to_exec_file and target_ops::pid_to_exec_file to return a "const char *". I couldn't build many of these targets, but did examine the code by hand -- also, as this only affects the return type, it's normally pretty safe. This brings gdb and gdbserver a bit closer, and allows for the removal of a const_cast as well.
2022-04-29Slightly tweak and clarify target_resume's interfacePedro Alves1-5/+8
The current target_resume interface is a bit odd & non-intuitive. I've found myself explaining it a couple times the recent past, while reviewing patches that assumed STEP/SIGNAL always applied to the passed in PTID. It goes like this today: - if the passed in PTID is a thread, then the step/signal request is for that thread. - otherwise, if PTID is a wildcard (all threads or all threads of process), the step/signal request is for inferior_ptid, and PTID indicates which set of threads run free. Because GDB always switches the current thread to "leader" thread being resumed/stepped/signalled, we can simplify this a bit to: - step/signal are always for inferior_ptid. - PTID indicates the set of threads that run free. Still not ideal, but it's a minimal change and at least there are no special cases this way. That's what this patch does. It renames the PTID parameter to SCOPE_PTID, adds some assertions to target_resume, and tweaks target_resume's description. In addition, it also renames PTID to SCOPE_PTID in the remote and linux-nat targets, and simplifies their implementation a little bit. Other targets could do the same, but they don't have to. Change-Id: I02a2ec2ab3a3e9b191de1e9a84f55c17cab7daaf
2022-04-14Move target_read_string to target/target.cTom Tromey1-19/+0
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-14Remove the byte order parameter to target_read_stringTom Tromey1-2/+1
target_read_string takes a byte order parameter, but only uses this to check whether a given character is zero. This is readily done without requiring the parameter, so remove it.
2022-04-14Rename read_stringTom Tromey1-2/+2
This renames read_string to be an overload of target_read_string. This makes it more consistent for the eventual merger with gdbserver.
2022-04-04Handle TLS variable lookups when using separate debug files.John Baldwin1-0/+5
Commit df22c1e5d53c38f38bce6072bb46de240f9e0e2b handled the case that a separate debug file was passed as the objfile for a shared library to svr4_fetch_objfile_link_map. However, a separate debug file can also be passed for TLS variables in the main executable. In addition, frv_fetch_objfile_link_map also expects to be passed the original objfile rather than a separate debug file, so pull the code to resolve a separate debug file to the main objfile up into target_translate_tls_address.
2022-03-29Unify gdb printf functionsTom Tromey1-92/+92
Now that filtered and unfiltered output can be treated identically, we can unify the printf family of functions. This is done under the name "gdb_printf". Most of this patch was written by script.
2022-03-29Unify gdb putc functionsTom Tromey1-1/+1
Now that filtered and unfiltered output can be treated identically, we can unify the putc family of functions. This is done under the name "gdb_putc". Most of this patch was written by script.
2022-03-29Unify gdb puts functionsTom Tromey1-1/+1
Now that filtered and unfiltered output can be treated identically, we can unify the puts family of functions. This is done under the name "gdb_puts". Most of this patch was written by script.
2022-03-29Remove some uses of printf_unfilteredTom Tromey1-8/+8
A number of spots call printf_unfiltered only because they are in code that should not be interrupted by the pager. However, I believe these cases are all handled by infrun's blanket ban on paging, and so can be converted to the default (_filtered) API. After this patch, I think all the remaining _unfiltered calls are ones that really ought to be. A few -- namely in complete_command -- could be replaced by a scoped assignment to pagination_enabled, but for the remainder, the code seems simple enough like this.
2022-03-14Replace deprecated_target_wait_hook by observersPatrick Monnerat1-1/+13
Commit b60cea7 (Make target_wait options use enum flags) broke deprecated_target_wait_hook usage: there's a commit comment telling this hook has not been converted. Rather than trying to mend it, this patch replaces the hook by two target_wait observers: target_pre_wait (ptid_t ptid) target_post_wait (ptid_t event_ptid) Upon target_wait entry, target_pre_wait is notified with the ptid passed to target_wait. Upon exit, target_post_wait is notified with the event ptid returned by target_wait. Should an exception occur, event_ptid is null_ptid. This change benefits to Insight (out-of-tree): there's no real use of the late hook in gdb itself.
2022-02-22Enable async mode on supported targets in target_resume.John Baldwin1-0/+3
Enabling async mode above the target layer removes duplicate code in ::resume methods of async-capable targets. Commit 5b6d1e4fa4f ("Multi-target support") enabled async mode in do_target_resume after target_resume returns which is a step in this direction. However, other callers of target_resume such as target_continue do not enable async mode. Rather than enabling async mode in each of the callers after target_resume returns, enable async mode at the end of target_resume.
2022-01-27gdb, gdbserver: update thread identifier in enable_btrace target methodMarkus Metzger1-2/+2
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-26gdb: convert maintenance target-async and target-non-stop settings to callbacksSimon Marchi1-36/+32
This simplifies things a bit, as we don't need two variables and think about reverting target_async_permitted_1 and target_non_stop_enabled_1 values if we can't change the setting. Change-Id: I36acab045dacf02ae1988486cfdb27c1dff309f6
2022-01-08Add explicit check for nullptr to target_announce_attachTom Tromey1-1/+1
Lancelot pointed out that target_announce_attach was missing an explicit check against nullptr. This patch adds it.
2022-01-06Use target_announce_detach in more targetsTom Tromey1-6/+7
target_announce_detach was added in commit 0f48b757 ("Factor out "Detaching from program" message printing"). There, Pedro wrote: (For now, I left the couple targets that print this a bit differently alone. Maybe this could be further pulled out into infcmd.c. If we did that, and those targets want to continue printing differently, this new function could be converted to a target method.) It seems to me that the differences aren't very big, and in some cases other targets handled the output a bit more nicely. In particular, some targets will print a different message when exec_file==NULL, rather than printing the same output with an empty string as exec_file. This patch incorporates the nicer output into target_announce_detach, then changes the remaining ports to use this function.
2022-01-06Introduce target_announce_attachTom Tromey1-0/+18
This introduces target_announce_attach, by analog with target_announce_detach. Then it converts existing targets to use this, rather than emitting their own output by hand.
2022-01-05Use filtered output in terminal_info implementationsTom Tromey1-1/+1
This changes one terminal_info implementation, and default_terminal_info, to use filtered output. Other implementations of this method already use filtered output. I can't compile go32-nat.c, so this is a 'best effort' patch.
2022-01-05Use filtered output in files_info implementationsTom Tromey1-5/+5
This changes the implementations of the target files_info method to use filtered output. This makes sense because the sole caller of this method is an ordinary command (info_program_command). This patch changes this command to use filtered output as well.
2022-01-01Automatic Copyright Year update after running gdb/copyright.pyJoel Brobecker1-1/+1
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.
2021-12-13gdb: make post_startup_inferior a virtual method on inf_ptrace_targetAndrew Burgess1-8/+0
While working on a later patch that required me to understand how GDB starts up inferiors, I was confused by the target_ops::post_startup_inferior method. The post_startup_inferior target function is only called from inf_ptrace_target::create_inferior. Part of the target class hierarchy looks like this: inf_child_target | '-- inf_ptrace_target | |-- linux_nat_target | |-- fbsd_nat_target | |-- nbsd_nat_target | |-- obsd_nat_target | '-- rs6000_nat_target Every sub-class of inf_ptrace_target, except rs6000_nat_target, implements ::post_startup_inferior. The rs6000_nat_target picks up the implementation of ::post_startup_inferior not from inf_ptrace_target, but from inf_child_target. No descendent of inf_child_target, outside the inf_ptrace_target sub-tree, implements ::post_startup_inferior, which isn't really surprising, as they would never see the method called (remember, the method is only called from inf_ptrace_target::create_inferior). What I find confusing is the role inf_child_target plays in implementing, what is really a helper function for just one of its descendents. In this commit I propose that we formally make ::post_startup_inferior a helper function of inf_ptrace_target. To do this I will remove the ::post_startup_inferior from the target_ops API, and instead make this a protected, pure virtual function on inf_ptrace_target. I'll remove the empty implementation of ::post_startup_inferior from the inf_child_target class, and add a new empty implementation to the rs6000_nat_target class. All the other descendents of inf_ptrace_target already provide an implementation of this method and so don't need to change beyond making the method protected within their class declarations. To me, this makes much more sense now. The helper function, which is only called from within the inf_ptrace_target class, is now a part of the inf_ptrace_target class. The only way in which this change is visible to a user is if the user turns on 'set debug target 1'. With this debug flag on, prior to this patch the user would see something like: -> native->post_startup_inferior (...) <- native->post_startup_inferior (2588939) After this patch these lines are no longer present, as the post_startup_inferior is no longer a top level target method. For me, this is an acceptable change.
2021-11-25gdb: add asserts in target.c for target_async_permittedAndrew Burgess1-1/+6
The target_async_permitted flag allows a user to override whether a target can act in async mode or not. In previous commits I have moved the checking of this flag out of the various ::can_async_p methods and into the common target.c code. In this commit I will add some additional assertions into target_is_async_p and target_async. The rules these assertions are checking are: 1. A target that returns false for target_can_async_p should never become "async enabled", and so ::is_async_p should always return false. This is being checked in target_is_async_p. 2. GDB should never try to enable async mode for a target that returns false for target_can_async_p, this is checked in target_async. There are a few places where we call the ::is_async_p method directly, in these cases we will obviously not pass through the assert in target_is_async_p, however, there are also plenty of places where we do call target_is_async_p so if GDB starts to misbehave we should catch it quickly enough. There should be no user visible changes after this commit.
2021-11-25gdb: hoist target_async_permitted checks into target.cAndrew Burgess1-0/+2
This commit moves the target_async_permitted check out of each targets ::can_async_p method and into the target_can_async_p wrapper function. I've left some asserts in the two ::can_async_p methods that I changed, which will hopefully catch any direct calls to these methods that might be added in the future. There should be no user visible changes after this commit.
2021-11-25gdb: introduce a new overload of target_can_async_pAndrew Burgess1-2/+10
There are a few places where we call the target_ops::can_async_p member function directly, instead of using the target_can_async_p wrapper. In some of these places this is because we need to ask before the target has been pushed, and in another location (in target.c) it seems unnecessary to go through the wrapper when we are already in target.c code. However, in the next commit I'd like to hoist some common checks out of target specific code into target.c. To achieve this, in this commit, I introduce a new overload of target_can_async_p which takes a target_ops pointer, and calls the ::can_async_p method directly. I then make use of the new overload where appropriate. There should be no user visible changes after this commit.
2021-11-16gdb/gdbsupport: make xstrprintf and xstrvprintf return a unique_ptrAndrew Burgess1-3/+3
The motivation is to reduce the number of places where unmanaged pointers are returned from allocation type routines. All of the callers are updated. There should be no user visible changes after this commit.
2021-10-21gdb, gdbserver: make target_waitstatus safeSimon Marchi1-2/+1
I stumbled on a bug caused by the fact that a code path read target_waitstatus::value::sig (expecting it to contain a gdb_signal value) while target_waitstatus::kind was TARGET_WAITKIND_FORKED. This meant that the active union field was in fact target_waitstatus::value::related_pid, and contained a ptid. The read signal value was therefore garbage, and that caused GDB to crash soon after. Or, since that GDB was built with ubsan, this nice error message: /home/simark/src/binutils-gdb/gdb/linux-nat.c:1271:12: runtime error: load of value 2686365, which is not a valid value for type 'gdb_signal' Despite being a large-ish change, I think it would be nice to make target_waitstatus safe against that kind of bug. As already done elsewhere (e.g. dynamic_prop), validate that the type of value read from the union matches what is supposed to be the active field. - Make the kind and value of target_waitstatus private. - Make the kind initialized to TARGET_WAITKIND_IGNORE on target_waitstatus construction. This is what most users appear to do explicitly. - Add setters, one for each kind. Each setter takes as a parameter the data associated to that kind, if any. This makes it impossible to forget to attach the associated data. - Add getters, one for each associated data type. Each getter validates that the data type fetched by the user matches the wait status kind. - Change "integer" to "exit_status", "related_pid" to "child_ptid", just because that's more precise terminology. - Fix all users. That last point is semi-mechanical. There are a lot of obvious changes, but some less obvious ones. For example, it's not possible to set the kind at some point and the associated data later, as some users did. But in any case, the intent of the code should not change in this patch. This was tested on x86-64 Linux (unix, native-gdbserver and native-extended-gdbserver boards). It was built-tested on x86-64 FreeBSD, NetBSD, MinGW and macOS. The rest of the changes to native files was done as a best effort. If I forgot any place to update in these files, it should be easy to fix (unless the change happens to reveal an actual bug). Change-Id: I0ae967df1ff6e28de78abbe3ac9b4b2ff4ad03b7
2021-09-23Change get_ada_task_ptid parameter typeTom Tromey1-3/+3
get_ada_task_ptid currently takes a 'long' as its 'thread' parameter type. However, on some platforms this is actually a pointer, and using 'long' can sometimes end up with the value being sign-extended. This sign extension can cause problems later, if the tid is then later used as an address again. This patch changes the parameter type to ULONGEST and updates all the uses. This approach preserves sign extension on the targets where it is apparently intended, while avoiding it on others. Co-Authored-By: John Baldwin <jhb@FreeBSD.org>
2021-09-07gdb: make thread_info::executing privateAndrew Burgess1-1/+1
Rename thread_info::executing to thread_info::m_executing, and make it private. Add a new get/set member functions, and convert GDB to make use of these. The only real change of interest in this patch is in thread.c where I have deleted the helper function set_executing_thread, and now just use the new set function thread_info::set_executing. However, the old helper function set_executing_thread included some code to reset the thread's stop_pc, so I moved this code into the new function thread_info::set_executing. However, I don't believe there is anywhere that this results in a change of behaviour, previously the executing flag was always set true through a call to set_executing_thread anyway.
2021-08-03gdb: follow-fork: push target and add thread in target_follow_forkSimon Marchi1-6/+18
In the context of ROCm-gdb [1], the ROCm target sits on top of the linux-nat target. when a process forks, it needs to carry over some data from the forking inferior to the fork child inferior. Ideally, the ROCm target would implement the follow_fork target_ops method, but there are some small problems. This patch fixes these, which helps the ROCm target, but also makes things more consistent and a bit nicer in general, I believe. The main problem is: when follow-fork-mode is "parent", target_follow_fork is called with the parent as the current inferior. When it's "child", target_follow_fork is called with the child as the current inferior. This means that target_follow_fork is sometimes called on the parent's target stack and sometimes on the child's target stack. The parent's target stack may contain targets above the process target, such as the ROCm target. So if follow-fork-child is "parent", the ROCm target would get notified of the fork and do whatever is needed. But the child's target stack, at that moment, only contains the exec and process target copied over from the parent. The child's target stack is set up by follow_fork_inferior, before calling target_follow_fork. In that case, the ROCm target wouldn't get notified of the fork. For consistency, I think it would be good to always call target_follow_fork on the parent inferior's target stack. I think it makes sense as a way to indicate "this inferior has called fork, do whatever is needed". The desired outcome of the fork (whether an inferior is created for the child, do we need to detach from the child) can be indicated by passed parameter. I therefore propose these changes: - make follow_fork_inferior always call target_follow_fork with the parent as the current inferior. That lets all targets present on the parent's target stack do some fork-related handling and push themselves on the fork child's target stack if needed. For this purpose, pass the child inferior down to target_follow_fork and follow_fork implementations. This is nullptr if no inferior is created for the child, because we want to detach from it. - as a result, in follow_fork_inferior, detach from the parent inferior (if needed) only after the target_follow_fork call. This is needed because we want to call target_follow_fork before the parent's target stack is torn down. - hand over to the targets in the parent's target stack (including the process target) the responsibility to push themselves, if needed, to the child's target stack. Also hand over the responsibility to the process target, at the same time, to create the child's initial thread (just like we do for follow_exec). - pass the child inferior to exec_on_vfork, so we don't need to swap the current inferior between parent and child. Nothing in exec_on_vfork depends on the current inferior, after this change. Although this could perhaps be replaced with just having the exec target implement follow_fork and push itself in the child's target stack, like the process target does... We would just need to make sure the process target calls beneath()->follow_fork(...). I'm not sure about this one. gdb/ChangeLog: * target.h (struct target_ops) <follow_fork>: Add inferior* parameter. (target_follow_fork): Likewise. * target.c (default_follow_fork): Likewise. (target_follow_fork): Likewise. * fbsd-nat.h (class fbsd_nat_target) <follow_fork>: Likewise. (fbsd_nat_target::follow_fork): Likewise, and call inf_ptrace_target::follow_fork. * linux-nat.h (class linux_nat_target) <follow_fork>: Likewise. * linux-nat.c (linux_nat_target::follow_fork): Likewise, and call inf_ptrace_target::follow_fork. * obsd-nat.h (obsd_nat_target) <follow_fork>: Likewise. * obsd-nat.c (obsd_nat_target::follow_fork): Likewise, and call inf_ptrace_target::follow_fork. * remote.c (class remote_target) <follow_fork>: Likewise. (remote_target::follow_fork): Likewise, and call process_stratum_target::follow_fork. * process-stratum-target.h (class process_stratum_target) <follow_fork>: New. * process-stratum-target.c (process_stratum_target::follow_fork): New. * target-delegates.c: Re-generate. [1] https://github.com/ROCm-Developer-Tools/ROCgdb Change-Id: I460bd0af850f0485e8aed4b24c6d8262a4c69929
2021-07-23gdb: remove cmd_list_element::function::sfuncSimon Marchi1-2/+2
I don't understand what the sfunc function type in cmd_list_element::function is for. Compared to cmd_simple_func_ftype, it has an extra cmd_list_element parameter, giving the callback access to the cmd_list_element for the command being invoked. This allows registering the same callback with many commands, and alter the behavior using the cmd_list_element's context. From the comment in cmd_list_element, it sounds like at some point it was the callback function type for set and show functions, hence the "s". But nowadays, it's used for many more commands that need to access the cmd_list_element object (see add_catch_command for example). I don't really see the point of having sfunc at all, since do_sfunc is just a trivial shim that changes the order of the arguments. All commands using sfunc could just as well set cmd_list_element::func to their callback directly. Therefore, remove the sfunc field in cmd_list_element and everything that goes with it. Rename cmd_const_sfunc_ftype to cmd_func_ftype and use it for cmd_list_element::func, as well as for the add_setshow commands. Change-Id: I1eb96326c9b511c293c76996cea0ebc51c70fac0
2021-07-14gdb: pass child_ptid and fork kind to target_ops::follow_forkSimon Marchi1-3/+5
This is a small cleanup I think would be nice, that I spotted while doing the following patch. gdb/ChangeLog: * target.h (struct target_ops) <follow_fork>: Add ptid and target_waitkind parameters. (target_follow_fork): Likewise. * target.c (default_follow_fork): Likewise. (target_follow_fork): Likewise. * fbsd-nat.h (class fbsd_nat_target) <follow_fork>: Likewise. * fbsd-nat.c (fbsd_nat_target::follow_fork): Likewise. * linux-nat.h (class linux_nat_target) <follow_fork>: Likewise. * linux-nat.c (linux_nat_target::follow_fork): Likewise. * obsd-nat.h (class obsd_nat_target) <follow_fork>: Likewise. * obsd-nat.c (obsd_nat_target::follow_fork): Likewise. * remote.c (class remote_target) <follow_fork>: Likewise. * target-debug.h (target_debug_print_target_waitkind): New. * target-delegates.c: Re-generate. Change-Id: I5421a542f2e19100a22b74cc333d2b235d0de3c8
2021-07-13Fix detach with target remote (PR gdb/28080)Pedro Alves1-6/+2
Commit 408f66864a1a823591b26420410c982174c239a2 ("detach in all-stop with threads running") regressed "detach" with "target remote": (gdb) detach Detaching from program: target:/any/program, process 3671843 Detaching from process 3671843 Ending remote debugging. [Inferior 1 (process 3671843) detached] In main terminate called after throwing an instance of 'gdb_exception_error' Aborted (core dumped) Here's the exception above being thrown: (top-gdb) bt #0 throw_error (error=TARGET_CLOSE_ERROR, fmt=0x555556035588 "Remote connection closed") at src/gdbsupport/common-exceptions.cc:222 #1 0x0000555555bbaa46 in remote_target::readchar (this=0x555556a11040, timeout=10000) at src/gdb/remote.c:9440 #2 0x0000555555bbb9e5 in remote_target::getpkt_or_notif_sane_1 (this=0x555556a11040, buf=0x555556a11058, forever=0, expecting_notif=0, is_notif=0x0) at src/gdb/remote.c:9928 #3 0x0000555555bbbda9 in remote_target::getpkt_sane (this=0x555556a11040, buf=0x555556a11058, forever=0) at src/gdb/remote.c:10030 #4 0x0000555555bc0e75 in remote_target::remote_hostio_send_command (this=0x555556a11040, command_bytes=13, which_packet=14, remote_errno=0x7fffffffcfd0, attachment=0x0, attachment_len=0x0) at src/gdb/remote.c:12137 #5 0x0000555555bc1b6c in remote_target::remote_hostio_close (this=0x555556a11040, fd=8, remote_errno=0x7fffffffcfd0) at src/gdb/remote.c:12455 #6 0x0000555555bc1bb4 in remote_target::fileio_close (During symbol reading: .debug_line address at offset 0x64f417 is 0 [in module build/gdb/gdb] this=0x555556a11040, fd=8, remote_errno=0x7fffffffcfd0) at src/gdb/remote.c:12462 #7 0x0000555555c9274c in target_fileio_close (fd=3, target_errno=0x7fffffffcfd0) at src/gdb/target.c:3365 #8 0x000055555595a19d in gdb_bfd_iovec_fileio_close (abfd=0x555556b9f8a0, stream=0x555556b11530) at src/gdb/gdb_bfd.c:439 #9 0x0000555555e09e3f in opncls_bclose (abfd=0x555556b9f8a0) at src/bfd/opncls.c:599 #10 0x0000555555e0a2c7 in bfd_close_all_done (abfd=0x555556b9f8a0) at src/bfd/opncls.c:847 #11 0x0000555555e0a27a in bfd_close (abfd=0x555556b9f8a0) at src/bfd/opncls.c:814 #12 0x000055555595a9d3 in gdb_bfd_close_or_warn (abfd=0x555556b9f8a0) at src/gdb/gdb_bfd.c:626 #13 0x000055555595ad29 in gdb_bfd_unref (abfd=0x555556b9f8a0) at src/gdb/gdb_bfd.c:715 #14 0x0000555555ae4730 in objfile::~objfile (this=0x555556515540, __in_chrg=<optimized out>) at src/gdb/objfiles.c:573 #15 0x0000555555ae955a in std::_Sp_counted_ptr<objfile*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x555556c20db0) at /usr/include/c++/9/bits/shared_ptr_base.h:377 #16 0x000055555572b7c8 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x555556c20db0) at /usr/include/c++/9/bits/shared_ptr_base.h:155 #17 0x00005555557263c3 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x555556bf0588, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:730 #18 0x0000555555ae745e in std::__shared_ptr<objfile, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x555556bf0580, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:1169 #19 0x0000555555ae747e in std::shared_ptr<objfile>::~shared_ptr (this=0x555556bf0580, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr.h:103 #20 0x0000555555b1c1dc in __gnu_cxx::new_allocator<std::_List_node<std::shared_ptr<objfile> > >::destroy<std::shared_ptr<objfile> > (this=0x5555564cdd60, __p=0x555556bf0580) at /usr/include/c++/9/ext/new_allocator.h:153 #21 0x0000555555b1bb1d in std::allocator_traits<std::allocator<std::_List_node<std::shared_ptr<objfile> > > >::destroy<std::shared_ptr<objfile> > (__a=..., __p=0x555556bf0580) at /usr/include/c++/9/bits/alloc_traits.h:497 #22 0x0000555555b1b73e in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::_M_erase (this=0x5555564cdd60, __position=std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x555556515540}) at /usr/include/c++/9/bits/stl_list.h:1921 #23 0x0000555555b1afeb in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::erase (this=0x5555564cdd60, __position=std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x555556515540}) at /usr/include/c++/9/bits/list.tcc:158 #24 0x0000555555b19576 in program_space::remove_objfile (this=0x5555564cdd20, objfile=0x555556515540) at src/gdb/progspace.c:210 #25 0x0000555555ae4502 in objfile::unlink (this=0x555556515540) at src/gdb/objfiles.c:487 #26 0x0000555555ae5a12 in objfile_purge_solibs () at src/gdb/objfiles.c:875 #27 0x0000555555c09686 in no_shared_libraries (ignored=0x0, from_tty=1) at src/gdb/solib.c:1236 #28 0x00005555559e3f5f in detach_command (args=0x0, from_tty=1) at src/gdb/infcmd.c:2769 So frame #28 already detached the remote process, and then we're purging the shared libraries. GDB had opened remote shared libraries via the target: sysroot, so it tries closing them. GDBserver is tearing down already, so remote communication breaks down and we close the remote target and throw TARGET_CLOSE_ERROR. Note frame #14: #14 0x0000555555ae4730 in objfile::~objfile (this=0x555556515540, __in_chrg=<optimized out>) at src/gdb/objfiles.c:573 That's a dtor, thus noexcept. That's the reason for the std::terminate. Stepping back a bit, why do we still have open remote files if we've managed to detach already, and, we're debugging with "target remote"? The reason is that commit 408f66864a1a823591b26420410c982174c239a2 makes detach_command hold a reference to the target, so the remote target won't be finally closed until frame #28 returns. It's closing the target that invalidates target file I/O handles. This commit fixes the issue by not relying on target_close to invalidate the target file I/O handles, instead invalidate them immediately in remote_unpush_target. So when GDB purges the solibs, and we end up in target_fileio_close (frame #7 above), there's nothing to do, and we don't try to talk with the remote target anymore. The regression isn't seen when testing with --target_board=native-gdbserver, because that does "set sysroot" to disable the "target:" sysroot, for test run speed reasons. So this commit adds a testcase that explicitly tests detach with "set sysroot target:". gdb/ChangeLog: yyyy-mm-dd Pedro Alves <pedro@palves.net> PR gdb/28080 * remote.c (remote_unpush_target): Invalidate file I/O target handles. * target.c (fileio_handles_invalidate_target): Make extern. * target.h (fileio_handles_invalidate_target): Declare. gdb/testsuite/ChangeLog: yyyy-mm-dd Pedro Alves <pedro@palves.net> PR gdb/28080 * gdb.base/detach-sysroot-target.exp: New. * gdb.base/detach-sysroot-target.c: New. Reported-By: Jonah Graham <jonah@kichwacoders.com> Change-Id: I851234910172f42a1b30e731161376c344d2727d
2021-06-25gdb: add context getter/setter to cmd_list_elementSimon Marchi1-3/+4
Straightforward replacement of get_cmd_context / set_cmd_context with cmd_list_element methods. gdb/ChangeLog: * cli/cli-decode.h (struct cmd_list_element) <set_context, context>: New. <context>: Rename to... <m_context>: ... this. * cli/cli-decode.c (set_cmd_context, get_cmd_context): Remove. * command.h (set_cmd_context, get_cmd_context): Remove, use cmd_list_element::set_context and cmd_list_element::context everywhere instead. Change-Id: I5016b0079014e3f17d1aa449ada7954473bf2b5d
2021-05-13gdb: on exec, delegate pushing / unpushing target and adding thread to ↵Simon Marchi1-3/+5
target_ops::follow_exec On "exec", some targets need to unpush themselves from the inferior, and do some bookkeeping, like forgetting the data associated to the exec'ing inferior. One such example is the thread-db target. It does so in a special case in thread_db_target::wait, just before returning the TARGET_WAITKIND_EXECD event to its caller. We have another such case in the context of rocm-gdb [1], where the "rocm" target is pushed on top of the linux-nat target. When an exec happens, we want to unpush the rocm target from the exec'ing inferior to close some file descriptors that refer to the pre-exec address space and forget about that inferior. We then want to push the target on the inferior in which execution continues, to open the file descriptors for the post-exec address space. I think that a good way to address this cleanly is to do all this in the target_ops::follow_exec implementations. Make the process_stratum_target::follow_exec implementation have the default behavior of pushing itself to the new inferior's target stack (if execution continues in a new inferior) and add the initial thread. remote_target::follow_exec is an example of process target that wants to do a bit more than the default behavior. So it calls process_stratum_target::follow_exec first and does the extra work second. linux-thread-db (a non-process target) implements follow_exec to do some bookeeping (forget about that process' data), before handing down the event down to the process target (which hits process_stratum_target::follow_exec). gdb/ChangeLog: * target.h (struct target_ops) <follow_exec>: Add ptid_t parameter. (target_follow_exec): Likewise. * target.c (target_follow_exec): Add ptid_t parameter. * infrun.c (follow_exec): Adjust call to target_follow_exec, don't push target nor create thread. * linux-thread-db.c (class thread_db_target) <follow_exec>: New. (thread_db_target::wait): Just return on TARGET_WAITKIND_EXECD. (thread_db_target::follow_exec): New. * remote.c (class remote_target) <follow_exec>: Add ptid_t parameter. (remote_target::follow_exec): Call process_stratum_target::follow_exec. * target-delegates.c: Re-generate. Change-Id: I3f96d0ba3ea0dde6540b7e1b4d5cdb01635088c8
2021-05-12gdb: generate the prefix name for prefix commands on demandMarco Barisione1-1/+1
Previously, the prefixname field of struct cmd_list_element was manually set for prefix commands. This seems verbose and error prone as it required every single call to functions adding prefix commands to specify the prefix name while the same information can be easily generated. Historically, this was not possible as the prefix field was null for many commands, but this was fixed in commit 3f4d92ebdf7f848b5ccc9e8d8e8514c64fde1183 by Philippe Waroquiers, so we can rely on the prefix field being set when generating the prefix name. This commit also fixes a use after free in this scenario: * A command gets created via Python (using the gdb.Command class). The prefix name member is dynamically allocated. * An alias to the new command is created. The alias's prefixname is set to point to the prefixname for the original command with a direct assignment. * A new command with the same name as the Python command is created. * The object for the original Python command gets freed and its prefixname gets freed as well. * The alias is updated to point to the new command, but its prefixname is not updated so it keeps pointing to the freed one. gdb/ChangeLog: * command.h (add_prefix_cmd): Remove the prefixname argument as it can now be generated automatically. Update all callers. (add_basic_prefix_cmd): Ditto. (add_show_prefix_cmd): Ditto. (add_prefix_cmd_suppress_notification): Ditto. (add_abbrev_prefix_cmd): Ditto. * cli/cli-decode.c (add_prefix_cmd): Ditto. (add_basic_prefix_cmd): Ditto. (add_show_prefix_cmd): Ditto. (add_prefix_cmd_suppress_notification): Ditto. (add_prefix_cmd_suppress_notification): Ditto. (add_abbrev_prefix_cmd): Ditto. * cli/cli-decode.h (struct cmd_list_element): Replace the prefixname member variable with a method which generates the prefix name at runtime. Update all code reading the prefix name to use the method, and remove all code setting it. * python/py-cmd.c (cmdpy_destroyer): Remove code to free the prefixname member as it's now a method. (cmdpy_function): Determine if the command is a prefix by looking at prefixlist, not prefixname.
2021-05-07gdb: remove reference to current inferior in target_stack::unpushSimon Marchi1-1/+1
target_stack::unpush needs to get the target beneath the target being unpushed to update the m_top field (which keeps the stratum of the top-most target). It currently does so using target_ops::beneath, which uses the target stack of the current inferior. The target stack of the current inferior is the same as the `this` in the unpush method. Avoid this detour and remove this reference to the current inferior by calling target_ops::find_beneath and passing `this` to find the target beneath `t` in the target stack that is `this`. gdb/ChangeLog: * target.c (target_stack::unpush): Call target_ops::find_beneath to get the target beneath `t`. Change-Id: If9d9661567c5c16f655d270bd2ec9f1b3aa6dadc
2021-05-07gdb: make target_close check that the target isn't pushed in all inferiorsSimon Marchi1-1/+2
The target_close function currently checks that the target to be closed isn't pushed in the current inferior: gdb_assert (!current_inferior ()->target_is_pushed (targ)); Normally, a target is closed when its refcount has dropped to 0, due to not being used in any inferior anymore. I think it would make sense to change that assert to not only check in the current inferior, but to check in all inferiors. It would be quite bad (and a bug) to close a target while it's still pushed in one of the non-current inferiors. gdb/ChangeLog: * target.c (target_close): Check in all inferiors that the target is not pushed. Change-Id: I6e37fc3f3476a0593da1e476604642b2de90f1d5
2021-04-07gdb: make target_ops::follow_fork return voidSimon Marchi1-4/+3
I noticed that all implementations return false, so target_ops::follow_fork doesn't really need to return a value. Change it to return void. gdb/ChangeLog: * target.h (struct target_ops) <follow_fork>: Return void. (target_follow_fork): Likewise. * target.c (default_follow_fork): Likewise. (target_follow_fork): Likewise. * infrun.c (follow_fork_inferior): Adjust. * fbsd-nat.h (class fbsd_nat_target) <follow_fork>: Return void. * fbsd-nat.c (fbsd_nat_target:::follow_fork): Likewise. * linux-nat.h (class linux_nat_target) <follow_fork>: Likewise. * linux-nat.c (linux_nat_target::follow_fork): Return void. * obsd-nat.h (class obsd_nat_target) <follow_fork>: Return void. * obsd-nat.c (obsd_nat_target::follow_fork): Likewise. * remote.c (class remote_target) <follow_fork>: Likewise. (remote_target::follow_fork): Likewise. * target-delegates.c: Re-generate. Change-Id: If908c2f68b29fa275be2b0b9deb41e4c6a1b7879
2021-03-26gdb: defer commit resume until all available events are consumedSimon Marchi1-0/+8
Rationale --------- Let's say you have multiple threads hitting a conditional breakpoint at the same time, and all of these are going to evaluate to false. All these threads will need to be resumed. Currently, GDB fetches one target event (one SIGTRAP representing the breakpoint hit) and decides that the thread should be resumed. It calls resume and commit_resume immediately. It then fetches the second target event, and does the same, until it went through all threads. The result is therefore something like: - consume event for thread A - resume thread A - commit resume (affects thread A) - consume event for thread B - resume thread B - commit resume (affects thread B) - consume event for thread C - resume thread C - commit resume (affects thread C) For targets where it's beneficial to group resumptions requests (most likely those that implement target_ops::commit_resume), it would be much better to have: - consume event for thread A - resume thread A - consume event for thread B - resume thread B - consume event for thread C - resume thread C - commit resume (affects threads A, B and C) Implementation details ---------------------- To achieve this, this patch adds another check in maybe_set_commit_resumed_all_targets to avoid setting the commit-resumed flag of targets that readily have events to provide to infrun. To determine if a target has events readily available to report, this patch adds an `has_pending_events` target_ops method. The method returns a simple bool to say whether or not it has pending events to report. Testing ======= To test this, I start GDBserver with a program that spawns multiple threads: $ ../gdbserver/gdbserver --once :1234 ~/src/many-threads-stepping-over-breakpoints/many-threads-stepping-over-breakpoints I then connect with GDB and install a conditional breakpoint that always evaluates to false (and force the evaluation to be done by GDB): $ ./gdb -nx --data-directory=data-directory \ /home/simark/src/many-threads-stepping-over-breakpoints/many-threads-stepping-over-breakpoints \ -ex "set breakpoint condition-evaluation host" \ -ex "set pag off" \ -ex "set confirm off" \ -ex "maint set target-non-stop on" \ -ex "tar rem :1234" \ -ex "tb main" \ -ex "b 13 if 0" \ -ex c \ -ex "set debug infrun" \ -ex "set debug remote 1" \ -ex "set debug displaced" I then do "continue" and look at the log. The remote target receives a bunch of stop notifications for all threads that have hit the breakpoint. infrun consumes and processes one event, decides it should not cause a stop, prepares a displaced step, after which we should see: [infrun] maybe_set_commit_resumed_all_process_targets: not requesting commit-resumed for target remote, target has pending events Same for a second thread (since we have 2 displaced step buffers). For the following threads, their displaced step is deferred since there are no more buffers available. After consuming the last event the remote target has to offer, we get: [infrun] maybe_set_commit_resumed_all_process_targets: enabling commit-resumed for target remote [infrun] maybe_call_commit_resumed_all_process_targets: calling commit_resumed for target remote [remote] Sending packet: $vCont;s:p14d16b.14d1b1;s:p14d16b.14d1b2#55 [remote] Packet received: OK Without the patch, there would have been one vCont;s just after each prepared displaced step. gdb/ChangeLog: yyyy-mm-dd Simon Marchi <simon.marchi@efficios.com> Pedro Alves <pedro@palves.net> * async-event.c (async_event_handler_marked): New. * async-event.h (async_event_handler_marked): Declare. * infrun.c (maybe_set_commit_resumed_all_targets): Switch to inferior before calling target method. Don't commit-resumed if target_has_pending_events is true. * remote.c (remote_target::has_pending_events): New. * target-delegates.c: Regenerate. * target.c (target_has_pending_events): New. * target.h (target_ops::has_pending_events): New target method. (target_has_pending_events): New. Change-Id: I18112ba19a1ff4986530c660f530d847bb4a1f1d
2021-03-26gdb: generalize commit_resume, avoid commit-resuming when threads have ↵Simon Marchi1-16/+11
pending statuses The rationale for this patch comes from the ROCm port [1], the goal being to reduce the number of back and forths between GDB and the target when doing successive operations. I'll start with explaining the rationale and then go over the implementation. In the ROCm / GPU world, the term "wave" is somewhat equivalent to a "thread" in GDB. So if you read if from a GPU stand point, just s/thread/wave/. ROCdbgapi, the library used by GDB [2] to communicate with the GPU target, gives the illusion that it's possible for the debugger to control (start and stop) individual threads. But in reality, this is not how it works. Under the hood, all threads of a queue are controlled as a group. To stop one thread in a group of running ones, the state of all threads is retrieved from the GPU, all threads are destroyed, and all threads but the one we want to stop are re-created from the saved state. The net result, from the point of view of GDB, is that the library stopped one thread. The same thing goes if we want to resume one thread while others are running: the state of all running threads is retrieved from the GPU, they are all destroyed, and they are all re-created, including the thread we want to resume. This leads to some inefficiencies when combined with how GDB works, here are two examples: - Stopping all threads: because the target operates in non-stop mode, when the user interface mode is all-stop, GDB must stop all threads individually when presenting a stop. Let's suppose we have 1000 threads and the user does ^C. GDB asks the target to stop one thread. Behind the scenes, the library retrieves 1000 thread states and restores the 999 others still running ones. GDB asks the target to stop another one. The target retrieves 999 thread states and restores the 998 remaining ones. That means that to stop 1000 threads, we did 1000 back and forths with the GPU. It would have been much better to just retrieve the states once and stop there. - Resuming with pending events: suppose the 1000 threads hit a breakpoint at the same time. The breakpoint is conditional and evaluates to true for the first thread, to false for all others. GDB pulls one event (for the first thread) from the target, decides that it should present a stop, so stops all threads using stop_all_threads. All these other threads have a breakpoint event to report, which is saved in `thread_info::suspend::waitstatus` for later. When the user does "continue", GDB resumes that one thread that did hit the breakpoint. It then processes the pending events one by one as if they just arrived. It picks one, evaluates the condition to false, and resumes the thread. It picks another one, evaluates the condition to false, and resumes the thread. And so on. In between each resumption, there is a full state retrieval and re-creation. It would be much nicer if we could wait a little bit before sending those threads on the GPU, until it processed all those pending events. To address this kind of performance issue, ROCdbgapi has a concept called "forward progress required", which is a boolean state that allows its user (i.e. GDB) to say "I'm doing a bunch of operations, you can hold off putting the threads on the GPU until I'm done" (the "forward progress not required" state). Turning forward progress back on indicates to the library that all threads that are supposed to be running should now be really running on the GPU. It turns out that GDB has a similar concept, though not as general, commit_resume. One difference is that commit_resume is not stateful: the target can't look up "does the core need me to schedule resumed threads for execution right now". It is also specifically linked to the resume method, it is not used in other contexts. The target accumulates resumption requests through target_ops::resume calls, and then commits those resumptions when target_ops::commit_resume is called. The target has no way to check if it's ok to leave resumed threads stopped in other target methods. To bridge the gap, this patch generalizes the commit_resume concept in GDB to match the forward progress concept of ROCdbgapi. The current name (commit_resume) can be interpreted as "commit the previous resume calls". I renamed the concept to "commit_resumed", as in "commit the threads that are resumed". In the new version, we have two things: - the commit_resumed_state field in process_stratum_target: indicates whether GDB requires target stacks using this target to have resumed threads committed to the execution target/device. If false, an execution target is allowed to leave resumed threads un-committed at the end of whatever method it is executing. - the commit_resumed target method: called when commit_resumed_state transitions from false to true. While commit_resumed_state was false, the target may have left some resumed threads un-committed. This method being called tells it that it should commit them back to the execution device. Let's take the "Stopping all threads" scenario from above and see how it would work with the ROCm target with this change. Before stopping all threads, GDB would set the target's commit_resumed_state field to false. It would then ask the target to stop the first thread. The target would retrieve all threads' state from the GPU and mark that one as stopped. Since commit_resumed_state is false, it leaves all the other threads (still resumed) stopped. GDB would then proceed to call target_stop for all the other threads. Since resumed threads are not committed, this doesn't do any back and forth with the GPU. To simplify the implementation of targets, this patch makes it so that when calling certain target methods, the contract between the core and the targets guarantees that commit_resumed_state is false. This way, the target doesn't need two paths, one for commit_resumed_state == true and one for commit_resumed_state == false. It can just assert that commit_resumed_state is false and work with that assumption. This also helps catch places where we forgot to disable commit_resumed_state before calling the method, which represents a probable optimization opportunity. The commit adds assertions in the target method wrappers (target_resume and friends) to have some confidence that this contract between the core and the targets is respected. The scoped_disable_commit_resumed type is used to disable the commit resumed state of all process targets on construction, and selectively re-enable it on destruction (see below for criteria). Note that it only sets the process_stratum_target::commit_resumed_state flag. A subsequent call to maybe_call_commit_resumed_all_targets is necessary to call the commit_resumed method on all target stacks with process targets that got their commit_resumed_state flag turned back on. This separation is because we don't want to call the commit_resumed methods in scoped_disable_commit_resumed's destructor, as they may throw. On destruction, commit-resumed is not re-enabled for a given target if: 1. this target has no threads resumed, or 2. this target has at least one resumed thread with a pending status known to the core (saved in thread_info::suspend::waitstatus). The first point is not technically necessary, because a proper commit_resumed implementation would be a no-op if the target has no resumed threads. But since we have a flag do to a quick check, it shouldn't hurt. The second point is more important: together with the scoped_disable_commit_resumed instance added in fetch_inferior_event, it makes it so the "Resuming with pending events" described above is handled efficiently. Here's what happens in that case: 1. The user types "continue". 2. Upon destruction, the scoped_disable_commit_resumed in the `proceed` function does not enable commit-resumed, as it sees some threads have pending statuses. 3. fetch_inferior_event is called to handle another event, the breakpoint hit evaluates to false, and that thread is resumed. Because there are still more threads with pending statuses, the destructor of scoped_disable_commit_resumed in fetch_inferior_event still doesn't enable commit-resumed. 4. Rinse and repeat step 3, until the last pending status is handled by fetch_inferior_event. In that case, scoped_disable_commit_resumed's destructor sees there are no more threads with pending statues, so it asks the target to commit resumed threads. This allows us to avoid all unnecessary back and forths, there is a single commit_resumed call once all pending statuses are processed. This change required remote_target::remote_stop_ns to learn how to handle stopping threads that were resumed but pending vCont. The simplest example where that happens is when using the remote target in all-stop, but with "maint set target-non-stop on", to force it to operate in non-stop mode under the hood. If two threads hit a breakpoint at the same time, GDB will receive two stop replies. It will present the stop for one thread and save the other one in thread_info::suspend::waitstatus. Before this patch, when doing "continue", GDB first resumes the thread without a pending status: Sending packet: $vCont;c:p172651.172676#f3 It then consumes the pending status in the next fetch_inferior_event call: [infrun] do_target_wait_1: Using pending wait status status->kind = stopped, signal = GDB_SIGNAL_TRAP for Thread 1517137.1517137. [infrun] target_wait (-1.0.0, status) = [infrun] 1517137.1517137.0 [Thread 1517137.1517137], [infrun] status->kind = stopped, signal = GDB_SIGNAL_TRAP It then realizes it needs to stop all threads to present the stop, so stops the thread it just resumed: [infrun] stop_all_threads: Thread 1517137.1517137 not executing [infrun] stop_all_threads: Thread 1517137.1517174 executing, need stop remote_stop called Sending packet: $vCont;t:p172651.172676#04 This is an unnecessary resume/stop. With this patch, we don't commit resumed threads after proceeding, because of the pending status: [infrun] maybe_commit_resumed_all_process_targets: not requesting commit-resumed for target extended-remote, a thread has a pending waitstatus When GDB handles the pending status and stop_all_threads runs, we stop a resumed but pending vCont thread: remote_stop_ns: Enqueueing phony stop reply for thread pending vCont-resume (1520940, 1520976, 0) That thread was never actually resumed on the remote stub / gdbserver, so we shouldn't send a packet to the remote side asking to stop the thread. Note that there are paths that resume the target and then do a synchronous blocking wait, in sort of nested event loop, via wait_sync_command_done. For example, inferior function calls, or any run control command issued from a breakpoint command list. We handle that making wait_sync_command_one a "sync" point -- force forward progress, or IOW, force-enable commit-resumed state. gdb/ChangeLog: yyyy-mm-dd Simon Marchi <simon.marchi@efficios.com> Pedro Alves <pedro@palves.net> * infcmd.c (run_command_1, attach_command, detach_command) (interrupt_target_1): Use scoped_disable_commit_resumed. * infrun.c (do_target_resume): Remove target_commit_resume call. (commit_resume_all_targets): Remove. (maybe_set_commit_resumed_all_targets): New. (maybe_call_commit_resumed_all_targets): New. (enable_commit_resumed): New. (scoped_disable_commit_resumed::scoped_disable_commit_resumed) (scoped_disable_commit_resumed::~scoped_disable_commit_resumed) (scoped_disable_commit_resumed::reset) (scoped_disable_commit_resumed::reset_and_commit) (scoped_enable_commit_resumed::scoped_enable_commit_resumed) (scoped_enable_commit_resumed::~scoped_enable_commit_resumed): New. (proceed): Use scoped_disable_commit_resumed and maybe_call_commit_resumed_all_targets. (fetch_inferior_event): Use scoped_disable_commit_resumed. * infrun.h (struct scoped_disable_commit_resumed): New. (maybe_call_commit_resumed_all_process_targets): New. (struct scoped_enable_commit_resumed): New. * mi/mi-main.c (exec_continue): Use scoped_disable_commit_resumed. * process-stratum-target.h (class process_stratum_target): <commit_resumed_state>: New. * record-full.c (record_full_wait_1): Change commit_resumed_state around calling commit_resumed. * remote.c (class remote_target) <commit_resume>: Rename to... <commit_resumed>: ... this. (struct stop_reply): Move up. (remote_target::commit_resume): Rename to... (remote_target::commit_resumed): ... this. Check if there is any thread pending vCont resume. (remote_target::remote_stop_ns): Generate stop replies for resumed but pending vCont threads. (remote_target::wait_ns): Add gdb_assert. * target-delegates.c: Regenerate. * target.c (target_wait, target_resume): Assert that the current process_stratum target isn't in commit-resumed state. (defer_target_commit_resume): Remove. (target_commit_resume): Remove. (target_commit_resumed): New. (make_scoped_defer_target_commit_resume): Remove. (target_stop): Assert that the current process_stratum target isn't in commit-resumed state. * target.h (struct target_ops) <commit_resume>: Rename to ... <commit_resumed>: ... this. (target_commit_resume): Remove. (target_commit_resumed): New. (make_scoped_defer_target_commit_resume): Remove. * top.c (wait_sync_command_done): Use scoped_enable_commit_resumed. [1] https://github.com/ROCm-Developer-Tools/ROCgdb/ [2] https://github.com/ROCm-Developer-Tools/ROCdbgapi Change-Id: I836135531a29214b21695736deb0a81acf8cf566
2021-03-26target_is_non_stop_p and sync targetsPedro Alves1-4/+5
gdb.base/maint-target-async-off.exp fails if you test against gdbserver with "maint set target-non-stop on" forced. (gdb) run Starting program: build/gdb/testsuite/outputs/gdb.base/maint-target-async-off/maint-target-async-off Breakpoint 1, main () at src/gdb/testsuite/gdb.base/maint-target-async-off.c:21 21 return 0; (gdb) FAIL: gdb.base/maint-target-async-off.exp: continue until exit (timeout) Above, GDB just stopped listening to stdin. Basically, GDB assumes that a target working in non-stop mode operation also supports async mode; it's a requirement. GDB misbehaves badly otherwise, and even hits failed assertions. Fix this by making target_is_non_stop_p return false if async is off. gdb/ChangeLog: * target.c (target_always_non_stop_p): Also check whether the target can async. Change-Id: I7e52e1061396a5b9b02ada462f68a14b76d68974
2021-03-24gdb: remove current_top_target functionSimon Marchi1-193/+275
The current_top_target function is a hidden dependency on the current inferior. Since I'd like to slowly move towards reducing our dependency on the global current state, remove this function and make callers use current_inferior ()->top_target () There is no expected change in behavior, but this one step towards making those callers use the inferior from their context, rather than refer to the global current inferior. gdb/ChangeLog: * target.h (current_top_target): Remove, make callers use the current inferior instead. * target.c (current_top_target): Remove. Change-Id: Iccd457036f84466cdaa3865aa3f9339a24ea001d
2021-03-24gdb: move all "current target" wrapper implementations to target.cSimon Marchi1-0/+578
The following patch removes the current_top_target function, replacing uses with `current_inferior ()->top_target ()`. This is a problem for uses in target.h, because they don't have access to the current_inferior function and the inferior structure: target.h can't include inferior.h, otherwise that would make a cyclic inclusion. Avoid this by moving all implementations of the wrappers that call target methods with the current target to target.c. Many of them are changed from a macro to a function, which is an improvement for readability and debuggability, IMO. target_shortname and target_longname were not function-like macros, so a few adjustments are needed. gdb/ChangeLog: * target.h (target_shortname): Change to function declaration. (target_longname): Likewise. (target_attach_no_wait): Likewise. (target_post_attach): Likewise. (target_prepare_to_store): Likewise. (target_supports_enable_disable_tracepoint): Likewise. (target_supports_string_tracing): Likewise. (target_supports_evaluation_of_breakpoint_conditions): Likewise. (target_supports_dumpcore): Likewise. (target_dumpcore): Likewise. (target_can_run_breakpoint_commands): Likewise. (target_files_info): Likewise. (target_post_startup_inferior): Likewise. (target_insert_fork_catchpoint): Likewise. (target_remove_fork_catchpoint): Likewise. (target_insert_vfork_catchpoint): Likewise. (target_remove_vfork_catchpoint): Likewise. (target_insert_exec_catchpoint): Likewise. (target_remove_exec_catchpoint): Likewise. (target_set_syscall_catchpoint): Likewise. (target_rcmd): Likewise. (target_can_lock_scheduler): Likewise. (target_can_async_p): Likewise. (target_is_async_p): Likewise. (target_execution_direction): Likewise. (target_extra_thread_info): Likewise. (target_pid_to_exec_file): Likewise. (target_thread_architecture): Likewise. (target_find_memory_regions): Likewise. (target_make_corefile_notes): Likewise. (target_get_bookmark): Likewise. (target_goto_bookmark): Likewise. (target_stopped_by_watchpoint): Likewise. (target_stopped_by_sw_breakpoint): Likewise. (target_supports_stopped_by_sw_breakpoint): Likewise. (target_stopped_by_hw_breakpoint): Likewise. (target_supports_stopped_by_hw_breakpoint): Likewise. (target_have_steppable_watchpoint): Likewise. (target_can_use_hardware_watchpoint): Likewise. (target_region_ok_for_hw_watchpoint): Likewise. (target_can_do_single_step): Likewise. (target_insert_watchpoint): Likewise. (target_remove_watchpoint): Likewise. (target_insert_hw_breakpoint): Likewise. (target_remove_hw_breakpoint): Likewise. (target_can_accel_watchpoint_condition): Likewise. (target_can_execute_reverse): Likewise. (target_get_ada_task_ptid): Likewise. (target_filesystem_is_local): Likewise. (target_trace_init): Likewise. (target_download_tracepoint): Likewise. (target_can_download_tracepoint): Likewise. (target_download_trace_state_variable): Likewise. (target_enable_tracepoint): Likewise. (target_disable_tracepoint): Likewise. (target_trace_start): Likewise. (target_trace_set_readonly_regions): Likewise. (target_get_trace_status): Likewise. (target_get_tracepoint_status): Likewise. (target_trace_stop): Likewise. (target_trace_find): Likewise. (target_get_trace_state_variable_value): Likewise. (target_save_trace_data): Likewise. (target_upload_tracepoints): Likewise. (target_upload_trace_state_variables): Likewise. (target_get_raw_trace_data): Likewise. (target_get_min_fast_tracepoint_insn_len): Likewise. (target_set_disconnected_tracing): Likewise. (target_set_circular_trace_buffer): Likewise. (target_set_trace_buffer_size): Likewise. (target_set_trace_notes): Likewise. (target_get_tib_address): Likewise. (target_set_permissions): Likewise. (target_static_tracepoint_marker_at): Likewise. (target_static_tracepoint_markers_by_strid): Likewise. (target_traceframe_info): Likewise. (target_use_agent): Likewise. (target_can_use_agent): Likewise. (target_augmented_libraries_svr4_read): Likewise. (target_log_command): Likewise. * target.c (target_shortname): New. (target_longname): New. (target_attach_no_wait): New. (target_post_attach): New. (target_prepare_to_store): New. (target_supports_enable_disable_tracepoint): New. (target_supports_string_tracing): New. (target_supports_evaluation_of_breakpoint_conditions): New. (target_supports_dumpcore): New. (target_dumpcore): New. (target_can_run_breakpoint_commands): New. (target_files_info): New. (target_post_startup_inferior): New. (target_insert_fork_catchpoint): New. (target_remove_fork_catchpoint): New. (target_insert_vfork_catchpoint): New. (target_remove_vfork_catchpoint): New. (target_insert_exec_catchpoint): New. (target_remove_exec_catchpoint): New. (target_set_syscall_catchpoint): New. (target_rcmd): New. (target_can_lock_scheduler): New. (target_can_async_p): New. (target_is_async_p): New. (target_execution_direction): New. (target_extra_thread_info): New. (target_pid_to_exec_file): New. (target_thread_architecture): New. (target_find_memory_regions): New. (target_make_corefile_notes): New. (target_get_bookmark): New. (target_goto_bookmark): New. (target_stopped_by_watchpoint): New. (target_stopped_by_sw_breakpoint): New. (target_supports_stopped_by_sw_breakpoint): New. (target_stopped_by_hw_breakpoint): New. (target_supports_stopped_by_hw_breakpoint): New. (target_have_steppable_watchpoint): New. (target_can_use_hardware_watchpoint): New. (target_region_ok_for_hw_watchpoint): New. (target_can_do_single_step): New. (target_insert_watchpoint): New. (target_remove_watchpoint): New. (target_insert_hw_breakpoint): New. (target_remove_hw_breakpoint): New. (target_can_accel_watchpoint_condition): New. (target_can_execute_reverse): New. (target_get_ada_task_ptid): New. (target_filesystem_is_local): New. (target_trace_init): New. (target_download_tracepoint): New. (target_can_download_tracepoint): New. (target_download_trace_state_variable): New. (target_enable_tracepoint): New. (target_disable_tracepoint): New. (target_trace_start): New. (target_trace_set_readonly_regions): New. (target_get_trace_status): New. (target_get_tracepoint_status): New. (target_trace_stop): New. (target_trace_find): New. (target_get_trace_state_variable_value): New. (target_save_trace_data): New. (target_upload_tracepoints): New. (target_upload_trace_state_variables): New. (target_get_raw_trace_data): New. (target_get_min_fast_tracepoint_insn_len): New. (target_set_disconnected_tracing): New. (target_set_circular_trace_buffer): New. (target_set_trace_buffer_size): New. (target_set_trace_notes): New. (target_get_tib_address): New. (target_set_permissions): New. (target_static_tracepoint_marker_at): New. (target_static_tracepoint_markers_by_strid): New. (target_traceframe_info): New. (target_use_agent): New. (target_can_use_agent): New. (target_augmented_libraries_svr4_read): New. (target_log_command): New. * bfin-tdep.c (bfin_sw_breakpoint_from_kind): Adjust. * infrun.c (set_schedlock_func): Adjust. * mi/mi-main.c (exec_reverse_continue): Adjust. * reverse.c (exec_reverse_once): Adjust. * sh-tdep.c (sh_sw_breakpoint_from_kind): Adjust. * tui/tui-stack.c (tui_locator_window::make_status_line): Adjust. * remote-sim.c (gdbsim_target::detach): Adjust. (gdbsim_target::files_info): Adjust. Change-Id: I72ef56e9a25adeb0b91f1ad05e34c89f77ebeaa8
2021-03-23gdb: remove target_is_pushed free functionSimon Marchi1-10/+1
Same principle as the previous patches. gdb/ChangeLog: * target.h (target_is_pushed): Remove, update callers to use inferior::target_is_pushed instead. * target.c (target_is_pushed): Remove. Change-Id: I9862e6205acc65672da807cbe4b46cde009e7b9d
2021-03-23gdb: remove push_target free functionsSimon Marchi1-18/+1
Same as the previous patch, but for the push_target functions. The implementation of the move variant is moved to a new overload of inferior::push_target. gdb/ChangeLog: * target.h (push_target): Remove, update callers to use inferior::push_target. * target.c (push_target): Remove. * inferior.h (class inferior) <push_target>: New overload. Change-Id: I5a95496666278b8f3965e5e8aecb76f54a97c185
2021-03-23gdb: remove unpush_target free functionSimon Marchi1-10/+8
unpush_target unpushes the passed-in target from the current inferior's target stack. Calling it is therefore an implicit dependency on the current global inferior. Remove that function and make the callers use the inferior::unpush_target method directly. This sometimes allows using the inferior from the context rather than the global current inferior. target_unpusher::operator() now needs to be implemented in target.c, otherwise target.h and inferior.h both need to include each other, and that wouldn't work. gdb/ChangeLog: * target.h (unpush_target): Remove, update all callers to use `inferior::unpush_target` instead. (struct target_unpusher) <operator()>: Just declare. * target.c (unpush_target): Remove. (target_unpusher::operator()): New. Change-Id: Ia5172dfb3f373e0a75b991885b50322ca2142a8c