aboutsummaryrefslogtreecommitdiff
path: root/gdb
AgeCommit message (Collapse)AuthorFilesLines
2023-07-23gdb/testsuite: replace $testfile with $binfile in one caseAndrew Burgess1-1/+1
For *reasons* I was hacking on gdb.base/foll-vfork.exp and wanted to change the name of the binary that was created. Should be easy, I adjusted the global $binfile variable .... but that didn't work. In one place the script uses $testfile instead of $binfile. Fixed this to use $binfile, now I can easily change the name of the generated binary, and the test still works. There's no change in what is tested after this commit.
2023-07-22[gdb/testsuite] Improve gdb.arch/arm-pthread_cond_timedwait-bt.expTom de Vries1-3/+6
I noticed in test-case gdb.arch/arm-pthread_cond_timedwait-bt.exp that prepare_for_testing is used, followed by a clean_restart. This calls clean_restart twice in a row. Fix this by using build_executable instead. Also, I noticed that the test-case requires an SVC instruction, so add a require to limit the test-case to supported architectures. While we're at it, run M-x indent-region in emacs to fix indentation. Tested on x86_64-linux.
2023-07-22[gdb/testsuite] Use proc readnow in two test-casesTom de Vries2-14/+8
Use "require !readnow" in two test-cases, instead of the written-out variant. Tested on x86_64-linux, with target boards unix and readnow.
2023-07-21Fix crash with DW_FORM_implicit_constTom Tromey3-13/+22
Jakub pointed out that using DW_FORM_implicit_const with DW_AT_bit_size would cause gdb to crash. This happened because DW_FORM_implicit_const is not an "unsigned" form, causing as_unsigned to assert. This patch fixes the problem. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30651 Approved-By: Andrew Burgess <aburgess@redhat.com>
2023-07-21Implement DAP modules requestTom Tromey8-1/+228
This implements the DAP "modules" request, and also arranges to add the module ID to stack frames.
2023-07-21Add Progspace.objfile_for_addressTom Tromey6-0/+62
This adds a new objfile_for_address method to gdb.Progspace. This makes it easy to find the objfile for a given address. There's a related PR; and while this change would have been sufficient for my original need, it's not clear to me whether I should close the bug. Nevertheless I think it makes sense to at least mention it here. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=19288 Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-07-21Remove unused importsTom Tromey2-4/+0
I noticed an unused import in dap/evaluate.py; and also I found out that my recent changes to use frame filters from DAP left some unused imports in dap/bt.py.
2023-07-21Document array indexing for Python gdb.ValueTom Tromey1-0/+7
I noticed that the documentation for gdb.Value doesn't mention array indexing. Approved-By: Eli Zaretskii <eliz@gnu.org>
2023-07-21Remove redundant @findex from python.texiTom Tromey1-52/+0
In a review, Eli pointed out that @findex is redundant when used with @defun. This patch removes all such uses from python.texi, plus a couple uses before @defvar that are also unnecessary. Approved-By: Eli Zaretskii <eliz@gnu.org>
2023-07-21Fix typo in py-type.c docstringTom Tromey1-1/+1
I noticed that a doc string py-type.c says "an signed". This patch corrects it to "a signed".
2023-07-21Implement Ada target name symbolTom Tromey5-7/+113
Ada 2022 adds the "target name symbol", which can be used on the right hand side of an assignment to refer to the left hand side. This allows for convenient updates. This patch implements this for gdb's Ada expression parser. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-07-21Add instruction bytes to DAP disassembly responseTom Tromey3-1/+18
The DAP disassemble command lets the client return the underlying bytes of the instruction in an implementation-defined format. This patch updates gdb to return this, and simply uses a hex string of the bytes as the format. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-07-21Remove ancient Ada workaroundTom Tromey4-35/+0
I ran across this very old code in gdb's Ada support. After a bit of archaeology, we couldn't determine what bug this might have been working around. It is no longer needed, so this patch removes it. As this is entirely Ada-specific and was reviewed and tested at AdaCore, I'm checking it in.
2023-07-21gdb/solib-rocm: limit the number of opened file descriptorsLancelot Six1-10/+115
ROCm programs can load a high number of compute kernels on GPU devices, especially if lazy code-object loading have been disabled. Each code object containing such program is loaded once for each device available, and each instance is reported by GDB as an individual shared library. We came across situations where the number of shared libraries opened by GDB gets higher than the allowed number of opened files for the process. Increasing the opened files limit works around the problem, but there is a better way this patch proposes to follow. Under the hood, the GPU code objects are embedded inside the host application binary and shared library binaries. GDB currently opens the underlying file once for each shared library it sees. That means that the same file is re-opened every time a code object is loaded on a GPU. This patch proposes to only open each underlying file once. This is done by implementing a reference counting mechanism so the underlying file is opened when the underlying file first needs to be opened, and closed when the last BFD using the underlying file is closed. On a program where GDB used to open about 1500 files to load all shared libraries, this patch makes it so only 54 opened file descriptors are needed. I have tested this patch on downstream ROCgdb's full testsuite and upstream GDB testsuite with no regression. Approved-By: Pedro Alves <pedro@palves.net>
2023-07-21[gdb/symtab] Add optimized out static var to cooked indexTom de Vries5-9/+156
Consider the test-case: ... $ cat main.c int main (void) { return 0; } $ cat static-optimized-out.c static int aaa; ... compiled like this: ... $ gcc-12 static-optimized-out.c main.c -g -O2 -flto ... There's a difference in behaviour depending on symtab expansion state: ... $ gdb -q -batch a.out -ex "print aaa" No symbol "aaa" in current context. $ gdb -q -batch a.out -ex "maint expand-symtab" -ex "print aaa" $1 = <optimized out> ... The reason for the difference is that the optimized out variable aaa: ... <1><104>: Abbrev Number: 2 (DW_TAG_variable) <105> DW_AT_name : aaa <109> DW_AT_decl_file : 1 <10a> DW_AT_decl_line : 18 <10b> DW_AT_decl_column : 12 <10c> DW_AT_type : <0x110> ... is not added to the cooked index because of this clause in abbrev_table::read: ... else if (!has_location && !has_specification_or_origin && !has_external && cur_abbrev->tag == DW_TAG_variable) cur_abbrev->interesting = false; ... Fix this inconsistency by making sure that the optimized out variable is added to the cooked index. Regression tested on x86_64-linux. Add two test-cases, a C test-case gdb.opt/static-optimized-out.exp and a dwarf assembly test-case gdb.dwarf2/static-optimized-out.exp. Tested gdb.opt/static-optimized-out.exp with gcc-8 to gcc-12, for which we now consistently get: ... (gdb) print aaa^M $1 = <optimized out>^M ... and with gcc 7.5.0 and clang 13.0.1, for which we still consistently get: ... (gdb) print aaa^M No symbol "aaa" in current context.^M ... due to missing debug info for the variable. PR symtab/30656 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30656 Approved-By: Tom Tromey <tom@tromey.com>
2023-07-21[gdb/tui] Fix superfluous newline for long promptTom de Vries2-19/+1
In test-case gdb.tui/long-prompt.exp, with a prompt of 40 chars, the same size as the terminal width, we get a superfluous newline at line 19: ... 16 (gdb) set prompt 123456789A123456789B123 17 456789C123456789> 18 123456789A123456789B123456789C123456789> 19 20 123456789A123456789B123456789C123456789> 21 set prompt (gdb) 22 (gdb) ... as well as a superfluous repetition of the prompt at line 20 once we type the 's' starting "set prompt". I traced the superfluous newline back to readline's readline_internal_setup, that does: ... /* If we're not echoing, we still want to at least print a prompt, because rl_redisplay will not do it for us. If the calling application has a custom redisplay function, though, let that function handle it. */ if (_rl_echoing_p == 0 && rl_redisplay_function == rl_redisplay) ... else { if (rl_prompt && rl_already_prompted) rl_on_new_line_with_prompt (); else rl_on_new_line (); (*rl_redisplay_function) (); ... and then we hit the case that calls rl_on_new_line_with_prompt, which does: ... /* If the prompt length is a multiple of real_screenwidth, we don't know whether the cursor is at the end of the last line, or already at the beginning of the next line. Output a newline just to be safe. */ if (l > 0 && (l % real_screenwidth) == 0) _rl_output_some_chars ("\n", 1); ... This doesn't look like a readline bug, because the behaviour matches the comment. [ And the fact that the output of the newline doesn't happen in the scope of tui_redisplay_readline means it doesn't get the prompt wrap detection treatment, causing start_line to be incorrect, which causes the superfluous repetition of the prompt. ] I looked at ways to work around this, and managed by switching off rl_already_prompted, which we set to 1 in tui_rl_startup_hook: ... /* Readline hook to redisplay ourself the gdb prompt. In the SingleKey mode, the prompt is not printed so that the command window is cleaner. It will be displayed if we temporarily leave the SingleKey mode. */ static int tui_rl_startup_hook (void) { rl_already_prompted = 1; if (tui_current_key_mode != TUI_COMMAND_MODE && !gdb_in_secondary_prompt_p (current_ui)) tui_set_key_mode (TUI_SINGLE_KEY_MODE); tui_redisplay_readline (); return 0; } ... Then I started looking at why rl_already_prompted is set to 1. The use case for rl_already_prompted seems to be: - app (application, the readline user) outputs prompt, - app sets rl_already_prompted to 1, and - app calls readline, which calls rl_on_new_line_with_prompt, which figures out how long the prompt is, and sets a few readline variables accordingly, which can be used in the following call to rl_redisplay_function. AFAICT, TUI does not fit this pattern. It does not output an initial prompt, rather it writes the prompt in every rl_redisplay_function. It doesn't use the variables set by rl_on_new_line_with_prompt, instead it figures stuff out by itself. Fix this by removing the rl_already_prompted setting. Also remove the call to tui_redisplay_readline, it's not necessary, the function is called anyway. Tested on x86_64-linux, no regressions.
2023-07-19gdb: LoongArch: Update status of the entire regset in regcacheHui Li1-2/+2
In the current code, when a register is fetched, the entire regset are fetched via ptrace, but only this register status is updated in regcache, it needs to fetch the same regset through ptrace again if another register in this regset is fetched later, this is obviously unnecessary. It is proper to update the status of the entire regset in regcache when fetching a register via ptrace. Signed-off-by: Hui Li <lihui@loongson.cn> Reviewed-By: Tom Tromey <tom@tromey.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2023-07-19Fix gdb.Inferior.read_memory without execution (PR dap/30644)Pedro Alves5-10/+20
Andrew reported that the previous change to gdb.Inferior.read_memory & friends introducing scoped_restore_current_inferior_for_memory broke gdb.dap/stop-at-main.exp. This is also reported as PR dap/30644. The root of the problem is that all the methods that now use scoped_restore_current_inferior_for_memory cause GDB to crash with a failed assert if they are run on an inferior that is not yet started. E.g.: (gdb) python i = gdb.selected_inferior () (gdb) python i.read_memory (4,4) gdb/thread.c:626: internal-error: any_thread_of_inferior: Assertion `inf->pid != 0' failed. This patch fixes the problem by removing scoped_restore_current_inferior_for_memory's ctor ptid parameter and the any_thread_of_inferior calls completely, and making scoped_restore_current_inferior_for_memory switch inferior_ptid to a pid ptid. I was a little worried that some port might be assuming inferior_ptid points at a thread in the xfer_partial memory access routines. We know that anything that supports forks must not assume that, due to how detach_breakpoints works. I looked at a number of xfer_partial implementations, and didn't see anything that is looking at inferior_ptid in a way that would misbehave. I'm thinking that we could go forward with this and just fix ports if they break. While on some ports like on AMD GPU we have thread-specific address spaces, and so when accessing memory for those address spaces, we must have the right thread context (via inferior_ptid) selected, in Inferior.read_memory, we only have the inferior to work with, so this API as is can't be used to access thread-specific address spaces. IOW, it can only be used to access the global address space that is visible to both the CPU and the GPUs. In proc-service.c:ps_xfer_memory, the other spot using scoped_restore_current_inferior_for_memory, we're always accessing per-inferior memory. If we end up using scoped_restore_current_inferior_for_memory later to set up the context to read memory from a specific thread, then we can add an alternative ctor that takes a thread_info pointer, and make inferior_ptid point to the thread, for example. New test added to gdb.python/py-inferior.exp, exercising Inferior.read_memory without execution. No regressions on native and extended-gdbserver x86_64 GNU/Linux. Reviewed-By: Tom Tromey <tom@tromey.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30644 Change-Id: I11309c5ddbbb51a4594cf63c21b3858bfd9aed19
2023-07-19gdb/amd-dbgapi-target: Use inf param in detachLancelot SIX1-1/+1
Current implementation of amd_dbgapi_target::detach (inferior *, int) does the following: remove_breakpoints_inf (current_inferior ()); detach_amd_dbgapi (inf); beneath ()->detach (inf, from_tty); I find that using a mix of `current_inferior ()` and `inf` disturbing. At this point, we know that both are the same (target_detach does assert that `inf == current_inferior ()` before calling target_ops::detach). To improve consistency, this patch replaces `current_inferior ()` with `inf` in amd_dbgapi_target::detach. Change-Id: I01b7ba2e661c25839438354b509d7abbddb7c5ed Approved-By: Pedro Alves <pedro@palves.net>
2023-07-19[gdb/testsuite] Fix gdb.gdb/python-helper.exp with -O2 -flto=auto and gcc 7.5.0Tom de Vries1-1/+5
With a gdb build with -O2 -flto=auto using gcc 7.5.0, I run into: ... (gdb) ptype global_c^M ^M Thread 1 "xgdb" hit Breakpoint 3, \ _Z12c_print_typeP4typePKcP7ui_fileii8languagePK18type_print_options () at \ gdb/c-typeprint.c:175^M 175 {^M (outer-gdb) FAIL: gdb.gdb/python-helper.exp: hit breakpoint in outer gdb again ... This is a problem with the debug info, which marks the CU containing the function declaration as C rather than C++. This is fixed in gcc 8 and later. Work around this compiler problem by allowing the mangled name. Tested on x86_64-linux. PR testsuite/30648 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30648
2023-07-17Remove unused declaration of child_terminal_init_with_pgrpTom Tromey1-2/+0
child_terminal_init_with_pgrp is declared but not defined. This patch removes the declaration. Tested by grep and rebuilding.
2023-07-17gdb: additional debug output in infrun.c and linux-nat.cAndrew Burgess2-8/+43
While working on some of the recent patches relating to vfork handling I found this debug output very helpful, I'd like to propose adding this into GDB. With debug turned off there should be no user visible changes after this commit.
2023-07-17gdb/testsuite: remove use of sleep from gdb.base/foll-vfork.expAndrew Burgess1-48/+0
While working on gdb.base/foll-vfork.exp I noticed that there are several random 'sleep' calls throughout the test. The comment suggests these are to allow for output from a vforked child to arrive, but in each case the test is about to close and restart GDB, so I don't see how random output from a child process could impact testing. I removed the sleep calls and couldn't reproduce any failures from this test, I left the test running for a couple of hours, and tried loading my machine, and the test seems fine with these removed. I've left this as a separate commit so that if, in the future, someone can show that these are required, it will be easy to revert this one patch and bring them back. There should be no change in what is tested after this commit.
2023-07-17gdb/testsuite: expand gdb.base/foll-vfork.expAndrew Burgess1-337/+304
This commit provides tests for all of the bugs fixed in the previous four commits, this is achieved by expanding gdb.base/foll-vfork.exp to run with different configurations: * target-non-stop on/off * non-stop on/off * schedule-multiple on/off We don't test with schedule-multiple on if we are using a remote target, this is due to bug gdb/30574. I've added a link to that bug in this commit, but all this commit does is expose that bug, there's no fixes here. Some of the bugs fixed in the previous commits are very timing dependent, as such, they don't always show up. I've had more success when running this test on a very loaded machine -- I usually run ~8 copies of the test in parallel, then the bugs would normally show up pretty quickly. Other than running the test in more configurations, I've not made any changes to what is actually being tested, other than in one place where, when testing with non-stop mode, GDB stops in a different inferior, as such I had to add a new 'inferior 2' call, this can be found in vfork_relations_in_info_inferiors. I have cleaned things up a little, for example, making use of proc_with_prefix to remove some with_test_prefix calls. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30574
2023-07-17gdb: don't resume vfork parent while child is still runningAndrew Burgess1-4/+20
Like the last few commit, this fixes yet another vfork related issue. Like the commit titled: gdb: don't restart vfork parent while waiting for child to finish which addressed a case in linux-nat where we would try to resume a vfork parent, this commit addresses a very similar case, but this time occurring in infrun.c. Just like with that previous commit, this bug results in the assert: x86-linux-dregs.c:146: internal-error: x86_linux_update_debug_registers: Assertion `lwp_is_stopped (lwp)' failed. In this case the issue occurs when target-non-stop is on, but non-stop is off, and again, schedule-multiple is on. As with the previous commit, GDB is in follow-fork-mode child. If you have not done so, it is worth reading the earlier commit as many of the problems leading to the failure are the same, they just appear in a different part of GDB. Here are the steps leading to the assertion failure: 1. The user performs a 'next' over a vfork, GDB stop in the vfork child, 2. As we are planning to follow the child GDB sets the vfork_parent and vfork_child member variables in the two inferiors, the thread_waiting_for_vfork_done member is left as nullptr, that member is only used when GDB is planning to follow the parent inferior, 3. The user does 'continue', our expectation is that the vfork child should resume, and once that process has exited or execd, GDB should detach from the vfork parent. As a result of the 'continue' GDB eventually enters the proceed function, 4. In proceed we selected a ptid_t to resume, because schedule-multiple is on we select minus_one_ptid (see user_visible_resume_ptid), 5. As GDB is running in all-stop on top of non-stop mode, in the proceed function we iterate over all threads that match the resume ptid, which turns out to be all threads, and call proceed_resume_thread_checked. One of the threads we iterate over is the vfork parent thread, 6. As the thread passed to proceed_resume_thread_checked doesn't match any of the early return conditions, GDB will set the thread resumed, 7. As we are resuming one thread at a time, this thread is seen by the lower layers (e.g. linux-nat) as the "event thread", which means we don't apply any of the checks, e.g. is this thread a vfork parent, instead we assume that GDB core knows what it's doing, and linux-nat will resume the thread, we have now incorrectly set running the vfork parent thread when this thread should be waiting for the vfork child to complete, 8. Back in the proceed function GDB continues to iterate over all threads, and now (correctly) resumes the vfork child thread, 8. As the vfork child is still alive the kernel holds the vfork parent stopped, 9. Eventually the child performs its exec and GDB is sent and EXECD event. However, because the parent is resumed, as soon as the child performs its exec the vfork parent also sends a VFORK_DONE event to GDB, 10. Depending on timing both of these events might seem to arrive in GDB at the same time. Normally GDB expects to see the EXECD or EXITED/SIGNALED event from the vfork child before getting the VFORK_DONE in the parent. We know this because it is as a result of the EXECD/EXITED/SIGNALED that GDB detaches from the parent (see handle_vfork_child_exec_or_exit for details). Further the comment in target/waitstatus.h on TARGET_WAITKIND_VFORK_DONE indicates that when we remain attached to the child (not the parent) we should not expect to see a VFORK_DONE, 11. If both events arrive at the same time then GDB will randomly choose one event to handle first, in some cases this will be the VFORK_DONE. As described above, upon seeing a VFORK_DONE GDB expects that (a) the vfork child has finished, however, in this case this is not completely true, the child has finished, but GDB has not processed the event associated with the completion yet, and (b) upon seeing a VFORK_DONE GDB assumes we are remaining attached to the parent, and so resumes the parent process, 12. GDB now handles the EXECD event. In our case we are detaching from the parent, so GDB calls target_detach (see handle_vfork_child_exec_or_exit), 13. While this has been going on the vfork parent is executing, and might even exit, 14. In linux_nat_target::detach the first thing we do is stop all threads in the process we're detaching from, the result of the stop request will be cached on the lwp_info object, 15. In our case the vfork parent has exited though, so when GDB waits for the thread, instead of a stop due to signal, we instead get a thread exited status, 16. Later in the detach process we try to resume the threads just prior to making the ptrace call to actually detach (see detach_one_lwp), as part of the process to resume a thread we try to touch some registers within the thread, and before doing this GDB asserts that the thread is stopped, 17. An exited thread is not classified as stopped, and so the assert triggers! Just like with the earlier commit, the fix is to spot the vfork parent status of the thread, and not resume such threads. Where the earlier commit fixed this in linux-nat, in this case I think the fix should live in infrun.c, in proceed_resume_thread_checked. This function already has a similar check to not resume the vfork parent in the case where we are planning to follow the vfork parent, I propose adding a similar case that checks for the vfork parent when we plan to follow the vfork child. This new check will mean that at step #6 above GDB doesn't try to resume the vfork parent thread, which prevents the VFORK_DONE from ever arriving. Once GDB sees the EXECD/EXITED/SIGNALLED event from the vfork child GDB will detach from the parent. There's no test included in this commit. In a subsequent commit I will expand gdb.base/foll-vfork.exp which is when this bug would be exposed. If you do want to reproduce this failure then you will for certainly need to run the gdb.base/foll-vfork.exp test in a loop as the failures are all very timing sensitive. I've found that running multiple copies in parallel makes the failure more likely to appear, I usually run ~6 copies in parallel and expect to see a failure after within 10mins.
2023-07-17gdb, infrun: refactor part of `proceed` into separate functionMihails Strasuns1-69/+86
Split the thread resuming code from proceed into new function proceed_resume_thread_checked. Co-Authored-By: Christina Schimpe <christina.schimpe@intel.com>
2023-07-17gdb: fix an issue with vfork in non-stop modeAndrew Burgess1-12/+22
This commit fixes a bug introduced by this commit: commit d8bbae6ea080249c05ca90b1f8640fde48a18301 Date: Fri Jan 14 15:40:59 2022 -0500 gdb: fix handling of vfork by multi-threaded program (follow-fork-mode=parent, detach-on-fork=on) The problem can be seen in this GDB session: $ gdb -q (gdb) set non-stop on (gdb) file ./gdb/testsuite/outputs/gdb.base/foll-vfork/foll-vfork Reading symbols from ./gdb/testsuite/outputs/gdb.base/foll-vfork/foll-vfork... (gdb) tcatch vfork Catchpoint 1 (vfork) (gdb) run Starting program: /tmp/gdb/testsuite/outputs/gdb.base/foll-vfork/foll-vfork Temporary catchpoint 1 (vforked process 1375914), 0x00007ffff7d5043c in vfork () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff7d5043c in vfork () from /lib64/libc.so.6 #1 0x00000000004011af in main (argc=1, argv=0x7fffffffad88) at .../gdb/testsuite/gdb.base/foll-vfork.c:32 (gdb) finish Run till exit from #0 0x00007ffff7d5043c in vfork () from /lib64/libc.so.6 [Detaching after vfork from child process 1375914] No unwaited-for children left. (gdb) Notice the "No unwaited-for children left." error. This is incorrect, given where we are stopped there's no reason why we shouldn't be able to use "finish" to return to the main frame. When the inferior is stopped as a result of the 'tcatch vfork', the inferior is in the process of performing the vfork, that is, GDB has seen the VFORKED event, but has not yet attached to the new child process, nor has the child process been resumed. However, GDB has seen the VFORKED, and, as we are going to follow the parent process, the inferior for the vfork parent will have its thread_waiting_for_vfork_done member variable set, this will point to the one and only thread that makes up the vfork parent process. When the "finish" command is used GDB eventually ends up in the proceed function (in infrun.c), in here we pass through all the function until we eventually encounter this 'else if' condition: else if (!cur_thr->resumed () && !thread_is_in_step_over_chain (cur_thr) /* In non-stop, forbid resuming a thread if some other thread of that inferior is waiting for a vfork-done event (this means breakpoints are out for this inferior). */ && !(non_stop && cur_thr->inf->thread_waiting_for_vfork_done != nullptr)) { The first two of these conditions will both be true, the thread is not already resumed, and is not in the step-over chain, however, the third condition, this one: && !(non_stop && cur_thr->inf->thread_waiting_for_vfork_done != nullptr)) is false, and this prevents the thread we are trying to finish from being resumed. This condition is false because (a) non_stop is true, and (b) cur_thr->inf->thread_waiting_for_vfork_done is not nullptr (see above for why). Now, if we check the comment embedded within the condition it says: /* In non-stop, forbid resuming a thread if some other thread of that inferior is waiting for a vfork-done event (this means breakpoints are out for this inferior). */ And this makes sense, if we have a vfork parent with two thread, and one thread has performed a vfork, then we shouldn't try to resume the second thread. However, if we are trying to resume the thread that actually performed a vfork, then this is fine. If we never resume the vfork parent then we'll never get a VFORK_DONE event, and so the vfork will never complete. Thus, the condition should actually be: && !(non_stop && cur_thr->inf->thread_waiting_for_vfork_done != nullptr && cur_thr->inf->thread_waiting_for_vfork_done != cur_thr)) This extra check will allow the vfork parent thread to resume, but prevent any other thread in the vfork parent process from resuming. This is the same condition that already exists in the all-stop on a non-stop-target block earlier in the proceed function. My actual fix is slightly different to the above, first, I've chosen to use a nested 'if' check instead of extending the original 'else if' check, this makes it easier to write a longer comment explaining what's going on, and second, instead of checking 'non_stop' I've switched to checking 'target_is_non_stop_p'. In this context this is effectively the same thing, a previous 'else if' block in proceed already handles '!non_stop && target_is_non_stop_p ()', so by the time we get here, if 'target_is_non_stop_p ()' then we must be running in non_stop mode. Both of these tweaks will make the next patch easier, which is a refactor to merge two parts of the proceed function, so this nested 'if' block is not going to exist for long. For testing, there is no test included with this commit. The test was exposed when using a modified version of the gdb.base/foll-vfork.exp test script, however, there are other bugs that are exposed when using the modified test script. These bugs will be addressed in subsequent commits, and then I'll add the updated gdb.base/foll-vfork.exp. If you wish to reproduce this failure then grab the updates to gdb.base/foll-vfork.exp from the later commit and run this test, the failure is always reproducible.
2023-07-17gdb: don't restart vfork parent while waiting for child to finishAndrew Burgess1-1/+8
While working on a later patch, which changes gdb.base/foll-vfork.exp, I noticed that sometimes I would hit this assert: x86_linux_update_debug_registers: Assertion `lwp_is_stopped (lwp)' failed. I eventually tracked it down to a combination of schedule-multiple mode being on, target-non-stop being off, follow-fork-mode being set to child, and some bad timing. The failing case is pretty simple, a single threaded application performs a vfork, the child process then execs some other application while the parent process (once the vfork child has completed its exec) just exits. As best I understand things, here's what happens when things go wrong: 1. The parent process performs a vfork, GDB sees the VFORKED event and creates an inferior and thread for the vfork child, 2. GDB resumes the vfork child process. As schedule-multiple is on and target-non-stop is off, this is translated into a request to start all processes (see user_visible_resume_ptid), 3. In the linux-nat layer we spot that one of the threads we are about to start is a vfork parent, and so don't start that thread (see resume_lwp), the vfork child thread is resumed, 4. GDB waits for the next event, eventually entering linux_nat_target::wait, which in turn calls linux_nat_wait_1, 5. In linux_nat_wait_1 we eventually call resume_stopped_resumed_lwps, this should restart threads that have stopped but don't actually have anything interesting to report. 6. Unfortunately, resume_stopped_resumed_lwps doesn't check for vfork parents like resume_lwp does, so at this point the vfork parent is resumed. This feels like the start of the bug, and this is where I'm proposing to fix things, but, resuming the vfork parent isn't the worst thing in the world because.... 7. As the vfork child is still alive the kernel holds the vfork parent stopped, 8. Eventually the child performs its exec and GDB is sent and EXECD event. However, because the parent is resumed, as soon as the child performs its exec the vfork parent also sends a VFORK_DONE event to GDB, 9. Depending on timing both of these events might seem to arrive in GDB at the same time. Normally GDB expects to see the EXECD or EXITED/SIGNALED event from the vfork child before getting the VFORK_DONE in the parent. We know this because it is as a result of the EXECD/EXITED/SIGNALED that GDB detaches from the parent (see handle_vfork_child_exec_or_exit for details). Further the comment in target/waitstatus.h on TARGET_WAITKIND_VFORK_DONE indicates that when we remain attached to the child (not the parent) we should not expect to see a VFORK_DONE, 10. If both events arrive at the same time then GDB will randomly choose one event to handle first, in some cases this will be the VFORK_DONE. As described above, upon seeing a VFORK_DONE GDB expects that (a) the vfork child has finished, however, in this case this is not completely true, the child has finished, but GDB has not processed the event associated with the completion yet, and (b) upon seeing a VFORK_DONE GDB assumes we are remaining attached to the parent, and so resumes the parent process, 11. GDB now handles the EXECD event. In our case we are detaching from the parent, so GDB calls target_detach (see handle_vfork_child_exec_or_exit), 12. While this has been going on the vfork parent is executing, and might even exit, 13. In linux_nat_target::detach the first thing we do is stop all threads in the process we're detaching from, the result of the stop request will be cached on the lwp_info object, 14. In our case the vfork parent has exited though, so when GDB waits for the thread, instead of a stop due to signal, we instead get a thread exited status, 15. Later in the detach process we try to resume the threads just prior to making the ptrace call to actually detach (see detach_one_lwp), as part of the process to resume a thread we try to touch some registers within the thread, and before doing this GDB asserts that the thread is stopped, 16. An exited thread is not classified as stopped, and so the assert triggers! So there's two bugs I see here. The first, and most critical one here is in step #6. I think that resume_stopped_resumed_lwps should not resume a vfork parent, just like resume_lwp doesn't resume a vfork parent. With this change in place the vfork parent will remain stopped in step instead GDB will only see the EXECD/EXITED/SIGNALLED event. The problems in #9 and #10 are therefore skipped and we arrive at #11, handling the EXECD event. As the parent is still stopped #12 doesn't apply, and in #13 when we try to stop the process we will see that it is already stopped, there's no risk of the vfork parent exiting before we get to this point. And finally, in #15 we are safe to poke the process registers because it will not have exited by this point. However, I did mention two bugs. The second bug I've not yet managed to actually trigger, but I'm convinced it must exist: if we forget vforks for a moment, in step #13 above, when linux_nat_target::detach is called, we first try to stop all threads in the process GDB is detaching from. If we imagine a multi-threaded inferior with many threads, and GDB running in non-stop mode, then, if the user tries to detach there is a chance that thread could exit just as linux_nat_target::detach is entered, in which case we should be able to trigger the same assert. But, like I said, I've not (yet) managed to trigger this second bug, and even if I could, the fix would not belong in this commit, so I'm pointing this out just for completeness. There's no test included in this commit. In a couple of commits time I will expand gdb.base/foll-vfork.exp which is when this bug would be exposed. Unfortunately there are at least two other bugs (separate from the ones discussed above) that need fixing first, these will be fixed in the next commits before the gdb.base/foll-vfork.exp test is expanded. If you do want to reproduce this failure then you will for certainly need to run the gdb.base/foll-vfork.exp test in a loop as the failures are all very timing sensitive. I've found that running multiple copies in parallel makes the failure more likely to appear, I usually run ~6 copies in parallel and expect to see a failure after within 10mins.
2023-07-17gdb: catch more errors in gdb.base/foll-vfork.expAndrew Burgess1-2/+8
For *reasons* I was looking at gdb.base/foll-vfork.exp. This test script has a proc 'setup_gdb' that could (potentially) fail. The setup_gdb proc is called from many places and I, initially, didn't think that we were checking if setup_gdb had failed or not. My confusion was because I didn't understand what this tcl construct did: return -code return this will actually act as a return in the context of a proc's caller, effectively returning two levels of the call stack. Neat (I guess). So it turns out my worries were misplaced, everywhere setup_gdb is called, if setup_gdb fails then we will (magically) return. However, I did spot one place where we managed to confuse ourselves with our cleverness. In check_vfork_catchpoints, this proc is called to check that GDB is able to catch vforks or not. This proc is called early in the test script, and the intention is that, should this proc fail, we'll mark the whole test script as unsupported and then move onto the next test script. However, check_vfork_catchpoints also uses setup_gdb, and so, if that call to setup_gdb fails we'll end up returning immediately from check_vfork_catchpoints, and then continue with the test of _this_ test script, which is not correct. To fix this I see two choices, one is remove the use of 'return -code return' from setup_gdb, however, this would require every use of setup_gdb to then be placed inside: if { ![setup_gdb] } { return } Or, I can wrap the one call to setup_gdb in check_vfork_catchpoints and check its return code. I chose the second option as this is the smaller code change. There should be no change in what is tested after this commit.
2023-07-16[gdb/testsuite] Handle has_native_target in ↵Tom de Vries1-0/+1
gdb.testsuite/gdb-caching-proc-consistency.exp With test-case gdb.testsuite/gdb-caching-proc-consistency.exp we run into: ... ERROR: no fileid for xerxes Couldn't send help target native to GDB. UNRESOLVED: <exp>: have_native_target: initial: help target native ... Fix this by handling have_native_target in gdb.testsuite/gdb-caching-proc-consistency.exp. Tested on x86_64-linux.
2023-07-15gdb/tui: make tui_win_info::title privateAndrew Burgess6-15/+20
This commit builds on this earlier work: commit 9fe01a376b2fb096e4836e985ba316ce9dc02399 Date: Thu Jun 29 11:26:55 2023 -0600 Update TUI window title when changed and makes tui_win_info::title private, renaming to m_title at the same time. There's a new tui_win_info::title() member function to provide read-only access to the title. There should be no user visible changes after this commit. Approved-By: Tom Tromey <tom@tromey.com>
2023-07-15gdb: style filenames in separate debug file warningsAndrew Burgess11-53/+167
After the commit: commit 6647f05df023b63bbe056e9167e9e234172fa2ca Date: Tue Jan 24 18:13:38 2023 +0100 gdb: defer warnings when loading separate debug files It was pointed out[1] that the warnings being deferred and then later emitted lacked styling. The warnings lacked styling before the above commit, but it was suggested that the filenames in these warnings should be styled, and this commit does this. There were a couple of previous attempts[2][3][4] to solve this problem, but these all tried to extend the mechanism introduced in the above commit, the deferred warnings were placed directly into a std::vector, but now we tried to, when appropriate, style these warnings. The review feedback that this approach looked too complex. So instead, this revision adds a new helper class 'deferred_warnings' which can be used to collect a set of deferred warnings, and then emit these deferred warnings later, if needed. This helper class hides the complexity, so at the point the deferred warning is created no extra logic is required. The deferred_warnings class will style the deferred warnings only if gdb_stderr supports styling. GDB's warnings are sent to gdb_stderr, so this should ensure we only style when expected. There was also review feedback[5] that all of the warnings should be bundled into a single string_file, this has not been done. I feel pretty strongly that separate warnings should be emitted using separate "warning" calls. If we do end up with multiple warnings in this case they aren't really related, one will be about looking up debug via .gnu_debuglink, while the other will be about build-id based lookup. So I'd really rather keep the warnings separate. [1] https://inbox.sourceware.org/gdb-patches/87edr9pcku.fsf@tromey.com/ [2] https://inbox.sourceware.org/gdb-patches/20230216195604.2685177-1-ahajkova@redhat.com/ [3] https://inbox.sourceware.org/gdb-patches/20230217123547.2737612-1-ahajkova@redhat.com/ [4] https://inbox.sourceware.org/gdb-patches/20230320145638.1202335-1-ahajkova@redhat.com/ [5] https://inbox.sourceware.org/gdb-patches/87o7nh1g8h.fsf@tromey.com/ Co-Authored-By: Alexandra Hájková <ahajkova@redhat.com> Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-07-15[gdb/testsuite] Fix gdb.dwarf2/forward-spec.exp with read1Tom de Vries1-2/+2
When running test-case gdb.dwarf2/forward-spec.exp with check-read1 we run into: ... parent: ((cooked_index_entry *) 0xFAIL: <exp>: v has a parent 7fdc1c002ed0) [ns]^M ... The problem is using regexps containing '.' to avoid escaping, which makes them too generic. Fix this by eliminating the '.' from the regexps. Tested on x86_64-linux.
2023-07-14Use correct inferior in Inferior.read_memory et alTom Tromey2-7/+63
A user noticed that Inferior.read_memory and a few other Python APIs will always use the currently selected inferior, not the one passed to the call. This patch fixes the bug by arranging to switch to the inferior. I found this same issue in several APIs, so this fixes them all. I also added a few missing calls to INFPY_REQUIRE_VALID to these methods. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30615 Approved-By: Pedro Alves <pedro@palves.net>
2023-07-14Introduce scoped_restore_current_inferior_for_memoryTom Tromey3-22/+35
This introduces a new class, scoped_restore_current_inferior_for_memory, and arranges to use it in a few places. This class is intended to handle setting up and restoring the various globals that are needed to read or write memory -- but without invalidating the frame cache. I wasn't able to test the change to aix-thread.c. Approved-By: Pedro Alves <pedro@palves.net>
2023-07-14Remove obsolete comment from gdbthread.hTom Tromey1-1/+1
A comment in gdbthread.h refers to a global that no longer exists. Approved-By: Pedro Alves <pedro@palves.net>
2023-07-14Rename Python variable in py-inferior.expTom Tromey1-5/+6
py-inferior.exp creates a Python variable named 'str'. This clashes with the built-in type of the same name and can be confusing when trying to evaluate Python code when debugging the test case. This patch renames it. Approved-By: Pedro Alves <pedro@palves.net>
2023-07-14Refactor py-inferior.expTom Tromey1-14/+29
This changes py-inferior.exp to make it a bit more robust when adding new inferiors during the course of the test. Approved-By: Pedro Alves <pedro@palves.net>
2023-07-14Minor cleanups in py-inferior.expTom Tromey1-4/+3
While working on this series, I noticed a some oddities in py-inferior.exp. One is an obviously incorrect comment, and the others are confusing test names. This patch fixes these. Approved-By: Pedro Alves <pedro@palves.net>
2023-07-14Revert "Simplify auto_load_expand_dir_vars and remove substitute_path_component"Tom Tromey5-21/+121
This reverts commit 02601231fdd91a7bd4837ce202906ea2ce661489. This commit was a refactoring to remove an xrealloc and simplify utils.[ch]. However, it has a flaw -- it mishandles a substitution like "$datadir/subdir". I am backing out the patch in the interests of fixing the regression before GDB 14. It can be reinstated (with modifications) later if we like. Regression tested on x86-64 Fedora 36.
2023-07-14Test that native targets can read a tdesc without a process attached.John Baldwin1-0/+27
This ensures that 'unset tdesc filename' does not generate any output on a "bare" native target inferior without an attached process.
2023-07-14Add a have_native_target helper function for use with require.John Baldwin2-17/+15
Move logic from auto-connect-native-target.exp into this helper.
2023-07-14*-linux-nat: Handle null inferior in read_description.John Baldwin7-0/+22
Don't invoke ptrace in the target read_description method if there is not an active inferior to query via ptrace. Instead, use the default register set for the architecture. Previously the native target could report an error from a failed ptrace operation when fetching a tdesc without an attached process. For example on Linux x86-64: (gdb) target native Done. Use the "run" command to start a process. (gdb) unset tdesc filename Couldn't get CS register: No such process.
2023-07-14*-fbsd-nat: Handle null inferior in read_description.John Baldwin4-0/+12
Don't invoke ptrace in the target read_description method if there is not an active inferior to query via ptrace. Instead, use the default register set for the architecture. Previously the native target could report an error from a failed ptrace operation when fetching a tdesc without an attached process. For example on FreeBSD/amd64: (gdb) target native Done. Use the "run" command to start a process. (gdb) unset tdesc filename Couldn't get registers: Operation not permitted.
2023-07-14gdb/doc: document '+' argument for 'list' commandBruno Larsen2-0/+4
The command 'list' has accepted the argument '+' for many years already, but this option wasn't documented either in the texinfo docs or in the help text for the command. This commit documents it. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2023-07-14gdb/cli: Improve UX when using list with no argsBruno Larsen6-9/+48
When using "list" with no arguments, GDB will first print the lines around where the inferior is stopped, then print the next N lines until reaching the end of file, at which point it warns the user "Line X out of range, file Y only has X-1 lines.". This is usually desirable, but if the user can no longer see the original line, they may have forgotten the current line or that a list command was used at all, making GDB's error message look cryptic. It was reported in bugzilla as PR cli/30497. This commit improves the user experience by changing the behavior of "list" slightly when a user passes no arguments. It now prints that the end of the file has been reached and recommends that the user use the command "list ." instead. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30497 Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2023-07-14gdb/cli: add '.' as an argument for 'list' commandBruno Larsen5-3/+78
Currently, after the user has used the list command once, there is no self-contained way to ask GDB to print the location where the inferior is stopped. The current best options require either using a separate command to scope out where the inferior is stopped, or using "list *$pc" requiring knowledge of GDB standard registers. This commit adds a way to do that using '.' as a new argument for the 'list' command. If the inferior isn't running, the command prints around the main function. Because this necessitated having the inferior running and the test was (seemingly unnecessarily) using printf in a non-essential way and it would make the resulting log harder to read for no benefit, it was replaced by a different statement. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2023-07-14gdb/cli: Factor out code to list lines around a given lineBruno Larsen1-13/+23
A future patch will add more situations that calculates "lines around a certain point" to be printed using print_source_lines, and the logic could be re-used. As a preparation for those commits, this one factors out that part of the logic of the list command into its own function. No functional changes are expected Approved-By: Tom Tromey <tom@tromey.com>
2023-07-13Implement 'Enum_Val and 'Enum_RepTom Tromey6-16/+99
This patch implements the Ada 2022 attributes 'Enum_Val and 'Enum_Rep. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-07-13Remove ada_attribute_nameTom Tromey1-32/+9
ada_attribute_name uses an array that must be kept in sync with an enum -- but the comment here refers to an enum that no longer exists. Looking at the sole caller, I see this can only be called for two opcodes. So, remove this entirely and inline it.