aboutsummaryrefslogtreecommitdiff
path: root/gdb/breakpoint.c
AgeCommit message (Collapse)AuthorFilesLines
2023-12-13Use unique_xmalloc_ptr in explicit_location_specTom Tromey1-3/+2
This changes explicit_location_spec to use unique_xmalloc_ptr, removing some manual memory management. Reviewed-By: John Baldwin <jhb@FreeBSD.org>
2023-12-13Use unique_xmalloc_ptr in linespec_location_specTom Tromey1-4/+5
This changes linespec_location_spec to use unique_xmalloc_ptr, removing some manual memory management. Reviewed-By: John Baldwin <jhb@FreeBSD.org>
2023-11-28[gdb] Fix segfault in for_each_block, part 1Tom de Vries1-13/+16
When running test-case gdb.base/vfork-follow-parent.exp on powerpc64 (likewise on s390x), I run into: ... (gdb) PASS: gdb.base/vfork-follow-parent.exp: \ exec_file=vfork-follow-parent-exit: target-non-stop=on: non-stop=off: \ resolution_method=schedule-multiple: print unblock_parent = 1 continue^M Continuing.^M Reading symbols from vfork-follow-parent-exit...^M ^M ^M Fatal signal: Segmentation fault^M ----- Backtrace -----^M 0x1027d3e7 gdb_internal_backtrace_1^M src/gdb/bt-utils.c:122^M 0x1027d54f _Z22gdb_internal_backtracev^M src/gdb/bt-utils.c:168^M 0x1057643f handle_fatal_signal^M src/gdb/event-top.c:889^M 0x10576677 handle_sigsegv^M src/gdb/event-top.c:962^M 0x3fffa7610477 ???^M 0x103f2144 for_each_block^M src/gdb/dcache.c:199^M 0x103f235b _Z17dcache_invalidateP13dcache_struct^M src/gdb/dcache.c:251^M 0x10bde8c7 _Z24target_dcache_invalidatev^M src/gdb/target-dcache.c:50^M ... or similar. The root cause for the segmentation fault is that linux_is_uclinux gives an incorrect result: it should always return false, given that we're running on a regular linux system, but instead it returns first true, then false. In more detail, the segmentation fault happens as follows: - a program space with an address space is created - a second program space is about to be created. maybe_new_address_space is called, and because linux_is_uclinux returns true, maybe_new_address_space returns false, and no new address space is created - a second program space with the same address space is created - a program space is deleted. Because linux_is_uclinux now returns false, gdbarch_has_shared_address_space (current_inferior ()->arch ()) returns false, and the address space is deleted - when gdb uses the address space of the remaining program space, we run into the segfault, because the address space is deleted. Hardcoding linux_is_uclinux to false makes the test-case pass. We leave addressing the root cause for the following commit in this series. For now, prevent the segmentation fault by making the address space a refcounted object. This was already suggested here [1]: ... A better solution might be to have the address spaces be reference counted ... Tested on top of trunk on x86_64-linux and ppc64le-linux. Tested on top of gdb-14-branch on ppc64-linux. Co-Authored-By: Simon Marchi <simon.marchi@polymtl.ca> PR gdb/30547 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30547 [1] https://sourceware.org/pipermail/gdb-patches/2023-October/202928.html
2023-11-21gdb: Replace gdb::optional with std::optionalLancelot Six1-9/+10
Since GDB now requires C++17, we don't need the internally maintained gdb::optional implementation. This patch does the following replacing: - gdb::optional -> std::optional - gdb::in_place -> std::in_place - #include "gdbsupport/gdb_optional.h" -> #include <optional> This change has mostly been done automatically. One exception is gdbsupport/thread-pool.* which did not use the gdb:: prefix as it already lives in the gdb namespace. Change-Id: I19a92fa03e89637bab136c72e34fd351524f65e9 Approved-By: Tom Tromey <tom@tromey.com> Approved-By: Pedro Alves <pedro@palves.net>
2023-11-17gdb: remove get_current_regcacheSimon Marchi1-1/+1
Remove get_current_regcache, inlining the call to get_thread_regcache in callers. When possible, pass the right thread_info object known from the local context. Otherwise, fall back to passing `inferior_thread ()`. This makes the reference to global context bubble up one level, a small step towards the long term goal of reducing the number of references to global context (or rather, moving those references as close as possible to the top of the call tree). No behavior change expected. Change-Id: Ifa6980c88825d803ea586546b6b4c633c33be8d6
2023-11-14Remove some redundant "break"sTom Tromey1-4/+0
I found some "break" statements that follow "return" or a call to a noreturn function. These aren't needed, and the compiler would warn if they were. So, this patch removes them. Tested by rebuilding.
2023-10-30Remove some frame invalidation codeTom Tromey1-3/+0
I stumbled across a few spots that mention that a function "invalidates frame" and also assignments of NULL to a frame_info_ptr. This code isn't harmful, but is also unnecessary since the introduction of frame_info_ptr -- nowadays frame invalidations are handled automatically. Regression tested on x86-64 Fedora 38. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-10-19gdb: rename struct so_list to shobjSimon Marchi1-3/+2
Now that so_list lists are implemented using intrusive_list, it doesn't really make sense for the element type to be named "_list". Rename to just `struct shobj` (`struct so` was deemed to be not greppable enough). Change-Id: I1063061901298bb40fee73bf0cce44cd12154c0e Approved-By: Pedro Alves <pedro@palves.net> Reviewed-By: Reviewed-By: Lancelot Six <lancelot.six@amd.com>
2023-10-19gdb: make so_list::{so_original_name,so_name} std::stringsSimon Marchi1-1/+1
Change these two fields, simplifying memory management and copying. Change-Id: If2559284c515721e71e1ef56ada8b64667eebe55 Approved-By: Pedro Alves <pedro@palves.net> Reviewed-By: Reviewed-By: Lancelot Six <lancelot.six@amd.com>
2023-10-19gdb: replace some so_list parameters to use referencesSimon Marchi1-2/+3
A subsequent patch changes so_list to be linked using intrusive_list. Iterating an intrusive_list yields some references to the list elements. Convert some functions accepting so_list objects to take references, to make things easier and more natural. Add const where possible and convenient. Change-Id: Id5ab5339c3eb6432e809ad14782952d6a45806f3 Approved-By: Pedro Alves <pedro@palves.net> Reviewed-By: Reviewed-By: Lancelot Six <lancelot.six@amd.com>
2023-10-10gdb: remove target_gdbarchSimon Marchi1-8/+8
This function is just a wrapper around the current inferior's gdbarch. I find that having that wrapper just obscures where the arch is coming from, and that it's often used as "I don't know which arch to use so I'll use this magical target_gdbarch function that gets me an arch" when the arch should in fact come from something in the context (a thread, objfile, symbol, etc). I think that removing it and inlining `current_inferior ()->arch ()` everywhere will make it a bit clearer where that arch comes from and will trigger people into reflecting whether this is the right place to get the arch or not. Change-Id: I79f14b4e4934c88f91ca3a3155f5fc3ea2fadf6b Reviewed-By: John Baldwin <jhb@FreeBSD.org> Approved-By: Andrew Burgess <aburgess@redhat.com>
2023-10-05gdb: remove unnecessary nullptr check in free_objfile observersSimon Marchi1-3/+0
The free_objfile observable is never called with a nullptr objfile. Change-Id: I1e990edeb45bc38009ccb129c623911097ab65fe Approved-By: Tom Tromey <tom@tromey.com>
2023-10-02gdb: remove solib::pspace fieldSimon Marchi1-2/+2
This backlink is not necessary, we always know the program space from the context. Pass it down the solib_unloaded observer. Change-Id: I45a503472dc791f517558b8141901472634e0556 Approved-By: Tom Tromey <tom@tromey.com>
2023-09-26Use string_file::release in some placesTom Tromey1-1/+1
I found a few spots like: string_file f; std::string x = f.string (); However, string_file::string returns a 'const std::string &'... so it seems to me that this must be copying the string (? I find it hard to reason about this in C++). This patch changes these spots to use release() instead, which moves the string. Reviewed-by: Keith Seitz <keiths@redhat.com> Reviewed-by: Lancelot Six <lancelot.six@amd.com>
2023-09-19Use gdb::checked_static_cast for code_breakpointTom Tromey1-2/+4
This replaces some casts to 'code_breakpoint *' with checked_static_cast. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-09-19Use gdb::checked_static_cast for tracepointsTom Tromey1-15/+19
This replaces some casts to 'tracepoint *' with checked_static_cast. Some functions are changed to accept a 'tracepoint *' now, for better type safety. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-09-19Use gdb::checked_static_cast for watchpointsTom Tromey1-152/+147
This replaces some casts to 'watchpoint *' with checked_static_cast. In one spot, an unnecessary block is also removed. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-09-19gdb, breakpoint: add a destructor to the watchpoint structMohamed Bouhaouel1-0/+14
Make sure to unlink the related breakpoint when the watchpoint instance is deleted. This prevents having a wp-related breakpoint that is linked to a NULL watchpoint (e.g. the watchpoint instance is being deleted when the 'watch' command fails). With the below scenario, having such a left out breakpoint will lead to a GDB hang, and this is due to an infinite loop when deleting all inferior breakpoints. Scenario: (gdb) set can-use-hw-watchpoints 0 (gdb) awatch <SCOPE VAR> Can't set read/access watchpoint when hardware watchpoints are disabled. (gdb) rwatch <SCOPE VAR> Can't set read/access watchpoint when hardware watchpoints are disabled. (gdb) <continue the program until the end> >> HANG << Signed-off-by: Mohamed Bouhaouel <mohamed.bouhaouel@intel.com> Reviewed-by: Bruno Larsen <blarsen@redhat.com>
2023-08-23gdb: centralize "[Thread ...exited]" notificationsPedro Alves1-1/+3
Currently, each target backend is responsible for printing "[Thread ...exited]" before deleting a thread. This leads to unnecessary differences between targets, like e.g. with the remote target, we never print such messages, even though we do print "[New Thread ...]". E.g., debugging the gdb.threads/attach-many-short-lived-threads.exp with gdbserver, letting it run for a bit, and then pressing Ctrl-C, we currently see: (gdb) c Continuing. ^C[New Thread 3850398.3887449] [New Thread 3850398.3887500] [New Thread 3850398.3887551] [New Thread 3850398.3887602] [New Thread 3850398.3887653] ... Thread 1 "attach-many-sho" received signal SIGINT, Interrupt. 0x00007ffff7e6a23f in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffffda80, rem=rem@entry=0x7fffffffda80) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78 78 in ../sysdeps/unix/sysv/linux/clock_nanosleep.c (gdb) Above, we only see "New Thread" notifications, even though threads were deleted. After this patch, we'll see: (gdb) c Continuing. ^C[Thread 3558643.3577053 exited] [Thread 3558643.3577104 exited] [Thread 3558643.3577155 exited] [Thread 3558643.3579603 exited] ... [New Thread 3558643.3597415] [New Thread 3558643.3600015] [New Thread 3558643.3599965] ... Thread 1 "attach-many-sho" received signal SIGINT, Interrupt. 0x00007ffff7e6a23f in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffffda80, rem=rem@entry=0x7fffffffda80) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78 78 in ../sysdeps/unix/sysv/linux/clock_nanosleep.c (gdb) q This commit fixes this by moving the thread exit printing to common code instead, triggered from within delete_thread (or rather, set_thread_exited). There's one wrinkle, though. While most targest want to print: [Thread ... exited] the Windows target wants to print: [Thread ... exited with code <exit_code>] ... and sometimes wants to suppress the notification for the main thread. To address that, this commits adds a delete_thread_with_code function, only used by that target (so far). This fix was originally posted as part of a larger series: https://inbox.sourceware.org/gdb-patches/20221212203101.1034916-1-pedro@palves.net/ But didn't really need to be part of that series. In order to get this fix merged sooner, I (Andrew Burgess) have rebased this commit outside of the original series. Any bugs introduced while splitting this patch out and rebasing, are entirely my own. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30129 Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
2023-08-23gdb: add missing notify_breakpoint_modified callAndrew Burgess1-1/+1
The commit: commit b080fe54fb3414b488b8ef323c6c50def061f918 Date: Tue Nov 8 12:32:51 2022 +0000 gdb: add inferior-specific breakpoints introduced a bug in the function breakpoint_set_inferior. The above commit includes this line: gdb::observers::breakpoint_modified.notify (b); when it should have instead used this line: notify_breakpoint_modified (b); The change to use notify_breakpoint_modified was introduced to GDB after commit b080fe54fb34 was written, but before it was merged, and I failed to update this part of the code during the rebase. The consequence of this error is that the MI interpreter will not emit breakpoint-modified notifications when breakpoint_set_inferior is called. In this commit I update the code to call notify_breakpoint_modified, and add a test that checks the MI events are being emitted correctly in this case.
2023-08-17gdb: add inferior-specific breakpointsAndrew Burgess1-49/+188
This commit extends the breakpoint mechanism to allow for inferior specific breakpoints (but not watchpoints in this commit). As GDB gains better support for multiple connections, and so for running multiple (possibly unrelated) inferiors, then it is not hard to imagine that a user might wish to create breakpoints that apply to any thread in a single inferior. To achieve this currently, the user would need to create a condition possibly making use of the $_inferior convenience variable, which, though functional, isn't the most user friendly. This commit adds a new 'inferior' keyword that allows for the creation of inferior specific breakpoints. Inferior specific breakpoints are automatically deleted when the associated inferior is removed from GDB, this is similar to how thread-specific breakpoints are deleted when the associated thread is deleted. Watchpoints are already per-program-space, which in most cases mean watchpoints are already inferior specific. There is a small window where inferior-specific watchpoints might make sense, which is after a vfork, when two processes are sharing the same address space. However, I'm leaving that as an exercise for another day. For now, attempting to use the inferior keyword with a watchpoint will give an error, like this: (gdb) watch a8 inferior 1 Cannot use 'inferior' keyword with watchpoints A final note on the implementation: currently, inferior specific breakpoints, like thread-specific breakpoints, are inserted into every inferior, GDB then checks once the inferior stops if we are in the correct thread or inferior, and resumes automatically if we stopped in the wrong thread/inferior. An obvious optimisation here is to only insert breakpoint locations into the specific program space (which mostly means inferior) that contains either the inferior or thread we are interested in. This would reduce the number times GDB has to stop and then resume again in a multi-inferior setup. I have a series on the mailing list[1] that implements this optimisation for thread-specific breakpoints. Once this series has landed I'll update that series to also handle inferior specific breakpoints in the same way. For now, inferior specific breakpoints are just slightly less optimal, but this is no different to thread-specific breakpoints in a multi-inferior debug session, so I don't see this as a huge problem. [1] https://inbox.sourceware.org/gdb-patches/cover.1685479504.git.aburgess@redhat.com/
2023-08-09gdb, breakpoint: add breakpoint location debugging logsMihails Strasuns1-0/+110
Add new commands: set debug breakpoint on|off show debug breakpoint This patch introduces new debugging information that prints breakpoint location insertion and removal flow. The debug output looks like: ~~~ (gdb) set debug breakpoint on (gdb) disassemble main Dump of assembler code for function main: 0x0000555555555129 <+0>: endbr64 0x000055555555512d <+4>: push %rbp 0x000055555555512e <+5>: mov %rsp,%rbp => 0x0000555555555131 <+8>: mov $0x0,%eax 0x0000555555555136 <+13>: pop %rbp 0x0000555555555137 <+14>: ret End of assembler dump. (gdb) break *0x0000555555555137 Breakpoint 2 at 0x555555555137: file main.c, line 4. [breakpoint] update_global_location_list: insert_mode = UGLL_MAY_INSERT (gdb) c Continuing. [breakpoint] update_global_location_list: insert_mode = UGLL_INSERT [breakpoint] insert_bp_location: Breakpoint 2 (0x5565daddb1e0) at address 0x555555555137 in main at main.c:4 [breakpoint] insert_bp_location: Breakpoint -2 (0x5565dab51c10) at address 0x7ffff7fd37b5 [breakpoint] insert_bp_location: Breakpoint -5 (0x5565dab68f30) at address 0x7ffff7fe509e [breakpoint] insert_bp_location: Breakpoint -7 (0x5565dab694f0) at address 0x7ffff7fe63f4 [breakpoint] remove_breakpoint_1: Breakpoint 2 (0x5565daddb1e0) at address 0x555555555137 in main at main.c:4 due to regular remove [breakpoint] remove_breakpoint_1: Breakpoint -2 (0x5565dab51c10) at address 0x7ffff7fd37b5 due to regular remove [breakpoint] remove_breakpoint_1: Breakpoint -5 (0x5565dab68f30) at address 0x7ffff7fe509e due to regular remove [breakpoint] remove_breakpoint_1: Breakpoint -7 (0x5565dab694f0) at address 0x7ffff7fe63f4 due to regular remove Breakpoint 2, 0x0000555555555137 in main () at main.c:4 4 } ~~~ Co-Authored-By: Christina Schimpe <christina.schimpe@intel.com>
2023-08-03gdb: avoid double stop after failed breakpoint condition checkAndrew Burgess1-12/+0
This commit replaces this earlier commit: commit 2e411b8c68eb2b035b31d5b00d940d4be1a0928b Date: Fri Oct 14 14:53:15 2022 +0100 gdb: don't always print breakpoint location after failed condition check and is a result of feedback received here[1]. The original commit addressed a problem where, if a breakpoint condition included an inferior function call, and if the inferior function call failed, then GDB would announce the stop twice. Here's an example of GDB's output before the above commit that shows the problem being addressed: (gdb) break foo if (some_func ()) Breakpoint 1 at 0x40111e: file bpcond.c, line 11. (gdb) r Starting program: /tmp/bpcond Program received signal SIGSEGV, Segmentation fault. 0x0000000000401116 in some_func () at bpcond.c:5 5 return *p; Error in testing condition for breakpoint 1: The program being debugged stopped while in a function called from GDB. Evaluation of the expression containing the function (some_func) will be abandoned. When the function is done executing, GDB will silently stop. Breakpoint 1, 0x0000000000401116 in some_func () at bpcond.c:5 5 return *p; (gdb) The original commit addressed this issue in breakpoint.c, by spotting that the $pc had changed while evaluating the breakpoint condition, and inferring from this that GDB must have stopped elsewhere. However, the way in which the original commit suppressed the second stop announcement was to set bpstat::print to true -- this tells GDB not to print the frame during the stop announcement, and for the CLI this is fine, however, it was pointed out that for the MI this still isn't really enough. Below is an example from an MI session after the above commit was applied, this shows the problem with the above commit: -break-insert -c "cond_fail()" foo ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x000000000040111e",func="foo",file="/tmp/mi-condbreak-fail.c",line="30",thread-groups=["i1"],cond="cond_fail()",times="0",original-location="foo"} (gdb) -exec-run =thread-group-started,id="i1",pid="2636270" =thread-created,id="1",group-id="i1" =library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0",thread-group="i1",ranges=[{from="0x00007ffff7fd3110",to="0x00007ffff7ff2bb4"}] ^running *running,thread-id="all" (gdb) =library-loaded,id="/lib64/libm.so.6",target-name="/lib64/libm.so.6",host-name="/lib64/libm.so.6",symbols-loaded="0",thread-group="i1",ranges=[{from="0x00007ffff7e59390",to="0x00007ffff7ef4f98"}] =library-loaded,id="/lib64/libc.so.6",target-name="/lib64/libc.so.6",host-name="/lib64/libc.so.6",symbols-loaded="0",thread-group="i1",ranges=[{from="0x00007ffff7ca66b0",to="0x00007ffff7df3c5f"}] ~"\nProgram" ~" received signal SIGSEGV, Segmentation fault.\n" ~"0x0000000000401116 in cond_fail () at /tmp/mi-condbreak-fail.c:24\n" ~"24\t return *p;\t\t\t/* Crash here. */\n" *stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",frame={addr="0x0000000000401116",func="cond_fail",args=[],file="/tmp/mi-condbreak-fail.c",fullname="/tmp/mi-condbreak-fail.c",line="24",arch="i386:x86-64"},thread-id="1",stopped-threads="all",core="9" &"Error in testing condition for breakpoint 1:\n" &"The program being debugged was signaled while in a function called from GDB.\n" &"GDB remains in the frame where the signal was received.\n" &"To change this behavior use \"set unwindonsignal on\".\n" &"Evaluation of the expression containing the function\n" &"(cond_fail) will be abandoned.\n" &"When the function is done executing, GDB will silently stop.\n" =breakpoint-modified,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x000000000040111e",func="foo",file="/tmp/mi-condbreak-fail.c",fullname="/tmp/mi-condbreak-fail.c",line="30",thread-groups=["i1"],cond="cond_fail()",times="1",original-location="foo"} *stopped (gdb) Notice that we still see two '*stopped' lines, the first includes the full frame information, while the second has no frame information, this is a result of bpstat::print having been set. Ideally, the second '*stopped' line should not be present. By setting bpstat::print I was addressing the problem too late, this flag really only changes how interp::on_normal_stop prints the stop event, and interp::on_normal_stop is called (indirectly) from the normal_stop function in infrun.c. A better solution is to avoid calling normal_stop at all for the stops which should not be reported to the user, and this is what I do in this commit. This commit has 3 parts: 1. In breakpoint.c, revert the above commit, 2. In fetch_inferior_event (infrun.c), capture the stop-id before calling handle_inferior_event. If, after calling handle_inferior_event, the stop-id has changed, then this indicates that somewhere within handle_inferior_event, a stop was announced to the user. If this is the case then GDB should not call normal_stop, and we should rely on whoever announced the stop to ensure that we are in a PROMPT_NEEDED state, which means the prompt will be displayed once fetch_inferior_event returns. And, 3. In infcall.c, do two things: (a) In run_inferior_call, after making the inferior call, ensure that either async_disable_stdin or async_enable_stdin is called to put the prompt state, and stdin handling into the correct state based on whether the inferior call completed successfully or not, and (b) In call_thread_fsm::should_stop, call async_enable_stdin rather than changing the prompt state directly. This isn't strictly necessary, but helped me understand this code more. This async_enable_stdin call is only reached if normal_stop is not going to be called, and replaces the async_enable_stdin call that exists in normal_stop. Though we could just adjust the prompt state if felt (to me) much easier to understand when I could see this call and the corresponding call in normal_stop. With these changes in place now, when the inferior call (from the breakpoint condition) fails, infcall.c leaves the prompt state as PROMPT_NEEDED, and leaves stdin registered with the event loop. Back in fetch_inferior_event GDB notices that the stop-id has changed and so avoids calling normal_stop. And on return from fetch_inferior_event GDB will display the prompt and handle input from stdin. As normal_stop is not called the MI problem is solved, and the test added in the earlier mentioned commit still passes just fine, so the CLI has not regressed. [1] https://inbox.sourceware.org/gdb-patches/6fd4aa13-6003-2563-5841-e80d5a55d59e@palves.net/
2023-07-10gdb: include location number in breakpoint error messageAndrew Burgess1-3/+11
This commit improves the output of this previous commit: commit 2dc3457a454a35d0617dc1f9cc1db77468471f95 Date: Fri Oct 14 13:22:55 2022 +0100 gdb: include breakpoint number in testing condition error message The earlier commit extended the error message: Error in testing breakpoint condition: to include the breakpoint number, e.g.: Error in testing breakpoint condition 3: This commit extends takes this further, and includes the location number if the breakpoint has multiple locations, so we might now see: Error in testing breakpoint condition 3.2: Just as with how GDB reports a normal breakpoint stop, if a breakpoint only has a single location then the location number is not included, this keeps things nice and consistent. I've extended one of the tests to cover the new functionality. Approved-By: Pedro Alves <pedro@palves.net>
2023-06-05[gdb] Fix more typosTom de Vries1-1/+1
Fix some more typos: - distinquish -> distinguish - actualy -> actually - singe -> single - frash -> frame - chid -> child - dissassembler -> disassembler - uninitalized -> uninitialized - precontidion -> precondition - regsiters -> registers - marge -> merge - sate -> state - garanteed -> guaranteed - explictly -> explicitly - prefices (nonstandard plural) -> prefixes - bondary -> boundary - formated -> formatted - ithe -> the - arrav -> array - coresponding -> corresponding - owend -> owned - fials -> fails - diasm -> disasm - ture -> true - tpye -> type There's one code change, the name of macro SIG_CODE_BONDARY_FAULT changed to SIG_CODE_BOUNDARY_FAULT. Tested on x86_64-linux.
2023-06-03[gdb] Fix typosTom de Vries1-1/+1
Fix a few typos: - implemention -> implementation - convertion(s) -> conversion(s) - backlashes -> backslashes - signoring -> ignoring - (un)ambigious -> (un)ambiguous - occured -> occurred - hidding -> hiding - temporarilly -> temporarily - immediatelly -> immediately - sillyness -> silliness - similiar -> similar - porkuser -> pokeuser - thats -> that - alway -> always - supercede -> supersede - accomodate -> accommodate - aquire -> acquire - priveleged -> privileged - priviliged -> privileged - priviledges -> privileges - privilige -> privilege - recieve -> receive - (p)refered -> (p)referred - succesfully -> successfully - successfuly -> successfully - responsability -> responsibility - wether -> whether - wich -> which - disasbleable -> disableable - descriminant -> discriminant - construcstor -> constructor - underlaying -> underlying - underyling -> underlying - structureal -> structural - appearences -> appearances - terciarily -> tertiarily - resgisters -> registers - reacheable -> reachable - likelyhood -> likelihood - intepreter -> interpreter - disassemly -> disassembly - covnersion -> conversion - conviently -> conveniently - atttribute -> attribute - struction -> struct - resonable -> reasonable - popupated -> populated - namespaxe -> namespace - intialize -> initialize - identifer(s) -> identifier(s) - expection -> exception - exectuted -> executed - dungerous -> dangerous - dissapear -> disappear - completly -> completely - (inter)changable -> (inter)changeable - beakpoint -> breakpoint - automativ -> automatic - alocating -> allocating - agressive -> aggressive - writting -> writing - reguires -> requires - registed -> registered - recuding -> reducing - opeartor -> operator - ommitted -> omitted - modifing -> modifying - intances -> instances - imbedded -> embedded - gdbaarch -> gdbarch - exection -> execution - direcive -> directive - demanged -> demangled - decidely -> decidedly - argments -> arguments - agrument -> argument - amespace -> namespace - targtet -> target - supress(ed) -> suppress(ed) - startum -> stratum - squence -> sequence - prompty -> prompt - overlow -> overflow - memember -> member - languge -> language - geneate -> generate - funcion -> function - exising -> existing - dinking -> syncing - destroh -> destroy - clenaed -> cleaned - changep -> changedp (name of variable) - arround -> around - aproach -> approach - whould -> would - symobl -> symbol - recuse -> recurse - outter -> outer - freeds -> frees - contex -> context Tested on x86_64-linux. Reviewed-By: Tom Tromey <tom@tromey.com>
2023-05-30gdb: add interp::on_breakpoint_modified methodSimon Marchi1-19/+28
Same idea as previous patches, but for breakpoint_modified. Change-Id: I4f0a9edea912de431e32451d74224b2022a7c328
2023-05-30gdb: add interp::on_breakpoint_deleted methodSimon Marchi1-1/+10
Same idea as previous patches, but for breakpoint_deleted. Change-Id: I59c231ce963491bb1eee1432ee1090138f09e19c
2023-05-30gdb: add interp::on_breakpoint_created methodSimon Marchi1-1/+11
Same idea as previous patches, but for breakpoint_created. Change-Id: I614113c924edc243590018b8fb3bf69cb62215ef
2023-05-25gdb: remove breakpoint_pointer_iteratorSimon Marchi1-304/+301
Remove the breakpoint_pointer_iterator layer. Adjust all users of all_breakpoints and all_tracepoints to use references instead of pointers. Change-Id: I376826f812117cee1e6b199c384a10376973af5d Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: link breakpoints with intrusive_listSimon Marchi1-26/+10
Change-Id: I043d8d6f3dd864d80d5088f6ffc2c098337249ea Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: remove bp_location_pointer_iteratorSimon Marchi1-124/+123
Remove the bp_location_pointer_iterator layer. Adjust all users of breakpoint::locations to use references instead of pointers. Change-Id: Iceed34f5e0f5790a9cf44736aa658be6d1ba1afa Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: use intrusive_list for breakpoint locationsSimon Marchi1-126/+113
Replace the hand-maintained linked lists of breakpoint locations with and intrusive list. - Remove breakpoint::loc, add breakpoint::m_locations. - Add methods for the various manipulations that need to be done on the location list, while maintaining reasonably good encapsulation. - bp_location currently has a default constructor because of one use in hoist_existing_locations. hoist_existing_locations now returns a bp_location_list, and doesn't need the default-constructor bp_location anymore, so remove the bp_location default constructor. - I needed to add a call to clear_locations in delete_breakpoint to avoid a use-after-free. - Add a breakpoint::last_loc method, for use in set_breakpoint_condition. bp_location_range uses reference_to_pointer_iterator, so that all existing callers of breakpoint::locations don't need to change right now. It will be removed in the next patch. The rest of the changes are to adapt the call sites to use the new methods, of breakpoint::locations, rather than breakpoint::loc directly. Change-Id: I25f7ee3d66a4e914a0540589ac414b3b820b6e70 Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: add breakpoint::first_loc methodsSimon Marchi1-57/+55
Add convenience first_loc methods to struct breakpoint (const and non-const overloads). A subsequent patch changes the list of locations to be an intrusive_list and makes the actual list private, so these spots would need to change from: b->loc to something ugly like: *b->locations ().begin () That would make the code much heavier and not readable. There is a surprisingly big number of places that access the first location of breakpoints. Whether this is correct, or these spots fail to consider the possibility of multi-location breakpoints, I don't know. But anyhow, I think that using this instead: b->first_loc () conveys the intention better than the other two forms. Change-Id: Ibbefe3e4ca6cdfe570351fe7e2725f2ce11d1e95 Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: add breakpoint "has locations" methodsSimon Marchi1-29/+33
Add three convenience methods to struct breakpoint: - has_locations: returns true if the breakpoint has at least one location - has_single_location: returns true if the breakpoint has exactly one location - has_multiple_locations: returns true if the breakpoint has more than one location A subsequent patch changes the list of breakpoints to be an intrusive_list, so all these spots would need to change. But in any case, I think that this: if (b->has_multiple_locations ()) conveys the intention better than: if (b->loc != nullptr && b->loc->next != nullptr) Change-Id: Ib18c3605fd35d425ef9df82cb7aacff1606c6747 Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: constify breakpoint::print_it parameterSimon Marchi1-8/+6
The print_it method itself is const. In a subsequent patch, the locations that come out of a const breakpoint will be const as well. It will therefore be needed to make the last_loc output parameter const as well. Make that change now to reduce the size of the following patches. Change-Id: I7ed962950bc9582646e31e2e42beca2a1c9c5105 Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-25gdb: make some breakpoint methods use `this`Simon Marchi1-16/+10
Some implementations of breakpoint::check_status and breakpoint::print_it do this: struct breakpoint *b = bs->breakpoint_at; bs->breakpoint_at is always the same as `this` (we can get convinced by looking at the call sites of check_status and print_it), so it would just be clearer to access fields through `this` instead. Change-Id: Ic542a64fcd88e31ae2aad6feff1da278c7086891 Reviewed-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com> Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-05-23Introduce and use parser flagsTom Tromey1-1/+2
This patch adds a new parser_flags type and changes the parser APIs to use it rather than a collection of 'int' and 'bool'. More flags will be added in subsquent patches.
2023-05-19gdb/breakpoint: use warning function instead of gdb_printfAndrew Burgess1-3/+3
Noticed that in breakpoint.c, in one place, we do this: gdb_printf (_("warning: Error removing " "breakpoint %d\n"), old_loc->owner->number); Instead of using the `warning` function. There are a number of differences between using gdb_printf like this and calling `warning`, the main one is probably that real warnings are sent to gdb_stderr, while the above gdb_printf call will go to gdb_stdout. In this commit I: 1. Change to call `warning`, we can drop the "warning: " prefix from the string in breakpoint.c, 2. Update the warning text, I now start with a lower case 'e', which I believe is the GDB style for warnings, 3. And I have included the address of the bp_location in the warning messsage, 4. Finally, I update all the tests (2) that include this error message. Reviewed-By: Tom Tromey <tom@tromey.com>
2023-05-11Disable out-of-scope watchpointsJohnson Sun1-0/+1
Currently, when a local software watchpoint goes out of scope, GDB sets the watchpoint's disposition to `delete at next stop' and then normal stops (i.e., stop and wait for the next GDB command). When GDB normal stops, it automatically deletes the breakpoints with their disposition set to `delete at next stop'. Suppose a Python script decides not to normal stop when a local software watchpoint goes out of scope, the watchpoint will not be automatically deleted even when its disposition is set to `delete at next stop'. Since GDB single-steps the program and tests the watched expression after each instruction, not deleting the watchpoint causes the watchpoint to be hit many more times than it should, as reported in PR python/29603. This was happening because the watchpoint is not deleted or disabled when going out of scope. This commit fixes this issue by disabling the watchpoint when going out of scope. It also adds a test to ensure this feature isn't regressed in the future. Calling `breakpoint_auto_delete' on all kinds of stops (in `fetch_inferior_event') seem to solve this issue, but is in fact inappropriate, since `breakpoint_auto_delete' goes over all breakpoints instead of just going through the bpstat chain (which only contains the breakpoints that were hit right now). Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29603 Change-Id: Ia85e670b2bcba2799219abe4b6be3b582387e383
2023-05-09gdb: fix use-after-free in check_longjmp_breakpoint_for_call_dummySimon Marchi1-9/+16
Commit 7a8de0c33019 ("Remove ALL_BREAKPOINTS_SAFE") introduced a use-after-free in the breakpoints iterations (see below for full ASan report). This makes gdb.base/stale-infcall.exp fail when GDB is build with ASan. check_longjmp_breakpoint_for_call_dummy iterates on all breakpoints, possibly deleting the current breakpoint as well as related breakpoints. The problem arises when a breakpoint in the B->related_breakpoint chain is also B->next. In that case, deleting that related breakpoint frees the breakpoint that all_breakpoints_safe has saved. The old code worked around that by manually changing B_TMP, which was the next breakpoint saved by the "safe iterator": while (b->related_breakpoint != b) { if (b_tmp == b->related_breakpoint) b_tmp = b->related_breakpoint->next; delete_breakpoint (b->related_breakpoint); } (Note that this seemed to assume that b->related_breakpoint->next was the same as b->next->next, not sure this is guaranteed.) The new code kept the B_TMP variable, but it's not useful in that context. We can't go change the next breakpoint as saved by the safe iterator, like we did before. I suggest fixing that by saving the breakpoints to delete in a map and deleting them all at the end. Here's the full ASan report: (gdb) PASS: gdb.base/stale-infcall.exp: continue to breakpoint: break-run1 print infcall () ================================================================= ==47472==ERROR: AddressSanitizer: heap-use-after-free on address 0x611000034980 at pc 0x563f7012c7bc bp 0x7ffdf3804d70 sp 0x7ffdf3804d60 READ of size 8 at 0x611000034980 thread T0 #0 0x563f7012c7bb in next_iterator<breakpoint>::operator++() /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/next-iterator.h:66 #1 0x563f702ce8c0 in basic_safe_iterator<next_iterator<breakpoint> >::operator++() /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/safe-iterator.h:84 #2 0x563f7021522a in check_longjmp_breakpoint_for_call_dummy(thread_info*) /home/smarchi/src/binutils-gdb/gdb/breakpoint.c:7611 #3 0x563f714567b1 in process_event_stop_test /home/smarchi/src/binutils-gdb/gdb/infrun.c:6881 #4 0x563f71454e07 in handle_signal_stop /home/smarchi/src/binutils-gdb/gdb/infrun.c:6769 #5 0x563f7144b680 in handle_inferior_event /home/smarchi/src/binutils-gdb/gdb/infrun.c:6023 #6 0x563f71436165 in fetch_inferior_event() /home/smarchi/src/binutils-gdb/gdb/infrun.c:4387 #7 0x563f7136ff51 in inferior_event_handler(inferior_event_type) /home/smarchi/src/binutils-gdb/gdb/inf-loop.c:42 #8 0x563f7168038d in handle_target_event /home/smarchi/src/binutils-gdb/gdb/linux-nat.c:4219 #9 0x563f72fccb6d in handle_file_event /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:573 #10 0x563f72fcd503 in gdb_wait_for_event /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:694 #11 0x563f72fcaf2b in gdb_do_one_event(int) /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:217 #12 0x563f7262b9bb in wait_sync_command_done() /home/smarchi/src/binutils-gdb/gdb/top.c:426 #13 0x563f7137a7c3 in run_inferior_call /home/smarchi/src/binutils-gdb/gdb/infcall.c:650 #14 0x563f71381295 in call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*) /home/smarchi/src/binutils-gdb/gdb/infcall.c:1332 #15 0x563f7137c0e2 in call_function_by_hand(value*, type*, gdb::array_view<value*>) /home/smarchi/src/binutils-gdb/gdb/infcall.c:780 #16 0x563f70fe5960 in evaluate_subexp_do_call(expression*, noside, value*, gdb::array_view<value*>, char const*, type*) /home/smarchi/src/binutils-gdb/gdb/eval.c:649 #17 0x563f70fe6617 in expr::operation::evaluate_funcall(type*, expression*, noside, char const*, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/eval.c:677 #18 0x563f6fd19668 in expr::operation::evaluate_funcall(type*, expression*, noside, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/expression.h:136 #19 0x563f70fe6bba in expr::var_value_operation::evaluate_funcall(type*, expression*, noside, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/eval.c:689 #20 0x563f704b71dc in expr::funcall_operation::evaluate(type*, expression*, noside) /home/smarchi/src/binutils-gdb/gdb/expop.h:2219 #21 0x563f70fe0f02 in expression::evaluate(type*, noside) /home/smarchi/src/binutils-gdb/gdb/eval.c:110 #22 0x563f71b1373e in process_print_command_args /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1319 #23 0x563f71b1391b in print_command_1 /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1332 #24 0x563f71b147ec in print_command /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1465 #25 0x563f706029b8 in do_simple_func /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:95 #26 0x563f7061972a in cmd_func(cmd_list_element*, char const*, int) /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:2735 #27 0x563f7262d0ef in execute_command(char const*, int) /home/smarchi/src/binutils-gdb/gdb/top.c:572 #28 0x563f7100ed9c in command_handler(char const*) /home/smarchi/src/binutils-gdb/gdb/event-top.c:543 #29 0x563f7101014b in command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) /home/smarchi/src/binutils-gdb/gdb/event-top.c:779 #30 0x563f72777942 in tui_command_line_handler /home/smarchi/src/binutils-gdb/gdb/tui/tui-interp.c:104 #31 0x563f7100d059 in gdb_rl_callback_handler /home/smarchi/src/binutils-gdb/gdb/event-top.c:250 #32 0x7f5a80418246 in rl_callback_read_char (/usr/lib/libreadline.so.8+0x3b246) (BuildId: 092e91fc4361b0ef94561e3ae03a75f69398acbb) #33 0x563f7100ca06 in gdb_rl_callback_read_char_wrapper_noexcept /home/smarchi/src/binutils-gdb/gdb/event-top.c:192 #34 0x563f7100cc5e in gdb_rl_callback_read_char_wrapper /home/smarchi/src/binutils-gdb/gdb/event-top.c:225 #35 0x563f728c70db in stdin_event_handler /home/smarchi/src/binutils-gdb/gdb/ui.c:155 #36 0x563f72fccb6d in handle_file_event /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:573 #37 0x563f72fcd503 in gdb_wait_for_event /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:694 #38 0x563f72fcb15c in gdb_do_one_event(int) /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:264 #39 0x563f7177ec1c in start_event_loop /home/smarchi/src/binutils-gdb/gdb/main.c:412 #40 0x563f7177f12e in captured_command_loop /home/smarchi/src/binutils-gdb/gdb/main.c:476 #41 0x563f717846e4 in captured_main /home/smarchi/src/binutils-gdb/gdb/main.c:1320 #42 0x563f71784821 in gdb_main(captured_main_args*) /home/smarchi/src/binutils-gdb/gdb/main.c:1339 #43 0x563f6fcedfbd in main /home/smarchi/src/binutils-gdb/gdb/gdb.c:32 #44 0x7f5a7e43984f (/usr/lib/libc.so.6+0x2384f) (BuildId: 2f005a79cd1a8e385972f5a102f16adba414d75e) #45 0x7f5a7e439909 in __libc_start_main (/usr/lib/libc.so.6+0x23909) (BuildId: 2f005a79cd1a8e385972f5a102f16adba414d75e) #46 0x563f6fcedd84 in _start (/home/smarchi/build/binutils-gdb/gdb/gdb+0xafb0d84) (BuildId: 50bd32e6e9d5e84543e9897b8faca34858ca3995) 0x611000034980 is located 0 bytes inside of 208-byte region [0x611000034980,0x611000034a50) freed by thread T0 here: #0 0x7f5a7fce312a in operator delete(void*, unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:164 #1 0x563f702bd1fa in momentary_breakpoint::~momentary_breakpoint() /home/smarchi/src/binutils-gdb/gdb/breakpoint.c:304 #2 0x563f702771c5 in delete_breakpoint(breakpoint*) /home/smarchi/src/binutils-gdb/gdb/breakpoint.c:12404 #3 0x563f702150a7 in check_longjmp_breakpoint_for_call_dummy(thread_info*) /home/smarchi/src/binutils-gdb/gdb/breakpoint.c:7673 #4 0x563f714567b1 in process_event_stop_test /home/smarchi/src/binutils-gdb/gdb/infrun.c:6881 #5 0x563f71454e07 in handle_signal_stop /home/smarchi/src/binutils-gdb/gdb/infrun.c:6769 #6 0x563f7144b680 in handle_inferior_event /home/smarchi/src/binutils-gdb/gdb/infrun.c:6023 #7 0x563f71436165 in fetch_inferior_event() /home/smarchi/src/binutils-gdb/gdb/infrun.c:4387 #8 0x563f7136ff51 in inferior_event_handler(inferior_event_type) /home/smarchi/src/binutils-gdb/gdb/inf-loop.c:42 #9 0x563f7168038d in handle_target_event /home/smarchi/src/binutils-gdb/gdb/linux-nat.c:4219 #10 0x563f72fccb6d in handle_file_event /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:573 #11 0x563f72fcd503 in gdb_wait_for_event /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:694 #12 0x563f72fcaf2b in gdb_do_one_event(int) /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:217 #13 0x563f7262b9bb in wait_sync_command_done() /home/smarchi/src/binutils-gdb/gdb/top.c:426 #14 0x563f7137a7c3 in run_inferior_call /home/smarchi/src/binutils-gdb/gdb/infcall.c:650 #15 0x563f71381295 in call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*) /home/smarchi/src/binutils-gdb/gdb/infcall.c:1332 #16 0x563f7137c0e2 in call_function_by_hand(value*, type*, gdb::array_view<value*>) /home/smarchi/src/binutils-gdb/gdb/infcall.c:780 #17 0x563f70fe5960 in evaluate_subexp_do_call(expression*, noside, value*, gdb::array_view<value*>, char const*, type*) /home/smarchi/src/binutils-gdb/gdb/eval.c:649 #18 0x563f70fe6617 in expr::operation::evaluate_funcall(type*, expression*, noside, char const*, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/eval.c:677 #19 0x563f6fd19668 in expr::operation::evaluate_funcall(type*, expression*, noside, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/expression.h:136 #20 0x563f70fe6bba in expr::var_value_operation::evaluate_funcall(type*, expression*, noside, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/eval.c:689 #21 0x563f704b71dc in expr::funcall_operation::evaluate(type*, expression*, noside) /home/smarchi/src/binutils-gdb/gdb/expop.h:2219 #22 0x563f70fe0f02 in expression::evaluate(type*, noside) /home/smarchi/src/binutils-gdb/gdb/eval.c:110 #23 0x563f71b1373e in process_print_command_args /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1319 #24 0x563f71b1391b in print_command_1 /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1332 #25 0x563f71b147ec in print_command /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1465 #26 0x563f706029b8 in do_simple_func /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:95 #27 0x563f7061972a in cmd_func(cmd_list_element*, char const*, int) /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:2735 #28 0x563f7262d0ef in execute_command(char const*, int) /home/smarchi/src/binutils-gdb/gdb/top.c:572 #29 0x563f7100ed9c in command_handler(char const*) /home/smarchi/src/binutils-gdb/gdb/event-top.c:543 previously allocated by thread T0 here: #0 0x7f5a7fce2012 in operator new(unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:95 #1 0x563f7029a9a3 in new_momentary_breakpoint<program_space*&, frame_id&, int&> /home/smarchi/src/binutils-gdb/gdb/breakpoint.c:8129 #2 0x563f702212f6 in momentary_breakpoint_from_master /home/smarchi/src/binutils-gdb/gdb/breakpoint.c:8169 #3 0x563f70212db1 in set_longjmp_breakpoint_for_call_dummy() /home/smarchi/src/binutils-gdb/gdb/breakpoint.c:7582 #4 0x563f713804db in call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*) /home/smarchi/src/binutils-gdb/gdb/infcall.c:1260 #5 0x563f7137c0e2 in call_function_by_hand(value*, type*, gdb::array_view<value*>) /home/smarchi/src/binutils-gdb/gdb/infcall.c:780 #6 0x563f70fe5960 in evaluate_subexp_do_call(expression*, noside, value*, gdb::array_view<value*>, char const*, type*) /home/smarchi/src/binutils-gdb/gdb/eval.c:649 #7 0x563f70fe6617 in expr::operation::evaluate_funcall(type*, expression*, noside, char const*, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/eval.c:677 #8 0x563f6fd19668 in expr::operation::evaluate_funcall(type*, expression*, noside, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/expression.h:136 #9 0x563f70fe6bba in expr::var_value_operation::evaluate_funcall(type*, expression*, noside, std::__debug::vector<std::unique_ptr<expr::operation, std::default_delete<expr::operation> >, std::allocator<std::unique_ptr<expr::operation, std::default_delete<expr::operation> > > > const&) /home/smarchi/src/binutils-gdb/gdb/eval.c:689 #10 0x563f704b71dc in expr::funcall_operation::evaluate(type*, expression*, noside) /home/smarchi/src/binutils-gdb/gdb/expop.h:2219 #11 0x563f70fe0f02 in expression::evaluate(type*, noside) /home/smarchi/src/binutils-gdb/gdb/eval.c:110 #12 0x563f71b1373e in process_print_command_args /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1319 #13 0x563f71b1391b in print_command_1 /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1332 #14 0x563f71b147ec in print_command /home/smarchi/src/binutils-gdb/gdb/printcmd.c:1465 #15 0x563f706029b8 in do_simple_func /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:95 #16 0x563f7061972a in cmd_func(cmd_list_element*, char const*, int) /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:2735 #17 0x563f7262d0ef in execute_command(char const*, int) /home/smarchi/src/binutils-gdb/gdb/top.c:572 #18 0x563f7100ed9c in command_handler(char const*) /home/smarchi/src/binutils-gdb/gdb/event-top.c:543 #19 0x563f7101014b in command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) /home/smarchi/src/binutils-gdb/gdb/event-top.c:779 #20 0x563f72777942 in tui_command_line_handler /home/smarchi/src/binutils-gdb/gdb/tui/tui-interp.c:104 #21 0x563f7100d059 in gdb_rl_callback_handler /home/smarchi/src/binutils-gdb/gdb/event-top.c:250 #22 0x7f5a80418246 in rl_callback_read_char (/usr/lib/libreadline.so.8+0x3b246) (BuildId: 092e91fc4361b0ef94561e3ae03a75f69398acbb) Change-Id: Id00c17ab677f847fbf4efdf0f4038373668d3d88 Approved-By: Tom Tromey <tom@tromey.com>
2023-05-07Remove ALL_BREAKPOINTS_SAFETom Tromey1-71/+63
There's just a single remaining use of the ALL_BREAKPOINTS_SAFE macro; this patch replaces it with a for-each and an explicit temporary variable.
2023-05-02Remove error_streamTom Tromey1-2/+2
error_stream is trivial and only used in a couple of spots in breakpoint.c. This patch removes it in favor of just writing it out at the spots where it was used.
2023-05-01gdb: move struct ui and related things to ui.{c,h}Simon Marchi1-0/+1
I'd like to move some things so they become methods on struct ui. But first, I think that struct ui and the related things are big enough to deserve their own file, instead of being scattered through top.{c,h} and event-top.c. Change-Id: I15594269ace61fd76ef80a7b58f51ff3ab6979bc
2023-05-01Remove evaluate_expressionTom Tromey1-1/+1
evaluate_expression is just a little wrapper for a method on expression. Removing it also removes a lot of ugly (IMO) calls to get().
2023-04-11gdb: fix indentation within print_one_breakpoint_locationAndrew Burgess1-9/+9
Spotted some code in print_one_breakpoint_location that was not indented correctly, this commit just changes the indentation. There should be no user visible changes after this commit.
2023-04-11gdb: warn when converting h/w watchpoints to s/wAndrew Burgess1-2/+17
On amd64 (at least) if a user sets a watchpoint before the inferior has started then GDB will assume that a hardware watchpoint can be created. When the inferior starts there is a chance that the watchpoint can't actually be create as a hardware watchpoint, in which case (currently) GDB will silently convert the watchpoint to a software watchpoint. Here's an example session: (gdb) p sizeof var $1 = 4000 (gdb) watch var Hardware watchpoint 1: var (gdb) info watchpoints Num Type Disp Enb Address What 1 hw watchpoint keep y var (gdb) starti Starting program: /home/andrew/tmp/watch Program stopped. 0x00007ffff7fd3110 in _start () from /lib64/ld-linux-x86-64.so.2 (gdb) info watchpoints Num Type Disp Enb Address What 1 watchpoint keep y var (gdb) Notice that before the `starti` command the watchpoint is showing as a hardware watchpoint, but afterwards it is showing as a software watchpoint. Additionally, note that we clearly told the user we created a hardware watchpoint: (gdb) watch var Hardware watchpoint 1: var I think this is bad. I used `starti`, but if the user did `start` or even `run` then the inferior is going to be _very_ slow, which will be unexpected -- after all, we clearly told the user that we created a hardware watchpoint, and the manual clearly says that hardware watchpoints are fast (at least compared to s/w watchpoints). In this patch I propose adding a new warning which will be emitted when GDB downgrades a h/w watchpoint to s/w. The session now looks like this: (gdb) p sizeof var $1 = 4000 (gdb) watch var Hardware watchpoint 1: var (gdb) info watchpoints Num Type Disp Enb Address What 1 hw watchpoint keep y var (gdb) starti Starting program: /home/andrew/tmp/watch warning: watchpoint 1 downgraded to software watchpoint Program stopped. 0x00007ffff7fd3110 in _start () from /lib64/ld-linux-x86-64.so.2 (gdb) info watchpoints Num Type Disp Enb Address What 1 watchpoint keep y var (gdb) The important line is: warning: watchpoint 1 downgraded to software watchpoint It's not much, but hopefully it will be enough to indicate to the user that something unexpected has occurred, and hopefully, they will not be surprised when the inferior runs much slower than they expected. I've added an amd64 only test in gdb.arch/, I didn't want to try adding this as a global test as other architectures might be able to support the watchpoint request in h/w. Also the test is skipped for extended-remote boards as there's a different set of options for limiting hardware watchpoints on remote targets, and this test isn't about them. Reviewed-By: Lancelot Six <lancelot.six@amd.com>
2023-04-03gdb: don't always print breakpoint location after failed condition checkAndrew Burgess1-0/+12
Consider the following session: (gdb) list some_func 1 int 2 some_func () 3 { 4 int *p = 0; 5 return *p; 6 } 7 8 void 9 foo () 10 { (gdb) break foo if (some_func ()) Breakpoint 1 at 0x40111e: file bpcond.c, line 11. (gdb) r Starting program: /tmp/bpcond Program received signal SIGSEGV, Segmentation fault. 0x0000000000401116 in some_func () at bpcond.c:5 5 return *p; Error in testing condition for breakpoint 1: The program being debugged stopped while in a function called from GDB. Evaluation of the expression containing the function (some_func) will be abandoned. When the function is done executing, GDB will silently stop. Breakpoint 1, 0x0000000000401116 in some_func () at bpcond.c:5 5 return *p; (gdb) What happens here is the breakpoint condition includes a call to an inferior function, and the inferior function segfaults. We can see that GDB reports the segfault, and then gives an error message that indicates that an inferior function call was interrupted. After this GDB appears to report that it is stopped at Breakpoint 1, inside some_func. I find this second stop report a little confusing. While it is true that GDB stopped as a result of hitting breakpoint 1, I think the message GDB currently prints might give the impression that GDB is actually stopped at a location of breakpoint 1, which is not the case. Also, I find the second stop message draws attention away from the "Program received signal SIGSEGV, Segmentation fault" stop message, and this second stop might be thought of as replacing in someway the earlier message. In short, I think things would be clearer if the second stop message were not reported at all, so the output should, I think, look like this: (gdb) list some_func 1 int 2 some_func () 3 { 4 int *p = 0; 5 return *p; 6 } 7 8 void 9 foo () 10 { (gdb) break foo if (some_func ()) Breakpoint 1 at 0x40111e: file bpcond.c, line 11. (gdb) r Starting program: /tmp/bpcond Program received signal SIGSEGV, Segmentation fault. 0x0000000000401116 in some_func () at bpcond.c:5 5 return *p; Error in testing condition for breakpoint 1: The program being debugged stopped while in a function called from GDB. Evaluation of the expression containing the function (some_func) will be abandoned. When the function is done executing, GDB will silently stop. (gdb) The user can still find the number of the breakpoint that triggered the initial stop in this line: Error in testing condition for breakpoint 1: But there's now only one stop reason reported, the SIGSEGV, which I think is much clearer. To achieve this change I set the bpstat::print field when: (a) a breakpoint condition evaluation failed, and (b) the $pc of the thread changed during condition evaluation. I've updated the existing tests that checked the error message printed when a breakpoint condition evaluation failed.
2023-04-03gdb: include breakpoint number in testing condition error messageAndrew Burgess1-1/+2
When GDB fails to test the condition of a conditional breakpoint, for whatever reason, the error message looks like this: (gdb) break foo if (*(int *) 0) == 1 Breakpoint 1 at 0x40111e: file bpcond.c, line 11. (gdb) r Starting program: /tmp/bpcond Error in testing breakpoint condition: Cannot access memory at address 0x0 Breakpoint 1, foo () at bpcond.c:11 11 int a = 32; (gdb) The line I'm interested in for this commit is this one: Error in testing breakpoint condition: In the case above we can figure out that the problematic breakpoint was #1 because in the final line of the message GDB reports the stop at breakpoint #1. However, in the next few patches I plan to change this. In some cases I don't think it makes sense for GDB to report the stop as being at breakpoint #1, consider this case: (gdb) list some_func 1 int 2 some_func () 3 { 4 int *p = 0; 5 return *p; 6 } 7 8 void 9 foo () 10 { (gdb) break foo if (some_func ()) Breakpoint 1 at 0x40111e: file bpcond.c, line 11. (gdb) r Starting program: /tmp/bpcond Program received signal SIGSEGV, Segmentation fault. 0x0000000000401116 in some_func () at bpcond.c:5 5 return *p; Error in testing breakpoint condition: The program being debugged was signaled while in a function called from GDB. GDB remains in the frame where the signal was received. To change this behavior use "set unwindonsignal on". Evaluation of the expression containing the function (some_func) will be abandoned. When the function is done executing, GDB will silently stop. Program received signal SIGSEGV, Segmentation fault. Breakpoint 1, 0x0000000000401116 in some_func () at bpcond.c:5 5 return *p; (gdb) Notice that, the final lines of output reports the stop as being at breakpoint #1, even though the inferior in not located within some_func, and it's certainly not located at the breakpoint location. I find this behaviour confusing, and propose that this should be changed. However, if I make that change then every reference to breakpoint #1 will be lost from the error message. So, in this commit, in preparation for the later commits, I propose to change the 'Error in testing breakpoint condition:' line to this: Error in testing condition for breakpoint NUMBER: where NUMBER will be filled in as appropriate. Here's the first example with the updated error: (gdb) break foo if (*(int *) 0) == 0 Breakpoint 1 at 0x40111e: file bpcond.c, line 11. (gdb) r Starting program: /tmp/bpcond Error in testing condition for breakpoint 1: Cannot access memory at address 0x0 Breakpoint 1, foo () at bpcond.c:11 11 int a = 32; (gdb) The breakpoint number does now appear twice in the output, but I don't see that as a negative. This commit just changes the one line of the error, and updates the few tests that either included the old error in comments, or actually checked for the error in the expected output. As the only test that checked the line I modified is a Python test, I've added a new test that doesn't rely on Python that checks the error message in detail. While working on the new test, I spotted that it would fail when run with native-gdbserver and native-extended-gdbserver target boards. This turns out to be due to a gdbserver bug. To avoid cluttering this commit I've added a work around to the new test script so that the test passes for the remote boards, in the next few commits I will fix gdbserver, and update the test script to remove the work around.
2023-03-20gdb: don't use the global thread-id in the saved breakpoints fileAndrew Burgess1-1/+4
I noticed that breakpoint::print_recreate_thread was printing the global thread-id. This function is used to implement the 'save breakpoints' command, and should be writing out suitable CLI commands for recreating the current breakpoints. The CLI does not use global thread-ids, but instead uses the inferior specific thread-ids, e.g. "2.1". After some discussion on the mailing list it was suggested that the most consistent solution would be for the saved breakpoints file to always contain the inferior-qualified thread-id, so the file would include "thread 1.1" instead of just "thread 1", even when there is only a single inferior. So, this commit adds print_full_thread_id, which is just like the existing print_thread_id, only it always prints the inferior-qualified thread-id. I then update the existing print_thread_id to make use of this new function, and finally, I update breakpoint::print_recreate_thread to also use this new function. There's a multi-inferior test that confirms the saved breakpoints file correctly includes the fully-qualified thread-id, and I've also updated the single inferior test gdb.base/save-bp.exp to have it validate that the saved breakpoints file includes the inferior-qualified thread-id, even for this single inferior case.