aboutsummaryrefslogtreecommitdiff
path: root/gdb/python/py-breakpoint.c
AgeCommit message (Collapse)AuthorFilesLines
2025-03-03Bploc should try to return full pathSimon Farre1-3/+22
Compilers often emit relative paths in the line number program, relative to the build directory for that compilation unit (if it's DWARF>=4 I think). Therefore use symtab->fullname() when not null as this seemingly has attempted path normalization for the symtab and only fall back on symtab->filename which will never be null if that fails. This has a much better UX. Applications may choose to expose this name as a clickable link to some file, at which point a non-normalized and non-absolute path would lead nowhere. When I wrote this feature the first time, I don't think this relative-to-cu-scheme was as prevalent in the output of gcc/clang for DWARF. Approved-By: Tom Tromey <tom@tromey.com>
2024-11-20gdb/python: fix reference leak in gdb.BreakpointLocation.thread_groupsAndrew Burgess1-1/+1
While reviewing another patch which uses PyList_Append I took a look at our other uses of PyList_Append in GDB. I spotted something odd about the use in bplocpy_get_thread_groups. We do: gdbpy_ref<> num = gdb_py_object_from_ulongest (inf->num); At which point `num` will own a reference to the `int` object. But when we add the object to the result list we do: if (PyList_Append (list.get (), num.release ()) != 0) return nullptr; By calling `release` we pass ownership of the reference to PyList_Append, however, PyList_Append acquires its own reference, it doesn't take ownership of an existing reference. The consequence of this is that we leak the reference held in `num`. This mostly isn't a problem though. For small (< 257) integers Python keeps a single instance of each and just hands out new references. By leaking the references, these small integers will not be cleaned up as the Python interpreter shuts down, but that is only done when GDB exits, so hardly a disaster. As we're dealing with GDB's internal inferior number here, unless the user has 257+ inferiors, we'll not actually be leaking memory. Still, lets do things right. Switch to using `num.get ()`. Now when `num` goes out of scope it will decrement the reference count as needed. Approved-By: Tom Tromey <tom@tromey.com>
2024-11-14gdb/python: missing PyObject_IsTrue error check in bppy_initAndrew Burgess1-6/+7
As with the previous two commits, this commit fixes a location where we called PyObject_IsTrue without including an error check, this time in bppy_init. The 'qualified' argument is supposed to be a bool, the docs say: The optional QUALIFIED argument is a boolean that allows interpreting the function passed in 'spec' as a fully-qualified name. It is equivalent to 'break''s '-qualified' flag (*note Linespec Locations:: and *note Explicit Locations::). It's not totally clear that the only valid values are True or False, but I'm choosing to interpret the docs that way, and so I've added a PyBool_Type check during argument parsing. Now, if a non-bool is passed the user will get a TypeError during argument parsing. I've added a test to cover this case. This is a potentially breaking change to the Python API, but hopefully this will not impact too many people. I've added a NEWS entry to highlight this change. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2024-09-24[gdb/python] Eliminate GDB_PY_SET_HANDLE_EXCEPTIONTom de Vries1-7/+7
Result of: ... $ search="GDB_PY_SET_HANDLE_EXCEPTION (" $ replace="return gdbpy_handle_gdb_exception (-1, " $ sed -i \ "s/$search/$replace/" \ gdb/python/*.c ... Also remove the now unused GDB_PY_SET_HANDLE_EXCEPTION. No functional changes. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-09-24[gdb/python] Eliminate GDB_PY_HANDLE_EXCEPTIONTom de Vries1-2/+2
Result of: ... $ search="GDB_PY_HANDLE_EXCEPTION (" $ replace="return gdbpy_handle_gdb_exception (nullptr, " $ sed -i \ "s/$search/$replace/" \ gdb/python/*.c ... Also remove the now unused GDB_PY_HANDLE_EXCEPTION. No functional changes. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-09-23Automatically add types to Python modulesTom Tromey1-13/+2
PR python/32163 points out that various types provided by gdb are not added to the gdb module, so they aren't available for interactive inspection. I think this is just an oversight. This patch fixes the problem by introducing a new helper function that both readies the type and then adds it to the appropriate module. The patch also poisons PyType_Ready, the idea being to avoid this bug in the future. v2: * Fixed a bug in original patch in gdb.Architecture registration * Added regression test for the types mentioned in the bug Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32163 Reviewed-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
2024-08-27[gdb/python] Use GDB_PY_SET_HANDLE_EXCEPTION more oftenTom de Vries1-2/+1
I found a few more places where we can use GDB_PY_SET_HANDLE_EXCEPTION. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-08-27[gdb/python] Use GDB_PY_HANDLE_EXCEPTION more oftenTom de Vries1-2/+1
I found a few more places where we can use GDB_PY_HANDLE_EXCEPTION. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-08-22[gdb] Add const to catch gdb_exceptionTom de Vries1-2/+2
I did a review of lines containing "catch (gdb_exception" and found a few where we can add const. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-06-24Rename symtab::fullnameTom Tromey1-2/+2
This renames symtab::fullname to m_fullname and adds new accessor methods.
2024-06-13Return gdbpy_ref<> from gdbpy_call_methodTom Tromey1-1/+1
This changes gdbpy_call_method to return a gdbpy_ref<>. This is slightly safer because it makes it simpler to correctly handle reference counts. Reviewed-By: Tom de Vries <tdevries@suse.de>
2024-06-12[gdb/python] Add typesafe wrapper around PyObject_CallMethodTom Tromey1-1/+1
In gdb/python/py-tui.c we have code like this: ... gdbpy_ref<> result (PyObject_CallMethod (m_window.get(), "hscroll", "i", num_to_scroll, nullptr)); ... The nullptr is superfluous, the format string already indicates that there's only one method argument. OTOH, passing no method args does use a nullptr: ... gdbpy_ref<> result (PyObject_CallMethod (m_window.get (), "render", nullptr)); ... Furthermore, choosing the right format string chars can be tricky. Add a typesafe wrapper around PyObject_CallMethod that hides these details, such that we can use the more intuitive: ... gdbpy_ref<> result (gdbpy_call_method (m_window.get(), "hscroll", num_to_scroll)); ... and: ... gdbpy_ref<> result (gdbpy_call_method (m_window.get (), "render")); ... Tested on x86_64-linux. Co-Authored-By: Tom de Vries <tdevries@suse.de> Approved-By: Tom Tromey <tom@tromey.com>
2024-04-25gdb: remove gdbcmd.hSimon Marchi1-1/+1
Most files including gdbcmd.h currently rely on it to access things actually declared in cli/cli-cmds.h (setlist, showlist, etc). To make things easy, replace all includes of gdbcmd.h with includes of cli/cli-cmds.h. This might lead to some unused includes of cli/cli-cmds.h, but it's harmless, and much faster than going through the 170 or so files by hand. Change-Id: I11f884d4d616c12c05f395c98bbc2892950fb00f Approved-By: Tom Tromey <tom@tromey.com>
2024-03-26gdb, gdbserver, gdbsupport: remove includes of early headersSimon Marchi1-1/+0
Now that defs.h, server.h and common-defs.h are included via the `-include` option, it is no longer necessary for source files to include them. Remove all the inclusions of these files I could find. Update the generation scripts where relevant. Change-Id: Ia026cff269c1b7ae7386dd3619bc9bb6a5332837 Approved-By: Pedro Alves <pedro@palves.net>
2024-03-14Remove 'if' from GDB_PY_HANDLE_EXCEPTIONTom Tromey1-8/+2
This removes the embedded 'if' from GDB_PY_HANDLE_EXCEPTION and GDB_PY_SET_HANDLE_EXCEPTION. I believe this 'if' was necessary with the old gdb try/catch macros, but it no longer is: these should only ever be called from a 'catch' block, where it's already known that an exception was thrown. Simon pointed out, though, that in a few spots, these were in facts called outside of 'catch' blocks. This patch cleans up these spots. I also found one spot where a redundant 'return nullptr' could be removed.
2024-01-12Update copyright year range in header of all files managed by GDBAndrew Burgess1-1/+1
This commit is the result of the following actions: - Running gdb/copyright.py to update all of the copyright headers to include 2024, - Manually updating a few files the copyright.py script told me to update, these files had copyright headers embedded within the file, - Regenerating gdbsupport/Makefile.in to refresh it's copyright date, - Using grep to find other files that still mentioned 2023. If these files were updated last year from 2022 to 2023 then I've updated them this year to 2024. I'm sure I've probably missed some dates. Feel free to fix them up as you spot them.
2024-01-12gdb/python: hoist common invalid object repr code into py-utils.cAndrew Burgess1-2/+2
Many object types now have a __repr__() function implementation. A common pattern is that, if an object is invalid, we print its representation as: <TYPENAME (invalid)>. I thought it might be a good idea to move the formatting of this specific representation into a utility function, and then update all of our existing code to call the new function. The only place where I haven't made use of the new function is in unwind_infopy_repr, where we currently return a different string. This case is a little different as the UnwindInfo is invalid because it references a frame, and it is the frame itself which is invalid. That said, I think it would be fine to switch to using the standard format; if the UnwindInfo references an invalid frame, then the UnwindInfo is itself invalid. But changing this would be an actual change in behaviour, while all the other changes in this commit are just refactoring. Approved-By: Tom Tromey <tom@tromey.com>
2023-12-13Use unique_xmalloc_ptr in explicit_location_specTom Tromey1-6/+6
This changes explicit_location_spec to use unique_xmalloc_ptr, removing some manual memory management. Reviewed-By: John Baldwin <jhb@FreeBSD.org>
2023-09-19Use gdb::checked_static_cast for watchpointsTom Tromey1-2/+1
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-08-17gdb: add inferior-specific breakpointsAndrew Burgess1-1/+95
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-07-04gdb: add __repr__() implementation to a few Python typesMatheus Branco Borella1-2/+65
Only a few types in the Python API currently have __repr__() implementations. This patch adds a few more of them. specifically: it adds __repr__() implementations to gdb.Symbol, gdb.Architecture, gdb.Block, gdb.Breakpoint, gdb.BreakpointLocation, and gdb.Type. This makes it easier to play around the GDB Python API in the Python interpreter session invoked with the 'pi' command in GDB, giving more easily accessible tipe information to users. An example of how this would look like: (gdb) pi >> gdb.lookup_type("char") <gdb.Type code=TYPE_CODE_INT name=char> >> gdb.lookup_global_symbol("main") <gdb.Symbol print_name=main> The gdb.Block.__repr__() method shows the first 5 symbols from the block, and then a message to show how many more were elided (if any).
2023-05-25gdb: remove breakpoint_pointer_iteratorSimon Marchi1-2/+2
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: remove bp_location_pointer_iteratorSimon Marchi1-2/+2
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-05gdb/python: add mechanism to manage Python initialization functionsAndrew Burgess1-2/+5
Currently, when we add a new python sub-system to GDB, e.g. py-inferior.c, we end up having to create a new function like gdbpy_initialize_inferior, which then has to be called from the function do_start_initialization in python.c. In some cases (py-micmd.c and py-tui.c), we have two functions gdbpy_initialize_*, and gdbpy_finalize_*, with the second being called from finalize_python which is also in python.c. This commit proposes a mechanism to manage these initialization and finalization calls, this means that adding a new Python subsystem will no longer require changes to python.c or python-internal.h, instead, the initialization and finalization functions will be registered directly from the sub-system file, e.g. py-inferior.c, or py-micmd.c. The initialization and finalization functions are managed through a new class gdbpy_initialize_file in python-internal.h. This class contains a single global vector of all the initialization and finalization functions. In each Python sub-system we create a new gdbpy_initialize_file object, the object constructor takes care of registering the two callback functions. Now from python.c we can call static functions on the gdbpy_initialize_file class which take care of walking the callback list and invoking each callback in turn. To slightly simplify the Python sub-system files I added a new macro GDBPY_INITIALIZE_FILE, which hides the need to create an object. We can now just do this: GDBPY_INITIALIZE_FILE (gdbpy_initialize_registers); One possible problem with this change is that there is now no guaranteed ordering of how the various sub-systems are initialized (or finalized). To try and avoid dependencies creeping in I have added a use of the environment variable GDB_REVERSE_INIT_FUNCTIONS, this is the same environment variable used in the generated init.c file. Just like with init.c, when this environment variable is set we reverse the list of Python initialization (and finalization) functions. As there is already a test that starts GDB with the environment variable set then this should offer some level of protection against dependencies creeping in - though for full protection I guess we'd need to run all gdb.python/*.exp tests with the variable set. I have tested this patch with the environment variable set, and saw no regressions, so I think we are fine right now. One other change of note was for gdbpy_initialize_gdb_readline, this function previously returned void. In order to make this function have the correct signature I've updated its return type to int, and we now return 0 to indicate success. All of the other initialize (and finalize) functions have been made static within their respective sub-system files. There should be no user visible changes after this commit.
2023-02-28gdb: fix mi breakpoint-deleted notifications for thread-specific b/pAndrew Burgess1-0/+3
Background ---------- When a thread-specific breakpoint is deleted as a result of the specific thread exiting the function remove_threaded_breakpoints is called which sets the disposition of the breakpoint to disp_del_at_next_stop and sets the breakpoint number to 0. Setting the breakpoint number to zero has the effect of hiding the breakpoint from the user. We also print a message indicating that the breakpoint has been deleted. It was brought to my attention during a review of another patch[1] that setting a breakpoints number to zero will suppress the MI breakpoint-deleted notification for that breakpoint, and indeed, this can be seen to be true, in delete_breakpoint, if the breakpoint number is zero, then GDB will not notify the breakpoint_deleted observer. It seems wrong that a user created, thread-specific breakpoint, will have a =breakpoint-created notification, but will not have a =breakpoint-deleted notification. I suspect that this is a bug. [1] https://sourceware.org/pipermail/gdb-patches/2023-February/196560.html The First Problem ----------------- During my initial testing I wanted to see how GDB handled the breakpoint after it's number was set to zero. To do this I created the testcase gdb.threads/thread-bp-deleted.exp. This test creates a worker thread, which immediately exits. After the worker thread has exited the main thread spins in a loop. In GDB I break once the worker thread has been created and place a thread-specific breakpoint, then use 'continue&' to resume the inferior in non-stop mode. The worker thread then exits, but the main thread never stops - instead it sits in the spin. I then tried to use 'maint info breakpoints' to see what GDB thought of the thread-specific breakpoint. Unfortunately, GDB crashed like this: (gdb) continue& Continuing. (gdb) [Thread 0x7ffff7c5d700 (LWP 1202458) exited] Thread-specific breakpoint 3 deleted - thread 2 no longer in the thread list. maint info breakpoints ... snip some output ... Fatal signal: Segmentation fault ----- Backtrace ----- 0x5ffb62 gdb_internal_backtrace_1 ../../src/gdb/bt-utils.c:122 0x5ffc05 _Z22gdb_internal_backtracev ../../src/gdb/bt-utils.c:168 0x89965e handle_fatal_signal ../../src/gdb/event-top.c:964 0x8997ca handle_sigsegv ../../src/gdb/event-top.c:1037 0x7f96f5971b1f ??? /usr/src/debug/glibc-2.30-2-gd74461fa34/nptl/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0 0xe602b0 _Z15print_thread_idP11thread_info ../../src/gdb/thread.c:1439 0x5b3d05 print_one_breakpoint_location ../../src/gdb/breakpoint.c:6542 0x5b462e print_one_breakpoint ../../src/gdb/breakpoint.c:6702 0x5b5354 breakpoint_1 ../../src/gdb/breakpoint.c:6924 0x5b58b8 maintenance_info_breakpoints ../../src/gdb/breakpoint.c:7009 ... etc ... As the thread-specific breakpoint is set to disp_del_at_next_stop, and GDB hasn't stopped yet, then the breakpoint still exists in the global breakpoint list. The breakpoint will not show in 'info breakpoints' as its number is zero, but it will show in 'maint info breakpoints'. As GDB prints the breakpoint, the thread-id for the breakpoint is printed as part of the 'stop only in thread ...' line. Printing the thread-id involves calling find_thread_global_id to convert the global thread-id into a thread_info*. Then calling print_thread_id to convert the thread_info* into a string. The problem is that find_thread_global_id returns nullptr as the thread for the thread-specific breakpoint has exited. The print_thread_id assumes it will be passed a non-nullptr. As a result GDB crashes. In this commit I've added an assert to print_thread_id (gdb/thread.c) to check that the pointed passed in is not nullptr. This assert would have triggered in the above case before GDB crashed. MI Notifications: The Dangers Of Changing A Breakpoint's Number --------------------------------------------------------------- Currently the delete_breakpoint function doesn't trigger the breakpoint_deleted observer for any breakpoint with the number zero. There is a comment explaining why this is the case in the code; it's something about watchpoints. But I did consider just removing the 'is the number zero' guard and always triggering the breakpoint_deleted observer, figuring that I'd then fix the watchpoint issue some other way. But I realised this wasn't going to be good enough. When the MI notification was delivered the number would be zero, so any frontend parsing the notifications would not be able to match =breakpoint-deleted notification to the earlier =breakpoint-created notification. What this means is that, at the point the breakpoint_deleted observer is called, the breakpoint's number must be correct. MI Notifications: The Dangers Of Delaying Deletion -------------------------------------------------- The test I used to expose the above crash also brought another problem to my attention. In the above test we used 'continue&' to resume, after which a thread exited, but the inferior didn't stop. Recreating the same test in the MI looks like this: -break-insert -p 2 main ^done,bkpt={number="2",type="breakpoint",disp="keep",...<snip>...} (gdb) -exec-continue ^running *running,thread-id="all" (gdb) ~"[Thread 0x7ffff7c5d700 (LWP 987038) exited]\n" =thread-exited,id="2",group-id="i1" ~"Thread-specific breakpoint 2 deleted - thread 2 no longer in the thread list.\n" At this point the we have a single thread left, which is still running: -thread-info ^done,threads=[{id="1",target-id="Thread 0x7ffff7c5eb80 (LWP 987035)",name="thread-bp-delet",state="running",core="4"}],current-thread-id="1" (gdb) Notice that we got the =thread-exited notification from GDB as soon as the thread exited. We also saw the CLI line from GDB, the line explaining that breakpoint 2 was deleted. But, as expected, we didn't see the =breakpoint-deleted notification. I say "as expected" because the number was set to zero. But, even if the number was not set to zero we still wouldn't see the notification. The MI notification is driven by the breakpoint_deleted observer, which is only called when we actually delete the breakpoint, which is only done the next time GDB stops. Now, maybe this is fine. The notification is delivered a little late. But remember, by setting the number to zero the breakpoint will be hidden from the user, for example, the breakpoint is removed from the MI's -break-info command output. This means that GDB is in a position where the breakpoint doesn't show up in the breakpoint table, but a =breakpoint-deleted notification has not yet been sent out. This doesn't seem right to me. What this means is that, when the thread exits, we should immediately be sending out the =breakpoint-deleted notification. We should not wait for GDB to next stop before sending the notification. The Solution ------------ My proposed solution is this; in remove_threaded_breakpoints, instead of setting the disposition to disp_del_at_next_stop and setting the number to zero, we now just call delete_breakpoint directly. The notification will now be sent out immediately; as soon as the thread exits. As the number has not changed when delete_breakpoint is called, the notification will have the correct number. And as the breakpoint is immediately removed from the breakpoint list, we no longer need to worry about 'maint info breakpoints' trying to print the thread-id for an exited thread. My only concern is that calling delete_breakpoint directly seems so obvious that I wonder why the original patch (that added remove_threaded_breakpoints) didn't take this approach. This code was added in commit 49fa26b0411d, but the commit message offers no clues to why this approach was taken, and the original email thread offers no insights either[2]. There are no test regressions after making this change, so I'm hopeful that this is going to be fine. [2] https://sourceware.org/pipermail/gdb-patches/2013-September/106493.html The Complication ---------------- Of course, it couldn't be that simple. The script gdb.python/py-finish-breakpoint.exp had some regressions during testing. The problem was with the FinishBreakpoint.out_of_scope callback implementation. This callback is supposed to trigger whenever the FinishBreakpoint goes out of scope; and this includes when the thread for the breakpoint exits. The problem I ran into is the Python FinishBreakpoint implementation. Specifically, after this change I was loosing some of the out_of_scope calls. The problem is that the out_of_scope call (of which I'm interested) is triggered from the inferior_exit observer. Before my change the observers were called in this order: thread_exit inferior_exit breakpoint_deleted The inferior_exit would trigger the out_of_scope call. After my change the breakpoint_deleted notification (for thread-specific breakpoints) occurs earlier, as soon as the thread-exits, so now the order is: thread_exit breakpoint_deleted inferior_exit Currently, after the breakpoint_deleted call the Python object associated with the breakpoint is released, so, when we get to the inferior_exit observer, there's no longer a Python object to call the out_of_scope method on. My solution is to follow the model for how bpfinishpy_pre_stop_hook and bpfinishpy_post_stop_hook are called, this is done from gdbpy_breakpoint_cond_says_stop in py-breakpoint.c. I've now added a new bpfinishpy_pre_delete_hook gdbpy_breakpoint_deleted in py-breakpoint.c, and from this new hook function I check and where needed call the out_of_scope method. With this fix in place I now see the gdb.python/py-finish-breakpoint.exp test fully passing again. Testing ------- Tested on x86-64/Linux with unix, native-gdbserver, and native-extended-gdbserver boards. New tests added to covers all the cases I've discussed above. Approved-By: Pedro Alves <pedro@palves.net>
2023-02-12gdb: use -1 for breakpoint::task default valueAndrew Burgess1-3/+3
Within the breakpoint struct we have two fields ::thread and ::task which are used for thread or task specific breakpoints. When a breakpoint doesn't have a specific thread or task then these fields have the values -1 and 0 respectively. There's no particular reason (as far as I can tell) why these two "default" values are different, and I find the difference a little confusing. Long term I'd like to potentially fold these two fields into a single field, but that isn't what this commit does. What this commit does is switch to using -1 as the "default" value for both fields, this means that the default for breakpoint::task has changed from 0 to -1. I've updated all the code I can find that relied on the value of 0, and I see no test regressions, especially in gdb.ada/tasks.exp, which still fully passes. There should be no user visible changes after this commit. Approved-By: Pedro Alves <pedro@palves.net>
2023-02-12gdb: only allow one of thread or task on breakpoints or watchpointsAndrew Burgess1-0/+14
After this mailing list posting: https://sourceware.org/pipermail/gdb-patches/2023-February/196607.html it seems to me that in practice an Ada task maps 1:1 with a GDB thread, and so it doesn't really make sense to allow uses to give both a thread and a task within a single breakpoint or watchpoint condition. This commit updates GDB so that the user will get an error if both are specified. I've added new tests to cover the CLI as well as the Python and Guile APIs. For the Python and Guile testing, as far as I can tell, this was the first testing for this corner of the APIs, so I ended up adding more than just a single test. For documentation I've added a NEWS entry, but I've not added anything to the docs themselves. Currently we document the commands with a thread-id or task-id as distinct command, e.g.: 'break LOCSPEC task TASKNO' 'break LOCSPEC task TASKNO if ...' 'break LOCSPEC thread THREAD-ID' 'break LOCSPEC thread THREAD-ID if ...' As such, I don't believe there is any indication that combining 'task' and 'thread' would be expected to work; it seems clear to me in the above that those four options are all distinct commands. I think the NEWS entry is enough that if someone is combining these keywords (it's not clear what the expected behaviour would be in this case) then they can figure out that this was a deliberate change in GDB, but for a new user, the manual doesn't suggest combining them is OK, and any future attempt to combine them will give an error. Approved-By: Pedro Alves <pedro@palves.net>
2023-01-01Update copyright year range in header of all files managed by GDBJoel Brobecker1-1/+1
This commit is the result of running the gdb/copyright.py script, which automated the update of the copyright year range for all source files managed by the GDB project to be updated to include year 2023.
2022-12-15gdb: remove static buffer in command_line_inputSimon Marchi1-1/+1
[I sent this earlier today, but I don't see it in the archives. Resending it through a different computer / SMTP.] The use of the static buffer in command_line_input is becoming problematic, as explained here [1]. In short, with this patch [2] that attempt to fix a post-hook bug, when running gdb.base/commands.exp, we hit a case where we read a "define" command line from a script file using command_command_line_input. The command line is stored in command_line_input's static buffer. Inside the define command's execution, we read the lines inside the define using command_line_input, which overwrites the define command, in command_line_input's static buffer. After the execution of the define command, execute_command does a command look up to see if a post-hook is registered. For that, it uses a now stale pointer that used to point to the define command, in the static buffer, causing a use-after-free. Note that the pointer in execute_command points to the dynamically-allocated buffer help by the static buffer in command_line_input, not to the static object itself, hence why we see a use-after-free. Fix that by removing the static buffer. I initially changed command_line_input and other related functions to return an std::string, which is the obvious but naive solution. The thing is that some callees don't need to return an allocated string, so this this an unnecessary pessimization. I changed it to passing in a reference to an std::string buffer, which the callee can use if it needs to return dynamically-allocated content. It fills the buffer and returns a pointers to the C string inside. The callees that don't need to return dynamically-allocated content simply don't use it. So, it started with modifying command_line_input as described above, all the other changes derive directly from that. One slightly shady thing is in handle_line_of_input, where we now pass a pointer to an std::string's internal buffer to readline's history_value function, which takes a `char *`. I'm pretty sure that this function does not modify the input string, because I was able to change it (with enough massaging) to take a `const char *`. A subtle change is that we now clear a UI's line buffer using a SCOPE_EXIT in command_line_handler, after executing the command. This was previously done by this line in handle_line_of_input: /* We have a complete command line now. Prepare for the next command, but leave ownership of memory to the buffer . */ cmd_line_buffer->used_size = 0; I think the new way is clearer. [1] https://inbox.sourceware.org/gdb-patches/becb8438-81ef-8ad8-cc42-fcbfaea8cddd@simark.ca/ [2] https://inbox.sourceware.org/gdb-patches/20221213112241.621889-1-jan.vrany@labware.com/ Change-Id: I8fc89b1c69870c7fc7ad9c1705724bd493596300 Reviewed-By: Tom Tromey <tom@tromey.com>
2022-12-07Remove unnecessary xstrdup from bppy_initTom Tromey1-6/+4
I saw that bppy_init used a non-const "char *". Fixing this revealed that the xstrdup here was also unnecessary, so this patch removes it.
2022-10-20gdb/python: break more dependencies between gdbpy_initialize_* functionsAndrew Burgess1-2/+21
In a later commit in this series I will propose removing all of the explicit gdbpy_initialize_* calls from python.c and replace these calls with a more generic mechanism. One of the side effects of this generic mechanism is that the order in which the various Python sub-systems within GDB are initialized is no longer guaranteed. On the whole I don't think this matters, most of the sub-systems are independent of each other, though testing did reveal a few places where we did have dependencies, though I don't think those dependencies were explicitly documented in comment anywhere. This commit is similar to the previous one, and fixes the second dependency issue that I found. In this case the finish_breakpoint_object_type uses the breakpoint_object_type as its tp_base, this means that breakpoint_object_type must have been initialized with a call to PyType_Ready before finish_breakpoint_object_type can be initialized. Previously we depended on the ordering of calls to gdbpy_initialize_breakpoints and gdbpy_initialize_finishbreakpoints in python.c. After this commit a new function gdbpy_breakpoint_init_breakpoint_type exists, this function ensures that breakpoint_object_type has been initialized, and can be called from any gdbpy_initialize_* function. I feel that this change makes the dependency explicit, which I think is a good thing. There should be no user visible changes after this commit.
2022-08-31Use ui_out_redirect_pop in more placesTom Tromey1-3/+1
This changes ui_out_redirect_pop to also perform the redirection, and then updates several sites to use this, rather than explicit redirects.
2022-07-28gdb/python: Add BreakpointLocation typeSimon Farre1-0/+316
PR python/18385 v7: This version addresses the issues pointed out by Tom. Added nullchecks for Python object creations. Changed from using PyLong_FromLong to the gdb_py-versions. Re-factored some code to make it look more cohesive. Also added the more safe Python reference count decrement PY_XDECREF, even though the BreakpointLocation type is never instantiated by the user (explicitly documented in the docs) decrementing < 0 is made impossible with the safe call. Tom pointed out that using the policy class explicitly to decrement a reference counted object was not the way to go, so this has instead been wrapped in a ref_ptr that handles that for us in blocpy_dealloc. Moved macro from py-internal to py-breakpoint.c. Renamed section at the bottom of commit message "Patch Description". v6: This version addresses the points Pedro gave in review to this patch. Added the attributes `function`, `fullname` and `thread_groups` as per request by Pedro with the argument that it more resembles the output of the MI-command "-break-list". Added documentation for these attributes. Cleaned up left overs from copy+paste in test suite, removed hard coding of line numbers where possible. Refactored some code to use more c++-y style range for loops wrt to breakpoint locations. Changed terminology, naming was very inconsistent. Used a variety of "parent", "owner". Now "owner" is the only term used, and the field in the gdb_breakpoint_location_object now also called "owner". v5: Changes in response to review by Tom Tromey: - Replaced manual INCREF/DECREF calls with gdbpy_ref ptrs in places where possible. - Fixed non-gdb style conforming formatting - Get parent of bploc increases ref count of parent. - moved bploc Python definition to py-breakpoint.c The INCREF of self in bppy_get_locations is due to the individual locations holding a reference to it's owner. This is decremented at de-alloc time. The reason why this needs to be here is, if the user writes for instance; py loc = gdb.breakpoints()[X].locations[Y] The breakpoint owner object is immediately going out of scope (GC'd/dealloced), and the location object requires it to be alive for as long as it is alive. Thanks for your review, Tom! v4: Fixed remaining doc issues as per request by Eli. v3: Rewritten commit message, shortened + reworded, added tests. Patch Description Currently, the Python API lacks the ability to query breakpoints for their installed locations, and subsequently, can't query any information about them, or enable/disable individual locations. This patch solves this by adding Python type gdb.BreakpointLocation. The type is never instantiated by the user of the Python API directly, but is produced by the gdb.Breakpoint.locations attribute returning a list of gdb.BreakpointLocation. gdb.Breakpoint.locations: The attribute for retrieving the currently installed breakpoint locations for gdb.Breakpoint. Matches behavior of the "info breakpoints" command in that it only returns the last known or currently inserted breakpoint locations. BreakpointLocation contains 7 attributes 6 read-only attributes: owner: location owner's Python companion object source: file path and line number tuple: (string, long) / None address: installed address of the location function: function name where location was set fullname: fullname where location was set thread_groups: thread groups (inferiors) where location was set. 1 writeable attribute: enabled: get/set enable/disable this location (bool) Access/calls to these, can all throw Python exceptions (documented in the online documentation), and that's due to the nature of how breakpoint locations can be invalidated "behind the scenes", either by them being removed from the original breakpoint or changed, like for instance when a new symbol file is loaded, at which point all breakpoint locations are re-created by GDB. Therefore this patch has chosen to be non-intrusive: it's up to the Python user to re-request the locations if they become invalid. Also there's event handlers that handle new object files etc, if a Python user is storing breakpoint locations in some larger state they've built up, refreshing the locations is easy and it only comes with runtime overhead when the Python user wants to use them. gdb.BreakpointLocation Python type struct "gdbpy_breakpoint_location_object" is found in python-internal.h Its definition, layout, methods and functions are found in the same file as gdb.Breakpoint (py-breakpoint.c) 1 change was also made to breakpoint.h/c to make it possible to enable and disable a bp_location* specifically, without having its LOC_NUM, as this number also can change arbitrarily behind the scenes. Updated docs & news file as per request. Testsuite: tests the .source attribute and the disabling of individual locations. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=18385 Change-Id: I302c1c50a557ad59d5d18c88ca19014731d736b0
2022-06-17Convert location_spec_to_string to a methodPedro Alves1-1/+1
This converts location_spec_to_string to a method of location_spec, simplifying the code using it, as it no longer has to use std::unique_ptr::get(). Change-Id: I621bdad8ea084470a2724163f614578caf8f2dd5
2022-06-17Eliminate the two-level data structures behind location_specsPedro Alves1-9/+12
Currently, there's the location_spec hierarchy, and then some location_spec subclasses have their own struct type holding all their data fields. I.e., there is this: location_spec explicit_location_spec linespec_location_spec address_location_spec probe_location_spec and then these separate types: explicit_location linespec_location where: explicit_location_spec has-a explicit_location linespec_location_spec has-a linespec_location This patch eliminates explicit_location and linespec_location, inlining their members in the corresponding location_spec type. The location_spec subclasses were the ones currently defined in location.c, so they are moved to the header. Since the definitions of the classes are now visible, we no longer need location_spec_deleter. Some constructors that are used for cloning location_specs, like: explicit explicit_location_spec (const struct explicit_location *loc) ... were converted to proper copy ctors. In the process, initialize_explicit_location is eliminated, and some functions that returned the "data type behind a locspec", like get_linespec_location are converted to downcast functions, like as_linespec_location_spec. Change-Id: Ia31ccef9382b25a52b00fa878c8df9b8cf2a6c5a
2022-06-17event_location -> location_specPedro Alves1-10/+10
Currently, GDB internally uses the term "location" for both the location specification the user input (linespec, explicit location, or an address location), and for actual resolved locations, like the breakpoint locations, or the result of decoding a location spec to SaLs. This is expecially confusing in the breakpoints module, as struct breakpoint has these two fields: breakpoint::location; breakpoint::loc; "location" is the location spec, and "loc" is the resolved locations. And then, we have a method called "locations()", which returns the resolved locations as range... The location spec type is presently called event_location: /* Location we used to set the breakpoint. */ event_location_up location; and it is described like this: /* The base class for all an event locations used to set a stop event in the inferior. */ struct event_location { and even that is incorrect... Location specs are used for finding actual locations in the program in scenarios that have nothing to do with stop events. E.g., "list" works with location specs. To clean all this confusion up, this patch renames "event_location" to "location_spec" throughout, and then all the variables that hold a location spec, they are renamed to include "spec" in their name, like e.g., "location" -> "locspec". Similarly, functions that work with location specs, and currently have just "location" in their name are renamed to include "spec" in their name too. Change-Id: I5814124798aa2b2003e79496e78f95c74e5eddca
2022-03-29Unify gdb printf functionsTom Tromey1-1/+1
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-23gdb/python: remove Python 2/3 compatibility macrosSimon Marchi1-6/+6
New in this version: - Rebase on master, fix a few more issues that appeared. python-internal.h contains a number of macros that helped make the code work with both Python 2 and 3. Remove them and adjust the code to use the Python 3 functions. Change-Id: I99a3d80067fb2d65de4f69f6473ba6ffd16efb2d
2022-01-26Change how Python architecture and language are handledTom Tromey1-13/+6
Currently, gdb's Python layer captures the current architecture and language when "entering" Python code. This has some undesirable effects, and so this series changes how this is handled. First, there is code like this: gdbpy_enter enter_py (python_gdbarch, python_language); This is incorrect, because both of these are NULL when not otherwise assigned. This can cause crashes in some cases -- I've added one to the test suite. (Note that this crasher is just an example, other ones along the same lines are possible.) Second, when the language is captured in this way, it means that Python code cannot affect the current language for its own purposes. It's reasonable to want to write code like this: gdb.execute('set language mumble') ... stuff using the current language gdb.execute('set language previous-value') However, this won't actually work, because the language is captured on entry. I've added a test to show this as well. This patch changes gdb to try to avoid capturing the current values. The Python concept of the current gdbarch is only set in those few cases where a non-default value is computed or needed; and the language is not captured at all -- instead, in the cases where it's required, the current language is temporarily changed.
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-11-16gdb/gdbsupport: make xstrprintf and xstrvprintf return a unique_ptrAndrew Burgess1-1/+1
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-20Use unique_xmalloc_ptr in breakpointTom Tromey1-1/+1
This changes struct breakpoint to use unique_xmalloc_ptr in a couple of spots, removing a bit of manual memory management.
2021-10-20Use unique_xmalloc_ptr in watchpointTom Tromey1-1/+1
This changes struct watchpoint to use unique_xmalloc_ptr in a couple of places, removing a bit of manual memory management.
2021-06-25gdb/python: allow for catchpoint type breakpoints in pythonAndrew Burgess1-1/+5
This commit adds initial support for catchpoints to the python breakpoint API. This commit adds a BP_CATCHPOINT constant which corresponds to GDB's internal bp_catchpoint. The new constant is documented in the manual. The user can't create breakpoints with type BP_CATCHPOINT after this commit, but breakpoints that already exist, obtained with the `gdb.breakpoints` function, can now have this type. Additionally, when a stop event is reported for hitting a catchpoint, GDB will now report a BreakpointEvent with the attached breakpoint being of type BP_CATCHPOINT - previously GDB would report a generic StopEvent in this situation. gdb/ChangeLog: * NEWS: Mention Python BP_CATCHPOINT feature. * python/py-breakpoint.c (pybp_codes): Add bp_catchpoint support. (bppy_init): Likewise. (gdbpy_breakpoint_created): Likewise. gdb/doc/ChangeLog: * python.texinfo (Breakpoints In Python): Add BP_CATCHPOINT description. gdb/testsuite/ChangeLog: * gdb.python/py-breakpoint.c (do_throw): New function. (main): Call do_throw. * gdb.python/py-breakpoint.exp (test_catchpoints): New proc.
2021-05-27gdb: remove iterate_over_breakpoints functionSimon Marchi1-16/+11
Now that we have range functions that let us use ranged for loops, we can remove iterate_over_breakpoints in favor of those, which are easier to read and write. This requires exposing the declaration of all_breakpoints and all_breakpoints_safe in breakpoint.h, as well as the supporting types. Change some users of iterate_over_breakpoints to use all_breakpoints, when they don't need to delete the breakpoint, and all_breakpoints_safe otherwise. gdb/ChangeLog: * breakpoint.h (iterate_over_breakpoints): Remove. Update callers to use all_breakpoints or all_breakpoints_safe. (breakpoint_range, all_breakpoints, breakpoint_safe_range, all_breakpoints_safe): Move here. * breakpoint.c (all_breakpoints, all_breakpoints_safe): Make non-static. (iterate_over_breakpoints): Remove. * python/py-finishbreakpoint.c (bpfinishpy_detect_out_scope_cb): Return void. * python/py-breakpoint.c (build_bp_list): Add comment, reverse return value logic. * guile/scm-breakpoint.c (bpscm_build_bp_list): Return void. Change-Id: Idde764a1f577de0423e4f2444a7d5cdb01ba5e48
2021-05-09gdb/py: add some debugging to py-breakpoint.cAndrew Burgess1-3/+56
Adds some new debugging to python/py-breakpoint.c. gdb/ChangeLog: * python/py-breakpoint.c (pybp_debug): New static global. (show_pybp_debug): New function. (pybp_debug_printf): Define. (PYBP_SCOPED_DEBUG_ENTER_EXIT): Define. (gdbpy_breakpoint_created): Add some debugging. (gdbpy_breakpoint_deleted): Likewise. (gdbpy_breakpoint_modified): Likewise. (_initialize_py_breakpoint): New function. gdb/doc/ChangeLog: * python.texinfo (Python Commands): Document 'set debug py-breakpoint' and 'show debug py-breakpoint'.
2021-04-24gdbsupport, gdb: give names to observersSimon Marchi1-3/+6
Give a name to each observer, this will help produce more meaningful debug message. gdbsupport/ChangeLog: * observable.h (class observable) <struct observer> <observer>: Add name parameter. <name>: New field. <attach>: Add name parameter, update all callers. Change-Id: Ie0cc4664925215b8d2b09e026011b7803549fba0
2021-04-21gdb/breakpoint: add a 'force_condition' parameter to 'create_breakpoint'Tankut Baris Aktemur1-1/+1
The 'create_breakpoint' function takes a 'parse_extra' argument that determines whether the condition, thread, and force-condition specifiers should be parsed from the extra string or be used from the function arguments. However, for the case when 'parse_extra' is false, there is no way to pass the force-condition specifier. This patch adds it as a new argument. Also, in the case when parse_extra is false, the current behavior is as if the condition is being forced. This is a bug. The default behavior should reject the breakpoint. See below for a demo of this incorrect behavior. (The MI command '-break-insert' uses the 'create_breakpoint' function with parse_extra=0.) $ gdb -q --interpreter=mi3 /tmp/simple =thread-group-added,id="i1" =cmd-param-changed,param="history save",value="on" =cmd-param-changed,param="auto-load safe-path",value="/" ~"Reading symbols from /tmp/simple...\n" (gdb) -break-insert -c junk -f main &"warning: failed to validate condition at location 1, disabling:\n " &"No symbol \"junk\" in current context.\n" ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="<MULTIPLE>",cond="junk",times="0",original-location="main",locations=[{number="1.1",enabled="N",addr="0x000000000000114e",func="main",file="/tmp/simple.c",fullname="/tmp/simple.c",line="2",thread-groups=["i1"]}]} (gdb) break main if junk &"break main if junk\n" &"No symbol \"junk\" in current context.\n" ^error,msg="No symbol \"junk\" in current context." (gdb) break main -force-condition if junk &"break main -force-condition if junk\n" ~"Note: breakpoint 1 also set at pc 0x114e.\n" &"warning: failed to validate condition at location 1, disabling:\n " &"No symbol \"junk\" in current context.\n" ~"Breakpoint 2 at 0x114e: file /tmp/simple.c, line 2.\n" =breakpoint-created,bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="<MULTIPLE>",cond="junk",times="0",original-location="main",locations=[{number="2.1",enabled="N",addr="0x000000000000114e",func="main",file="/tmp/simple.c",fullname="/tmp/simple.c",line="2",thread-groups=["i1"]}]} ^done (gdb) After applying this patch, we get the behavior below: (gdb) -break-insert -c junk -f main ^error,msg="No symbol \"junk\" in current context." This restores the behavior that is present in the existing releases. gdb/ChangeLog: 2021-04-21 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * breakpoint.h (create_breakpoint): Add a new parameter, 'force_condition'. * breakpoint.c (create_breakpoint): Use the 'force_condition' argument when 'parse_extra' is false to check if the condition is invalid at all of the breakpoint locations. Update the users below. (break_command_1) (dprintf_command) (trace_command) (ftrace_command) (strace_command) (create_tracepoint_from_upload): Update. * guile/scm-breakpoint.c (gdbscm_register_breakpoint_x): Update. * mi/mi-cmd-break.c (mi_cmd_break_insert_1): Update. * python/py-breakpoint.c (bppy_init): Update. * python/py-finishbreakpoint.c (bpfinishpy_init): Update. gdb/testsuite/ChangeLog: 2021-04-21 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.mi/mi-break.exp: Extend with checks for invalid breakpoint conditions.
2021-01-21Add Python support for hardware breakpointsHannes Domani1-2/+6
This allows the creation of hardware breakpoints in Python with gdb.Breakpoint(type=gdb.BP_HARDWARE_BREAKPOINT) And they are included in the sequence returned by gdb.breakpoints(). gdb/ChangeLog: 2021-01-21 Hannes Domani <ssbssa@yahoo.de> PR python/19151 * python/py-breakpoint.c (bppy_get_location): Handle bp_hardware_breakpoint. (bppy_init): Likewise. (gdbpy_breakpoint_created): Likewise. gdb/doc/ChangeLog: 2021-01-21 Hannes Domani <ssbssa@yahoo.de> PR python/19151 * python.texi (Breakpoints In Python): Document gdb.BP_HARDWARE_BREAKPOINT. gdb/testsuite/ChangeLog: 2021-01-21 Hannes Domani <ssbssa@yahoo.de> PR python/19151 * gdb.python/py-breakpoint.exp: Add tests for hardware breakpoints.
2021-01-01Update copyright year range in all GDB filesJoel Brobecker1-1/+1
This commits the result of running gdb/copyright.py as per our Start of New Year procedure... gdb/ChangeLog Update copyright year range in copyright header of all GDB files.