aboutsummaryrefslogtreecommitdiff
path: root/gdb
AgeCommit message (Collapse)AuthorFilesLines
2024-12-16Re-run isortTom Tromey1-1/+1
I noticed that an earlier commit caused a change in the isort output. This patch repairs the problem.
2024-12-16gdb/testsuite: rename test source file to avoid glibc clashAndrew Burgess2-14/+42
After posting this series: https://inbox.sourceware.org/gdb-patches/cover.1733742925.git.aburgess@redhat.com I got a failure report from the Linaro CI system. I eventually tracked the issue down to a filename clash with glibc. I was able to reproduce the issue when I installed the glibc debug information on to my local machine, and ran the gdb.base/dlmopen.exp test as updated in the above series. Here's what's happening: There is a file called dlmopen.c within glibc, within the glibc source tree the file can be found at ./dlfcn/dlmopen.c. When this file is compiled it appears that the glibc build system first enters the dlfcn directory, and then compiles the file using the relative path ./dlmopen.c, here's a snippet of the DWARF: <0><d5d27>: Abbrev Number: 12 (DW_TAG_compile_unit) <d5d28> DW_AT_producer : (alt indirect string, offset: 0x16433) t <d5d2c> DW_AT_language : 29 (C11) <d5d2d> DW_AT_name : (indirect line string, offset: 0x5c8f): dlmopen.c <d5d31> DW_AT_comp_dir : (indirect line string, offset: 0xb478): /usr/src/debug/glibc-2.38-19.fc39.x86_64/dlfcn <d5d35> DW_AT_low_pc : 0x8a4c0 <d5d3d> DW_AT_high_pc : 408 <d5d3f> DW_AT_stmt_list : 0x68ec1 The important thing here is the DW_AT_name, which is just "dlmopen.c". The gdb.base/dlmopen.exp test also has a source file called "dlmopen.c". The dlmopen.exp test makes use of the clean_restart TCL proc, which calls gdb_reinitialize_dir, which resets the source directories search path to '$cdir:$cwd', and then prepends the test source directory to the front of the list, so the source directory search path will look something like: /tmp/src/gdb/testsuite/gdb.base/gdb.base:$cdir:$cwd In the existing test we try to place a breakpoint on 'dlmopen.c:64'. This is the line tagged 'bp.main' in the source file. This currently works fine. GDB searches through the symtabs and finds two matches, the test dlmopen.c, and the glibc dlmopen.c. For each GDB tries to convert line 64 into an address. For the testsuite source file this is fine, we get the address of the line tagged 'bp.main' from the source, and the breakpoint is created. For the glibc source file though, at least, for the version available to me, line 64 happens to be the closing '}' of a function, and there isn't a line table entry for this exact line. So GDB searches forward looking for the next line in order to place a breakpoint there. The next line GDB finds is the start of the next function, and so GDB rejects this location due to commit: commit dcaa85e58c4ef50a92908e071ded631ce48c971c Date: Wed May 1 10:47:47 2024 +0100 gdb: reject inserting breakpoints between functions So we managed to avoid creating two breakpoint locations in this case, but only by pure good luck. In my updates to the test though I try to create a breakpoint at line 61 in addition to the breakpoint at line 64. So now the breakpoint spec is 'dlmopen.c:61'. Just as before, GDB identifies the 'dlmopen.c' could mean two files, and searches for line 61 in both. The test source works as expected and the breakpoint is created in the desired location. But this time, line 61 in the glibc source file is an actual line, with actual code, and so GDB places a breakpoint at this location. This second breakpoint, in glibc is entirely unexpected (by the dlmopen.exp test script). Unfortunately, the inferior hits this second glibc breakpoint before it hits the actual breakpoint within the main test executable, this throws the test off and causes some failures. In trying to fix this, I did wonder if I could just specify the full path to the source file, instead of using just 'dlmopen.c:61'. However, this doesn't work. Remember that the glibc source file is recorded as just 'dlmopen.c'. So, when GDB tries to figure out the absolute path to this source file, the source directory search path is used. In this case, the first entry in the source directory search path is the gdb.base/ directory in the GDB source tree. GDB looks in this directory and finds a dlmopen.c, and so GDB assumes that this is the file in question. Thus, GDB actually thinks that both files _are_ the same source file. Indeed, when GDB stops at the incorrect (glibc) breakpoint, and lists the source code, it actually lists the source code from the correct file. This confused me to begin with, GDB reported the wrong function (the glibc function), but listed code from the correct file and line. Now on my machine I have installed the package that provides the glibc source code. If I change the source directory search path so that $cdir is first instead of the gdb.base/ from the GDB source tree, this fixes the listing the wrong file problem. GDB does not realise that the files are different, and if I create the breakpoint using the absolute path then only a single breakpoint location is created. However, this relies on the developer having both the glibc debug information, and the glibc source package installed, this doesn't seem like a great requirement to have in place. So instead, I propose that we just take the easy way out, rename the test source file. By doing this all the issues are avoided. The test now creates a breakpoint at 'dlmopen-main.c:61', and there is only one file with this name found, so we only get a single breakpoint location created. I renamed the source file, but not the dlmopen.exp file because the test already makes use of multiple source files, so having a range of different names didn't feel that bad, but if this bothers people, I could rename both the .exp and main .c file, just let me know. If you want to explore this issue for yourself then try with installing the glibc debug information for your system, and ensure that your GDBs under test are able to find the glibc debug information. You can then either apply the series I linked above, or, you can modify the existing test source so that the line tagged as 'bp.main' becomes line 61, I just deleted 3 lines from the big comment at the head of the file. Of course, reproducing this does depend on how glibc is compiled, which could change from system to system, or overtime. I reproduced this issue on Fedora 39 with glibc-2.38-19. With this patch applied I no longer see any regressions when I apply the above linked series. While making these changes I took the opportunity to update the test script to make better use of standard_testfile and build_executable. Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
2024-12-14fix Windows buildoltolm1-1/+2
Fix the Windows build that was broken in "Introduce \"command\" styling". Approved-By: Tom Tromey <tom@tromey.com>
2024-12-14[gdb/dap] Fix regressions with python 3.6Tom de Vries1-1/+2
With test-case gdb.dap/ada-arrays.exp, on Leap openSUSE 15.6 with python 3.6, I run into: ... Python Exception <class 'TypeError'>: 'type' object is not subscriptable Error occurred in Python: 'type' object is not subscriptable ERROR: tcl error sourcing ada-arrays.exp. ... This is due to using a python 3.9 construct: ... thread_ids: dict[int, int] = {} ... Fix this by using typing.Dict instead. Tested on x86_64-linux.
2024-12-13[gdb] Fix tsan warning: signal handler spoils errnoTom de Vries3-0/+3
When building gdb with -fsanitize=thread and running test-case gdb.base/bg-exec-sigint-bp-cond.exp, I run into: ... ==================^M WARNING: ThreadSanitizer: signal handler spoils errno (pid=25422)^M #0 handler_wrapper gdb/posix-hdep.c:66^M #1 decltype ({parm#2}({parm#3}...)) gdb::handle_eintr<>() \ gdbsupport/eintr.h:67^M #2 gdb::waitpid(int, int*, int) gdbsupport/eintr.h:78^M #3 run_under_shell gdb/cli/cli-cmds.c:926^M ... Likewise in: - tui_sigwinch_handler with test-case gdb.python/tui-window.exp, and - handle_sighup with test-case gdb.base/quit-live.exp. Fix this by saving the original errno, and restoring it before returning [1]. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> [1] https://www.gnu.org/software/libc/manual/html_node/POSIX-Safety-Concepts.html
2024-12-13gdb/dap: allow some requests when the process is runningoltolm2-2/+2
It is impossible to set a breakpoint when the process is running, which I find annoying. LLDB does not have this restriction. I made `setBreakpoints` and `breakpointLocations` work when the process is running. Probably more requests can be changed, but I only need these two at the moment. Approved-By: Tom Tromey <tom@tromey.com>
2024-12-13gdb-dap: fix gdb.error: Frame is invalid.Oleg Tolmatcev2-18/+34
When you try to use a frame on one thread and it was created on another you get an error. I fixed it by creating a map from a frame ID to a thread ID. When a frame is created it is added to the map. When you try to find a frame for an id it checks if it is on the correct thread and if not switches to that thread. I had to store the frame id instead of the frame itself in a "_ScopeReference". Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32133 Approved-By: Tom Tromey <tom@tromey.com>
2024-12-12Reuse "title" style for list headersTom Tromey4-6/+13
This patch reuses the "title" style for titles -- in particular the header line of a list display. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-12Replace uses of "title" style with "command"Tom Tromey4-16/+17
Currently the "title" style is only used when printing command names. The "title" name itself is probably a misnomer, but meanwhile this patch changes the existing uses to instead use the new "command" style for consistency. The "title" style is not removed; see the next patch. Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-12Introduce "command" stylingTom Tromey22-65/+143
This adds a new "command" style that is used when styling the name of a gdb command. Note that not every instance of a command name that is output by gdb is changed here. There is currently no way to style error() strings, and there is no way to mark up command help strings. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31747 Reviewed-By: Eli Zaretskii <eliz@gnu.org> Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-12Lock bfd_stat and bfd_get_mtimeTom Tromey7-9/+47
PR gdb/31713 points out some races when using the background DWARF reader. This particular patch fixes some of these, namely the ones when using the sim. In this case, the 'load' command calls reopen_exec_file, which calls bfd_stat, which introduces a race. BFD only locks globals -- concurrent use of a single BFD must be handled by the application. To this end, this patch adds locked wrappers for bfd_stat and bfd_get_mtime. I couldn't reproduce these data races but the original reporter tested the patch and confirms that it helps. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31713 Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-12Fix formatting in gdb.ada/lazy-string.expTom Tromey1-3/+3
This fixes a formatting issue and corrects a comment in the new gdb.ada/lazy-string.exp. I meant to do this in an earlier patch but forgot to save.
2024-12-12Use generic_printstr from ada_language::printstrTom Tromey3-2/+77
Currently, if you create a lazy string while in Ada language mode, the string will be rendered strangely, like: "["d0"]["9f"]["d1"]["80"]["d0"]["b8"]... This happens because ada_printstr does not really handle UTF-8 decoding. This patch changes ada_language::printstr to use generic_printstr when UTF-8 is used. Note that this code could probably be improved some more -- the current patch only addresses the narrow case of the Python API. I've filed a follow-up bug (PR ada/32413) for the remaining changes. Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-12Fix GNAT version check in gdb.adaTom Tromey4-5/+5
Commit 1411185a ("Introduce and use gnat_version_compare") changed the Ada tests to use a new proc for version checking. Unfortunately this patch inadvertently reversed the sense of the test in packed_array_assign.exp. After fixing this, I went through that patch again and looked for other problems. I found one spot where the wrong syntax was used, and some others where I believe the sense of the test was inverted. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32444 Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-12Make rs6000-tdep.c:variants 'const'Tom Tromey1-1/+1
I noticed that rs6000-tdep.c has a global "variants" array that can be marked "const", moving it into rodata. Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-11dwarf_lang_to_enum_language: Map new DWARF5 constantsAlexandra Hájková1-0/+10
Add new DWARF5 language codes to gdb/dwarf2/read.c where they are converted to GDB language names. The codes were added to include/dwarf.h by syncing with gcc, Ada language codes were added to dwarf.h earlier. Approved-By: Tom Tromey <tom@tromey.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-11gdb: s390: Correct record/replay of may/mayr insnJens Remus1-0/+14
The IBM z/Architecture Principles of Operation [1] specifies that the R1 operand of the may and mayr instructions designates may designate either the lower- or higher-numbered register of a floating-point- register (FPR) pair. [1]: IBM z/Architecture Principles of Operation, SA22-7832-13, IBM z16, https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf gdb/ * s390-tdep.c (s390_process_record): may/mayr operand R1 may designate lower- or higher numbered register of FPR pair. Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2024-12-10[gdb/testsuite] Use setVariable in gdb.dap/scopes.expTom de Vries1-18/+9
The test-case gdb.dap/scopes.exp contains the following outdated comment: ... # setVariable isn't implemented yet, so use the register name. ... Now that setVariable is implemented, use it to set variable scalar, and remove the bit that sets the first register. That part is known to fail on s390x, because the first register isn't writeable [1]. Tested on x86_64-linux. Suggested-By: Tom Tromey <tom@tromey.com> Approved-By: Tom Tromey <tom@tromey.com> [1] https://sourceware.org/pipermail/gdb-patches/2024-December/213823.html
2024-12-10[gdb/testsuite] Fix gdb.dap/step-out.exp on s390xTom de Vries1-23/+29
With test-case gdb.dap/step-out.exp on s390x-linux, I get: ... >>> {"seq": 7, "type": "request", "command": "scopes", "arguments": {"frameId": 0}} Content-Length: 569^M ^M {"request_seq": 7, "type": "response", "command": "scopes", "body": {"scopes": [{"variablesReference": 1, "name": "Locals", "presentationHint": "locals", "expensive": false, "namedVariables": 1, "line": 35, "source": {"name": "step-out.c", "path": "/home/vries/gdb/src/gdb/testsuite/gdb.dap/step-out.c"}}, {"variablesReference": 2, "name": "Registers", "presentationHint": "registers", "expensive": false, "namedVariables": 114, "line": 35, "source": {"name": "step-out.c", "path": "/home/vries/gdb/src/gdb/testsuite/gdb.dap/step-out.c"}}]}, "success": true, "seq": 21}PASS: gdb.dap/step-out.exp: get scopes success FAIL: gdb.dap/step-out.exp: three scopes ... The problem is that the test-case expects three scopes: ... lassign $scopes scope reg_scope return_scope ... but the return_scope is missing because this doesn't work: ... $ gdb -q -batch outputs/gdb.dap/step-out/step-out \ -ex "b function_breakpoint_here" \ -ex run \ -ex finish ... Value returned has type: struct result. Cannot determine contents ... This is likely caused by a problem in gdb, but there's nothing wrong the DAP support. Fix this by: - allowing two scopes, and - declaring the tests of return_scope unsupported. Tested on s390x-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-12-10[gdb/testsuite] Fix fails in gdb.python/py-arch-reg-groups.expTom de Vries1-0/+3
Since commit e69d35f45e0 ("Use ui-out table in "maint print reggroups""), test-case gdb.python/py-arch-reg-groups.exp fails with check-read1: ... FAIL: $exp: Same number of registers groups found FAIL: $exp: all register groups match ... Fix this by adding a gdb_test_multiple clause that matches the command. Tested on x86_64-linux.
2024-12-09Introduce NoOpStringPrinterTom Tromey3-1/+147
We discovered that attempting to print a very large string-like array would succeed on the CLI, but in DAP would cause the "variables" request to fail with: value requires 67038491 bytes, which is more than max-value-size This turns out to be a limitation in Value.format_string, which de-lazy-ifies the value. This patch fixes this problem by introducing a new NoOpStringPrinter class, and then using it for string-like values. This printer returns a lazy string, which solves the problem. Note there are some special cases where we do not want to return a lazy string. I've documented these in the code. I considered making gdb.Value.lazy_string handle these cases -- for example it could return 'self' rather than a lazy string in some situations -- but this approach was simpler.
2024-12-09Clean up 0-length handling in gdbpy_create_lazy_string_objectTom Tromey2-8/+19
gdbpy_create_lazy_string_object will throw an exception if you pass it a NULL pointer without also setting length=0 -- the default, length==-1, will fail. This seems bizarre. Furthermore, it doesn't make sense to do this check for array types, as an array can have a zero length. This patch cleans up the check and makes it specific to TYPE_CODE_PTR.
2024-12-09Reject non-string types in gdb.Value.lazy_stringTom Tromey4-14/+9
Currently, gdb.Value.lazy_string will allow the conversion of any object to a "lazy string". However, this was never the intent and is weird besides. This patch changes this code to correctly throw an exception in the non-matching cases. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20769
2024-12-09Fix error check in gdb_py_test_silent_cmdTom Tromey1-0/+1
I added a new test using gdb_py_test_silent_cmd, and then was surprised to find out that the new test passed -- it caused a Python exception and I had expected it to fail. This patch fixes this proc to detect this situation and fail.
2024-12-09Omit artificial symbols from DAP variables responseTom Tromey6-1/+89
While testing DAP, we found a situation where a compiler-generated variable caused the "variables" request to fail -- the variable in question being an apparent 67-megabyte string. It seems to me that artificial variables like this aren't interesting to DAP users, and the gdb CLI omits these as well. This patch changes DAP to omit these variables, adding a new gdb.Symbol.is_artificial attribute to make this possible.
2024-12-09Defer DAP launch command until after configurationDoneTom Tromey36-164/+341
PR dap/32090 points out that gdb's DAP "launch" sequencing is incorrect. The current approach (which is itself a 2nd implementation...) was based on a misreading of the spec. The spec has since been clarified here: https://github.com/microsoft/debug-adapter-protocol/issues/497 The clarification here is that a client is free to send the "launch" (or "attach") request at any point after the "initialized" event has been sent by gdb. However, the "launch" does not cause any action to be taken -- and does not send a response -- until after "configurationDone" has been seen. This patch implements this by arranging for the launch and attach commands to return a DeferredRequest object. All the tests needed updates. I've also added a new test that checks that the deferred "launch" request can be cancelled. (Note that the cancellation is lazy -- it also waits until configurationDone is seen. This could be fixed, but I was not sure whether it is important to do so.) Finally, the "launch" command has a somewhat funny sequencing now. Simply sending the command and waiting for a response yielded strange results if the inferior did not stop -- in this case, the repsonse was never sent. So now, the command is split into two parts, with some setup being done synchronously (for better error propagation) and the actual "run" being done async. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32090 Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2024-12-09Add DAP deferred requestsTom Tromey1-24/+136
This adds a new "deferred request" capability to DAP. The idea here is that if a request returns a DeferredRequest object, then no response is sent immediately to the client. Instead, the request is pending until the deferred request is rescheduled. Some minor refactorings, particularly in cancellation, were needed to make this work. There's no use of this in the tree yet -- that is the next patch. Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2024-12-09Allow cancellation of DAP-thread requestsTom Tromey1-6/+18
This patch started as an attempt to fix the comment in CancellationHandler.cancel, but while working on it I found that the code could be improved as well. The current DAP cancellation code only handles the case where work is done on the gdb thread -- by checking for cancellation in interruptable_region. This means that if a request is handled completely in tthe DAP thread, then cancellation will never work. Now, this isn't a bug per se. DAP doesn't actually require that cancellation succeed. In fact, I think it can't, because cancellation is inherently racy. However, a coming patch will add a sort of "pending" request, and it would be nice if that were cancellable before any commands are sent to the gdb thread. No test in this patch, but one will arrive at the end of the series. Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2024-12-09Refactor CancellationHandler in DAPTom Tromey1-18/+15
This refactors the DAP CancellationHandler to be a context manager, and reorganizes the caller to use this. This is a bit more robust and also simplifies a subsequent patch in this series. Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2024-12-09Add call_function_later to DAPTom Tromey1-0/+12
This adds a new call_function_later API to DAP. This arranges to run a function after the current request has completed. This isn't used yet, but will be at the end of this series. Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2024-12-09Reimplement DAP delayed eventsTom Tromey1-12/+12
This patch changes how delayed events are implemented in DAP. The new implementation makes it simpler to add a delayed function call, which will be needed by the final patch in this series. Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2024-12-09Reimplement DAP's stopAtBeginningOfMainSubprogramTom Tromey1-5/+7
Right now, stopAtBeginningOfMainSubprogram is implemented "by hand", but then later the launch function uses "starti" to implement stopOnEntry. This patch unifies this code and rewrites it to use "start" when appropriate. Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2024-12-09[gdb/symtab] Apply workaround for PR gas/31115 a bit moreTom de Vries1-10/+31
In commit 8a61ee551ce ("[gdb/symtab] Workaround PR gas/31115"), I applied a workaround for PR gas/31115 in read_func_scope, fixing test-case gdb.arch/pr25124.exp. Recently I noticed that the test-case is failing again. Fix this by factoring out the workaround into a new function fixup_low_high_pc and applying it in dwarf2_die_base_address. While we're at it, do the same in dwarf2_record_block_ranges. Tested on arm-linux with target boards unix/-marm and unix/-mthumb. Reviewed-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
2024-12-09[gdb/syscalls] Generate aarch64-linux.xml.in in update-linux-from-src.shTom de Vries2-2/+50
Currently aarch64-linux.xml.in is skipped by update-linux-from-src.sh: ... $ ./update-linux-from-src.sh ~/upstream/linux-stable.git/ Skipping aarch64-linux.xml.in, no syscall.tbl ... $ ... and instead we use update-linux.sh. This works fine, but requires an aarch64 system with recent system headers, which makes it harder to pick up the latest changes in the linux kernel. Fix this by updating ./update-linux-from-src.sh to: - build the linux kernel headers for aarch64 - use update-linux.sh with those headers to generate aarch64-linux.xml.in. Regenerating aarch64-linux.xml.in using current trunk of linux-stable gives me these changes: ... + <syscall name="setxattrat" number="463"/> + <syscall name="getxattrat" number="464"/> + <syscall name="listxattrat" number="465"/> + <syscall name="removexattrat" number="466"/> ... which are the same changes I see for the other architectures. Note that the first step, building the linux kernel headers is a cross build and should work on any architecture. But the second step, update-linux.sh uses plain gcc rather than a cross-gcc, so there is scope for problems, but we seem to get away with this on x86_64-linux. So, while we could constrain this to only generate aarch64-linux.xml.in on aarch64-linux, I'm leaving this unconstrained. For aarch64-linux.xml.in, this doesn't matter much to me because I got an aarch64-linux system. But I don't have a longaarch system, and the same approach seems to work there. I'm leaving this for follow-up patch though. Tested on aarch64-linux and x86_64-linux. Verified with shellcheck.
2024-12-09Include gdbsupport/gdb_vecs.h in gdb/s390-linux-nat.cMark Wielaard1-0/+1
Commit c8889b913175 ("gdb, gdbserver, gdbsupport: remove some unused gdb_vecs.h includes") removed gdbsupport/gdb_vecs.h from various header files. This caused an compile issue for gdb/s390-linux-nat.c ../../binutils-gdb/gdb/s390-linux-nat.c: In member function ‘virtual int s390_linux_nat_target::remove_watchpoint(CORE_ADDR, int, target_hw_bp_type, expression*)’: ../../binutils-gdb/gdb/s390-linux-nat.c:875:11: error: ‘unordered_remove’ was not declared in this scope 875 | unordered_remove (state->watch_areas, ix); | ^~~~~~~~~~~~~~~~ ../../binutils-gdb/gdb/s390-linux-nat.c: In member function ‘virtual int s390_linux_nat_target::remove_hw_breakpoint(gdbarch*, bp_target_info*)’: ../../binutils-gdb/gdb/s390-linux-nat.c:928:11: error: ‘unordered_remove’ was not declared in this scope 928 | unordered_remove (state->break_areas, ix); | ^~~~~~~~~~~~~~~~ Fix this by including gdbsupport/gdb_vecs.h in gdb/s390-linux-nat.c.
2024-12-09gdb: allow core file containing special characters on the command lineAndrew Burgess2-71/+62
After the commit: commit 03ad29c86c232484f9090582bbe6f221bc87c323 Date: Wed Jun 19 11:14:08 2024 +0100 gdb: 'target ...' commands now expect quoted/escaped filenames it was no longer possible to pass GDB the name of a core file containing any special characters (white space or quote characters) on the command line. For example: $ gdb -c /tmp/core\ file.core Junk after filename "/tmp/core": file.core (gdb) The problem is that the above commit changed the 'target core' command to expect quoted filenames, so before the above commit a user could write: (gdb) target core /tmp/core file.core [New LWP 2345783] Core was generated by `./mkcore'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x0000000000401111 in ?? () (gdb) But after the above commit the user must write: (gdb) target core /tmp/core\ file.core or (gdb) target core "/tmp/core file.core" This is part of a move to make GDB's filename argument handling consistent. Anyway, the problem with the '-c' command line flag is that it forwards the filename unmodified through to the 'core-file' command, which in turn forwards to the 'target core' command. So when the user, at a shell writes: $ gdb -c "core file.core" this arrives in GDB as the unquoted string 'core file.core' (without the single quotes). GDB then forwards this to the 'core-file' command as if the user had written this at a GDB prompt: (gdb) core-file core file.core Which then fails to parse due to the unquoted white space between 'core' and 'file.core'. The solution I propose is to escape any special characters in the core file name passed from the command line before calling 'core-file' command from main.c. I've updated the corefile.exp test to include a test for passing a core file containing a white space character. While I was at it I've modernised the part of corefile.exp that I was touching.
2024-12-09gdb: make core_target_open staticAndrew Burgess2-6/+6
The core_target_open function is only used in corelow.c, so lets make it static. There should be no user visible changes after this commit.
2024-12-09gdb: use 'const' more in a couple of small breakpoint functionsAndrew Burgess2-6/+6
Make the 'struct breakpoint *' argument 'const' in user_breakpoint_p and pending_breakpoint_p. And make the 'struct bp_location *' argument 'const' in bl_address_is_meaningful. There should be no user visible changes after this commit.
2024-12-06gdb: make objfile::make actually use its pspace parameterSimon Marchi1-5/+3
Fix an oversight in commit 8991986e2413 ("gdb: pass program space to objfile::make"). Change-Id: I263eec6e94dde0a9763f831d2d87b4d300b6a36a
2024-12-06gdb, gdbserver, gdbsupport: remove some unused gdb_vecs.h includesSimon Marchi17-9/+8
Remove some includes reported as unused by clangd. Add some to files that actually need it. Change-Id: I01c61c174858c1ade5cb54fd7ee1f582b17c3363
2024-12-06gdb: Fix use-after-free when an objfile has no symbols to loadGuinevere Larsen2-4/+4
The recent commit <HASH> moved an initialization of an objfile_holder in syms_from_objfile_1 much earlier in the function, to better deal with when GDB is unable to read the objfile format. However, there is an early exit from syms_from_objfile_1 when the objfile can be understood, but has no symbols. That was not releasing the objfile_holder, so the objfile was being unlinked from the program space, but the process of reading the objfile was being continued, leading to use-after-frees flagged by the Address Sanitizer. This commit fixes that UAF by making the objfile_holder release the objfile right before the early exit. This commit also changes the test gdb.base/dump.exp since that was the original test that flagged the UAF, but at the end of the test the generated files were being deleted, meaning we couldn't redo the test manually after the fact. That final deletion was removed Reported-by: Simon Marchi <simark@simark.ca> Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-12-06Reduce WOW64 code duplicationHannes Domani3-222/+190
Currently we have duplicate code for each place where windows_thread_info::context is touched, since for WOW64 processes it has to do the equivalent with wow64_context instead. For example this code...: #ifdef __x86_64__ if (windows_process.wow64_process) { th->wow64_context.ContextFlags = WOW64_CONTEXT_ALL; CHECK (Wow64GetThreadContext (th->h, &th->wow64_context)); ... } else #endif { th->context.ContextFlags = CONTEXT_DEBUGGER_DR; CHECK (GetThreadContext (th->h, &th->context)); ... } ...changes to look like this instead: windows_process.with_context (th, [&] (auto *context) { context->ContextFlags = WindowsContext<decltype(context)>::all; CHECK (get_thread_context (th->h, context)); ... } The actual choice if context or wow64_context are used, is handled by this new function in windows_process_info: template<typename Function> auto with_context (windows_thread_info *th, Function function) { #ifdef __x86_64__ if (wow64_process) return function (th != nullptr ? th->wow64_context : nullptr); else #endif return function (th != nullptr ? th->context : nullptr); } The other parts to make this work are the templated WindowsContext class which give the appropriate ContextFlags for both types. And there are also overloaded helper functions, like in the case of get_thread_context here, call either GetThreadContext or Wow64GetThreadContext. According git log --stat, this results in 120 lines less code. Approved-By: Tom Tromey <tom@tromey.com>
2024-12-04gdb: fix parsing of DIEs with both low/high pc AND ranges attributesAndrew Burgess3-22/+403
After the commit: commit b9de07a5ff74663ff39bf03632d1b2ea417bf8d5 Date: Thu Oct 10 11:37:34 2024 +0100 gdb: fix handling of DW_AT_entry_pc of inlined subroutines GDB's buildbot CI testing highlighted this assertion failure: (gdb) c Continuing. ../../binutils-gdb/gdb/block.h:203: internal-error: set_entry_pc: Assertion `start >= this->start () && start < this->end ()' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ----- Backtrace ----- FAIL: gdb.base/break-probes.exp: run til our library loads (GDB internal error) This assertion was in the new function set_entry_pc and is asserting that the default_entry_pc() value is within the blocks start/end range. The default_entry_pc() is the value GDB will use as the entry-pc if the DWARF doesn't specifically override the entry-pc. This value is calculated as: 1. The start address of the first sub-range within the block, if the block has more than 1 range, or 2. The low address (from DW_AT_low_pc) for the block. If the block only has a single range then this means the block was defined with low/high pc attributes (case #2 above). These low/high pc values are what block::start() and block::end() return. This means that by definition, if the block is continuous, the above assert cannot trigger as 'start', the default_entry_pc() would be equivalent to block::start(). This means that, for the assert to trigger, the block must have multiple ranges, and the first address of the first range is not within the blocks low/high address range. This seems wrong. I inspected the state at the time the assert triggered and discovered the block's start() address. Then I removed the assert and restarted GDB. I was now able to inspect the blocks at the offending address: (gdb) maintenance info blocks 0x7ffff7dddaa4 Blocks at 0x7ffff7dddaa4: from objfile: [(objfile *) 0x44a37f0] /lib64/ld-linux-x86-64.so.2 [(block *) 0x46b30c0] 0x7ffff7ddd5a0..0x7ffff7dde8a6 entry pc: 0x7ffff7ddd5a0 is global block symbol count: 4 is contiguous [(block *) 0x46b3020] 0x7ffff7ddd5a0..0x7ffff7dde8a6 entry pc: 0x7ffff7ddd5a0 is static block symbol count: 9 is contiguous [(block *) 0x46b2f70] 0x7ffff7ddda00..0x7ffff7dddac3 entry pc: 0x7ffff7ddda00 function: __GI__dl_find_dso_for_object symbol count: 4 is contiguous [(block *) 0x46b2e10] 0x7ffff7dddaa4..0x7ffff7dddac3 entry pc: 0x7ffff7dddaa4 inline function: __GI__dl_find_dso_for_object symbol count: 5 is contiguous [(block *) 0x46b2a40] 0x7ffff7dddaa4..0x7ffff7dddac3 entry pc: 0x7ffff7dddaa4 symbol count: 1 is contiguous [(block *) 0x46b2970] 0x7ffff7dddaa4..0x7ffff7dddac3 entry pc: 0x7ffff7dddaa4 symbol count: 2 address ranges: 0x7ffff7ddda0e..0x7ffff7ddda77 0x7ffff7ddda90..0x7ffff7ddda96 I've left everything in for context, but the only really interesting bit is the very last block, it's low/high range is: 0x7ffff7dddaa4..0x7ffff7dddac3 but it has separate ranges: 0x7ffff7ddda0e..0x7ffff7ddda77 0x7ffff7ddda90..0x7ffff7ddda96 which are all outside the low/high range. This is what triggers the assert. But why does that block exist at all? What I believe is happening is that we're running into a bug in older versions of GCC. The buildbot failure was with an 8.5 gcc, and Tom de Vries also reported seeing failures when using version 7 and 8 gcc, but not with gcc 9 and onward. Looking at the DWARF I can see that the problematic block is created from this DIE: <4><15efb>: Abbrev Number: 83 (DW_TAG_lexical_block) <15efc> DW_AT_abstract_origin: <0x15e9f> <15efe> DW_AT_low_pc : 0x7ffff7dddaa4 <15f06> DW_AT_high_pc : 31 which links via DW_AT_abstract_origin to: <2><15e9f>: Abbrev Number: 80 (DW_TAG_lexical_block) <15ea0> DW_AT_ranges : 0x38e0 <15ea4> DW_AT_sibling : <0x15eca> And so we can see that <15efb> has got both low/high pc attributes and a ranges attribute. If I widen my checking to parents of DIE <15efb> then I see that they also have DW_AT_abstract_origin, however, there is something interesting going on, the parent DIEs are linking to a different DIE tree than <15efb>. What I believe is happening is this, we have an abstract instance tree, this is rooted at a DW_AT_subprogram, and contains all the blocks, variables, parameters, etc, that you would expect. As this is an abstract instance, then there are no low/high pc attributes, and no ranges attributes in this tree. This makes sense. Now elsewhere we have a DW_TAG_subprogram (not DW_TAG_inlined_subroutine) which links via DW_AT_abstract_origin to the abstract DW_AT_subprogram. This case is documented in the DWARF 5 spec in section 3.3.8.3, and describes an Out-of-Line Instance of an Inlined Subroutine. Within this out of line instance many of the DIE correctly link back, using DW_AT_abstract_origin to the abstract instance tree. This tree also includes the DIE <15e9f>, which is where our problem DIE references. Now, to really confuse things, within this out-of-line instance we have a DW_TAG_inlined_subroutine, which is another instance of the same abstract instance tree! This would seem to indicate a recursive call to the inline function, and the compiler, for some reason, needed to instantiate an out of line instance of this function. And it is within this nested, inlined subroutine, that the problem DIE exists. The problem DIE is referencing the corresponding DIE within the out of line instance tree, but I am convinced this must be a (long fixed) GCC bug, and that the problem DIE should be referencing the DIE within the abstract instance tree. I'm aware that the above is pretty confusing. The actual DWARF would be a around 200 lines long, so I'd like to avoid dumping it in here. But here's my attempt at representing what's going on in a minimal example. The numbers down the side represent the section offset, not the nesting level, and I've removed any attributes that are not relevant: <1> DW_TAG_subprogram <2> DW_TAG_lexical_block <3> DW_TAG_subprogram DW_AT_abstract_origin <1> <4> DW_TAG_lexical_block DW_AT_ranges ... <5> DW_TAG_inlined_subroutine DW_AT_abstract_origin <1> <6> DW_TAG_lexical_block DW_AT_abstract_origin <4> DW_AT_low_pc ... DW_AT_high_pc ... The lexical block at <6> is linking to <4> when it should be linking to <2>. There is one additional thing that we might wonder about, which is, when calculating the low/high pc range for a block, why does GDB not make use of the range information and expand the range beyond the defined low/high values? The answer to this is in dwarf_get_pc_bounds_ranges_or_highlow_pc in dwarf/read.c. This is where the low/high bounds are calculated. What we see is that GDB first checks for a low/high attribute pair, and if that is present, this defines the address range for the block. Only if there is no DW_AT_low_pc do we check for the DW_AT_ranges, and use that to define the extent of the block. And this makes sense, section 3.5 of the DWARF-5 spec says: The lexical block entry may have either a DW_AT_low_pc and DW_AT_high_pc pair of attributes or a DW_AT_ranges attribute whose values encode the contiguous or non-contiguous address ranges, respectively, of the machine instructions generated for the lexical block... Section 3.5 is specifically about lexical blocks, but the same wording, about it being either low/high OR ranges is repeated for other DW_TAG_ types. So this explains why GDB doesn't use the ranges to expand the problem blocks ranges; as the first DIE has low/high addresses, these are used, and the ranges is not consulted. It is only later in dwarf2_record_block_ranges that we create a range based off the low/high pc, and then also process the ranges data, this allows the problem block to exist with ranges that are outside the low/high range. To solve this I considered a number of options: 1. Prevent loading certain attributes from an abstract instance. Section 3.3.8.1 of the DWARF-5 spec talks about which attributes are appropriate to place in an abstract instance. Any attribute that might vary between instances should not appear in an abstract instance. DW_AT_ranges is included as an example in the non-exhaustive list of attributes that should not appear in an abstract instance. Currently in dwarf2_attr (dwarf2/read.c), when we see a DW_AT_abstract_origin attribute, we always follow this to try and find the attribute we are looking for. But we could change this function so that we prevent this following for attributes that we know should not be looked up in an abstract instance. This would solve the problem in this case by preventing us finding the DW_AT_ranges in the incorrect abstract instance. 2. Filter the ranges. Having established a blocks low/high address range in dwarf_get_pc_bounds_ranges_or_highlow_pc, we could allow dwarf2_record_block_ranges to parse the ranges, but we could reject any range that extends outside the blocks defined start and end addresses. For well behaved DWARF where we have either low/high or ranges, then the blocks start/end are defined from the range data, and so, by definition, every range would be acceptable. But in our problem case we would reject all of the invalid ranges. This is my least favourite solution as it feels like rejecting the ranges is tackling the problem too late on. 3. Don't try to parse ranges when we have low/high attributes. This option involves updating dwarf2_record_block_ranges to match the behaviour of dwarf_get_pc_bounds_ranges_or_highlow_pc, and, I believe, to match the DWARF spec: don't try to read range data from DW_AT_ranges if we have low/high pc attributes. In our case this solves the issue because the problematic DIE has the low/high attributes, and it then links to the wrong DIE which happens to have DW_AT_ranges. With this change in place we don't even look for the DW_AT_ranges. If the problem were reversed, and the initial DIE had DW_AT_ranges, but the incorrectly referenced DIE had the low/high pc attributes, we would pick up the wrong addresses, but this wouldn't trigger any asserts. The reason is that dwarf_get_pc_bounds_ranges_or_highlow_pc would also find the low/high addresses from the incorrectly referenced DIE, and so we would just end up with a block which had the wrong address ranges, but the block would be self consistent, which is different to the problem we hit here. In the end, in this commit I went with solution #3, having dwarf_get_pc_bounds_ranges_or_highlow_pc and dwarf2_record_block_ranges be consistent seems sensible. However, I do wonder if in the future we might want to explore solution #1 as an additional safety feature. With this patch in place I'm able to run the gdb.base/break-probes.exp without seeing the assert that CI testing highlighted. I see no regressions when testing on x86-64 GNU/Linux with gcc 9.3.1. Note: the diff in this commit looks big, but it's really just me indenting the code. Approved-By: Tom Tromey <tom@tromey.com>
2024-12-04[gdb/tdep] Remove includes of gdbsupport/common-defs.hTom de Vries3-3/+0
In commit 18d2988e5da ("gdb, gdbserver, gdbsupport: remove includes of early headers") all includes of gdbsupport/common-defs.h where removed, but commit c1cdee0e2c1 ("gdb: LoongArch: Add support for hardware watchpoint") reintroduced some. Fix this by removing them. Tested by doing this on x86_64-linux: ... $ make \ nat/loongarch-hw-point.o \ nat/loongarch-linux.o \ nat/loongarch-linux-hw-point.o CXX nat/loongarch-hw-point.o CXX nat/loongarch-linux.o CXX nat/loongarch-linux-hw-point.o ... Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-12-04[gdb/build] Fix build breaker on mingw-w64Simon Marchi3-5/+0
The mingw-w64 build breaks currently: ... In file included from gdb/cli/cli-cmds.c:58: gdbsupport/eintr.h: In function ‘pid_t gdb::waitpid(pid_t, int*, int)’: gdbsupport/eintr.h:77:35: error: ‘::waitpid’ has not been declared; \ did you mean ‘gdb::waitpid’? 77 | return gdb::handle_eintr (-1, ::waitpid, pid, wstatus, options); | ^~~~~~~ | gdb::waitpid gdbsupport/eintr.h:75:1: note: ‘gdb::waitpid’ declared here 75 | waitpid (pid_t pid, int *wstatus, int options) | ^~~~~~~ ... This is a regression since commit 658a03e9e85 ("[gdbsupport] Add gdb::{waitpid,read,write,close}"), which moved the use of ::waitpid from run_under_shell, where it was used conditionally: ... #if defined(CANT_FORK) || \ (!defined(HAVE_WORKING_VFORK) && !defined(HAVE_WORKING_FORK)) ... #else ... int ret = gdb::handle_eintr (-1, ::waitpid, pid, &status, 0); ... to gdb::waitpid, where it's used unconditionally: ... inline pid_t waitpid (pid_t pid, int *wstatus, int options) { return gdb::handle_eintr (-1, ::waitpid, pid, wstatus, options); } ... Likewise for ::wait. Guard these uses with HAVE_WAITPID and HAVE_WAIT. Reproduced and tested by doing a mingw-w64 cross-build on x86_64-linux. Reported-By: Simon Marchi <simark@simark.ca> Co-Authored-By: Tom de Vries <tdevries@suse.de>
2024-12-04gdb, testsuite: fix TCL error in 'gdb.base/structs.exp'Stephan Rohr1-1/+1
A failure of 'runto_main' in 'start_structs_test' results in a TCL error. The return value of 'start_structs_test' function is evaluated inside an if conditional clause, which expects a boolean value. Return '-1' on failure to avoid the error. Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
2024-12-04[gdb/testsuite] Fix failure in gdb.python/py-startup-opt.expTom de Vries1-5/+7
In commit 922ab963e1c ("[gdb/python] Handle empty PYTHONDONTWRITEBYTECODE") I added a test in gdb.python/py-startup-opt.exp that checks the "show python dont-write-bytecode" output. Then in commit 348290c7ef4 ("[gdb/python] Warn and ignore ineffective python settings") I changed the output of "show python dont-write-bytecode" after python initialization. I tested these changes individually, and found no problems but after committing both the test started failing, which the Linaro CI reported. Fix this by updating the expected output. While we're at it, make the test a bit more generic by testing "show python $setting" in all cases. Tested on x86_64-linux, using: - PYTHONDONTWRITEBYTECODE= - PYTHONDONTWRITEBYTECODE=1 - unset PYTHONDONTWRITEBYTECODE
2024-12-03Fix "maint print" error messagesTom Tromey1-7/+16
While working on an earlier patch, I noticed that all the register-related "maint print" commands used the wrong command name in an error message. This fixes them. Reviewed-by: Christina Schimpe <christina.schimpe@intel.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-03Use ui-out table in "maint print reggroups"Tom Tromey5-16/+20
This changes the "maint print reggroups" command to use a ui-out table rather than printf. It also fixes a typo I noticed in a related test case name; and lets us finally remove the leading \s from the regexp in completion.exp. Reviewed-by: Christina Schimpe <christina.schimpe@intel.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-12-03Use ui-out tables in some "maint print" commandsTom Tromey5-170/+192
This changes various "maint print" register commands to use ui-out tables rather than the current printf approach. Approved-By: Andrew Burgess <aburgess@redhat.com>