mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-02 20:53:06 +08:00
1099 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
758cb81029 |
Use "bool" in fetch_inferior_event
A while back I noticed that fetch_inferior_event used "int" for should_stop, whereas it can be bool. The method it is assigned from: should_stop = thread_fsm->should_stop (thr); ... already returns bool. Tested by rebuilding. gdb/ChangeLog 2020-11-14 Tom Tromey <tom@tromey.com> * infrun.c (fetch_inferior_event): Use "bool" for should_stop. |
|||
dda83cd783 |
gdb, gdbserver, gdbsupport: fix leading space vs tabs issues
Many spots incorrectly use only spaces for indentation (for example, there are a lot of spots in ada-lang.c). I've always found it awkward when I needed to edit one of these spots: do I keep the original wrong indentation, or do I fix it? What if the lines around it are also wrong, do I fix them too? I probably don't want to fix them in the same patch, to avoid adding noise to my patch. So I propose to fix as much as possible once and for all (hopefully). One typical counter argument for this is that it makes code archeology more difficult, because git-blame will show this commit as the last change for these lines. My counter counter argument is: when git-blaming, you often need to do "blame the file at the parent commit" anyway, to go past some other refactor that touched the line you are interested in, but is not the change you are looking for. So you already need a somewhat efficient way to do this. Using some interactive tool, rather than plain git-blame, makes this trivial. For example, I use "tig blame <file>", where going back past the commit that changed the currently selected line is one keystroke. It looks like Magit in Emacs does it too (though I've never used it). Web viewers of Github and Gitlab do it too. My point is that it won't really make archeology more difficult. The other typical counter argument is that it will cause conflicts with existing patches. That's true... but it's a one time cost, and those are not conflicts that are difficult to resolve. I have also tried "git rebase --ignore-whitespace", it seems to work well. Although that will re-introduce the faulty indentation, so one needs to take care of fixing the indentation in the patch after that (which is easy). gdb/ChangeLog: * aarch64-linux-tdep.c: Fix indentation. * aarch64-ravenscar-thread.c: Fix indentation. * aarch64-tdep.c: Fix indentation. * aarch64-tdep.h: Fix indentation. * ada-lang.c: Fix indentation. * ada-lang.h: Fix indentation. * ada-tasks.c: Fix indentation. * ada-typeprint.c: Fix indentation. * ada-valprint.c: Fix indentation. * ada-varobj.c: Fix indentation. * addrmap.c: Fix indentation. * addrmap.h: Fix indentation. * agent.c: Fix indentation. * aix-thread.c: Fix indentation. * alpha-bsd-nat.c: Fix indentation. * alpha-linux-tdep.c: Fix indentation. * alpha-mdebug-tdep.c: Fix indentation. * alpha-nbsd-tdep.c: Fix indentation. * alpha-obsd-tdep.c: Fix indentation. * alpha-tdep.c: Fix indentation. * amd64-bsd-nat.c: Fix indentation. * amd64-darwin-tdep.c: Fix indentation. * amd64-linux-nat.c: Fix indentation. * amd64-linux-tdep.c: Fix indentation. * amd64-nat.c: Fix indentation. * amd64-obsd-tdep.c: Fix indentation. * amd64-tdep.c: Fix indentation. * amd64-windows-tdep.c: Fix indentation. * annotate.c: Fix indentation. * arc-tdep.c: Fix indentation. * arch-utils.c: Fix indentation. * arch/arm-get-next-pcs.c: Fix indentation. * arch/arm.c: Fix indentation. * arm-linux-nat.c: Fix indentation. * arm-linux-tdep.c: Fix indentation. * arm-nbsd-tdep.c: Fix indentation. * arm-pikeos-tdep.c: Fix indentation. * arm-tdep.c: Fix indentation. * arm-tdep.h: Fix indentation. * arm-wince-tdep.c: Fix indentation. * auto-load.c: Fix indentation. * auxv.c: Fix indentation. * avr-tdep.c: Fix indentation. * ax-gdb.c: Fix indentation. * ax-general.c: Fix indentation. * bfin-linux-tdep.c: Fix indentation. * block.c: Fix indentation. * block.h: Fix indentation. * blockframe.c: Fix indentation. * bpf-tdep.c: Fix indentation. * break-catch-sig.c: Fix indentation. * break-catch-syscall.c: Fix indentation. * break-catch-throw.c: Fix indentation. * breakpoint.c: Fix indentation. * breakpoint.h: Fix indentation. * bsd-uthread.c: Fix indentation. * btrace.c: Fix indentation. * build-id.c: Fix indentation. * buildsym-legacy.h: Fix indentation. * buildsym.c: Fix indentation. * c-typeprint.c: Fix indentation. * c-valprint.c: Fix indentation. * c-varobj.c: Fix indentation. * charset.c: Fix indentation. * cli/cli-cmds.c: Fix indentation. * cli/cli-decode.c: Fix indentation. * cli/cli-decode.h: Fix indentation. * cli/cli-script.c: Fix indentation. * cli/cli-setshow.c: Fix indentation. * coff-pe-read.c: Fix indentation. * coffread.c: Fix indentation. * compile/compile-cplus-types.c: Fix indentation. * compile/compile-object-load.c: Fix indentation. * compile/compile-object-run.c: Fix indentation. * completer.c: Fix indentation. * corefile.c: Fix indentation. * corelow.c: Fix indentation. * cp-abi.h: Fix indentation. * cp-namespace.c: Fix indentation. * cp-support.c: Fix indentation. * cp-valprint.c: Fix indentation. * cris-linux-tdep.c: Fix indentation. * cris-tdep.c: Fix indentation. * darwin-nat-info.c: Fix indentation. * darwin-nat.c: Fix indentation. * darwin-nat.h: Fix indentation. * dbxread.c: Fix indentation. * dcache.c: Fix indentation. * disasm.c: Fix indentation. * dtrace-probe.c: Fix indentation. * dwarf2/abbrev.c: Fix indentation. * dwarf2/attribute.c: Fix indentation. * dwarf2/expr.c: Fix indentation. * dwarf2/frame.c: Fix indentation. * dwarf2/index-cache.c: Fix indentation. * dwarf2/index-write.c: Fix indentation. * dwarf2/line-header.c: Fix indentation. * dwarf2/loc.c: Fix indentation. * dwarf2/macro.c: Fix indentation. * dwarf2/read.c: Fix indentation. * dwarf2/read.h: Fix indentation. * elfread.c: Fix indentation. * eval.c: Fix indentation. * event-top.c: Fix indentation. * exec.c: Fix indentation. * exec.h: Fix indentation. * expprint.c: Fix indentation. * f-lang.c: Fix indentation. * f-typeprint.c: Fix indentation. * f-valprint.c: Fix indentation. * fbsd-nat.c: Fix indentation. * fbsd-tdep.c: Fix indentation. * findvar.c: Fix indentation. * fork-child.c: Fix indentation. * frame-unwind.c: Fix indentation. * frame-unwind.h: Fix indentation. * frame.c: Fix indentation. * frv-linux-tdep.c: Fix indentation. * frv-tdep.c: Fix indentation. * frv-tdep.h: Fix indentation. * ft32-tdep.c: Fix indentation. * gcore.c: Fix indentation. * gdb_bfd.c: Fix indentation. * gdbarch.sh: Fix indentation. * gdbarch.c: Re-generate * gdbarch.h: Re-generate. * gdbcore.h: Fix indentation. * gdbthread.h: Fix indentation. * gdbtypes.c: Fix indentation. * gdbtypes.h: Fix indentation. * glibc-tdep.c: Fix indentation. * gnu-nat.c: Fix indentation. * gnu-nat.h: Fix indentation. * gnu-v2-abi.c: Fix indentation. * gnu-v3-abi.c: Fix indentation. * go32-nat.c: Fix indentation. * guile/guile-internal.h: Fix indentation. * guile/scm-cmd.c: Fix indentation. * guile/scm-frame.c: Fix indentation. * guile/scm-iterator.c: Fix indentation. * guile/scm-math.c: Fix indentation. * guile/scm-ports.c: Fix indentation. * guile/scm-pretty-print.c: Fix indentation. * guile/scm-value.c: Fix indentation. * h8300-tdep.c: Fix indentation. * hppa-linux-nat.c: Fix indentation. * hppa-linux-tdep.c: Fix indentation. * hppa-nbsd-nat.c: Fix indentation. * hppa-nbsd-tdep.c: Fix indentation. * hppa-obsd-nat.c: Fix indentation. * hppa-tdep.c: Fix indentation. * hppa-tdep.h: Fix indentation. * i386-bsd-nat.c: Fix indentation. * i386-darwin-nat.c: Fix indentation. * i386-darwin-tdep.c: Fix indentation. * i386-dicos-tdep.c: Fix indentation. * i386-gnu-nat.c: Fix indentation. * i386-linux-nat.c: Fix indentation. * i386-linux-tdep.c: Fix indentation. * i386-nto-tdep.c: Fix indentation. * i386-obsd-tdep.c: Fix indentation. * i386-sol2-nat.c: Fix indentation. * i386-tdep.c: Fix indentation. * i386-tdep.h: Fix indentation. * i386-windows-tdep.c: Fix indentation. * i387-tdep.c: Fix indentation. * i387-tdep.h: Fix indentation. * ia64-libunwind-tdep.c: Fix indentation. * ia64-libunwind-tdep.h: Fix indentation. * ia64-linux-nat.c: Fix indentation. * ia64-linux-tdep.c: Fix indentation. * ia64-tdep.c: Fix indentation. * ia64-tdep.h: Fix indentation. * ia64-vms-tdep.c: Fix indentation. * infcall.c: Fix indentation. * infcmd.c: Fix indentation. * inferior.c: Fix indentation. * infrun.c: Fix indentation. * iq2000-tdep.c: Fix indentation. * language.c: Fix indentation. * linespec.c: Fix indentation. * linux-fork.c: Fix indentation. * linux-nat.c: Fix indentation. * linux-tdep.c: Fix indentation. * linux-thread-db.c: Fix indentation. * lm32-tdep.c: Fix indentation. * m2-lang.c: Fix indentation. * m2-typeprint.c: Fix indentation. * m2-valprint.c: Fix indentation. * m32c-tdep.c: Fix indentation. * m32r-linux-tdep.c: Fix indentation. * m32r-tdep.c: Fix indentation. * m68hc11-tdep.c: Fix indentation. * m68k-bsd-nat.c: Fix indentation. * m68k-linux-nat.c: Fix indentation. * m68k-linux-tdep.c: Fix indentation. * m68k-tdep.c: Fix indentation. * machoread.c: Fix indentation. * macrocmd.c: Fix indentation. * macroexp.c: Fix indentation. * macroscope.c: Fix indentation. * macrotab.c: Fix indentation. * macrotab.h: Fix indentation. * main.c: Fix indentation. * mdebugread.c: Fix indentation. * mep-tdep.c: Fix indentation. * mi/mi-cmd-catch.c: Fix indentation. * mi/mi-cmd-disas.c: Fix indentation. * mi/mi-cmd-env.c: Fix indentation. * mi/mi-cmd-stack.c: Fix indentation. * mi/mi-cmd-var.c: Fix indentation. * mi/mi-cmds.c: Fix indentation. * mi/mi-main.c: Fix indentation. * mi/mi-parse.c: Fix indentation. * microblaze-tdep.c: Fix indentation. * minidebug.c: Fix indentation. * minsyms.c: Fix indentation. * mips-linux-nat.c: Fix indentation. * mips-linux-tdep.c: Fix indentation. * mips-nbsd-tdep.c: Fix indentation. * mips-tdep.c: Fix indentation. * mn10300-linux-tdep.c: Fix indentation. * mn10300-tdep.c: Fix indentation. * moxie-tdep.c: Fix indentation. * msp430-tdep.c: Fix indentation. * namespace.h: Fix indentation. * nat/fork-inferior.c: Fix indentation. * nat/gdb_ptrace.h: Fix indentation. * nat/linux-namespaces.c: Fix indentation. * nat/linux-osdata.c: Fix indentation. * nat/netbsd-nat.c: Fix indentation. * nat/x86-dregs.c: Fix indentation. * nbsd-nat.c: Fix indentation. * nbsd-tdep.c: Fix indentation. * nios2-linux-tdep.c: Fix indentation. * nios2-tdep.c: Fix indentation. * nto-procfs.c: Fix indentation. * nto-tdep.c: Fix indentation. * objfiles.c: Fix indentation. * objfiles.h: Fix indentation. * opencl-lang.c: Fix indentation. * or1k-tdep.c: Fix indentation. * osabi.c: Fix indentation. * osabi.h: Fix indentation. * osdata.c: Fix indentation. * p-lang.c: Fix indentation. * p-typeprint.c: Fix indentation. * p-valprint.c: Fix indentation. * parse.c: Fix indentation. * ppc-linux-nat.c: Fix indentation. * ppc-linux-tdep.c: Fix indentation. * ppc-nbsd-nat.c: Fix indentation. * ppc-nbsd-tdep.c: Fix indentation. * ppc-obsd-nat.c: Fix indentation. * ppc-ravenscar-thread.c: Fix indentation. * ppc-sysv-tdep.c: Fix indentation. * ppc64-tdep.c: Fix indentation. * printcmd.c: Fix indentation. * proc-api.c: Fix indentation. * producer.c: Fix indentation. * producer.h: Fix indentation. * prologue-value.c: Fix indentation. * prologue-value.h: Fix indentation. * psymtab.c: Fix indentation. * python/py-arch.c: Fix indentation. * python/py-bpevent.c: Fix indentation. * python/py-event.c: Fix indentation. * python/py-event.h: Fix indentation. * python/py-finishbreakpoint.c: Fix indentation. * python/py-frame.c: Fix indentation. * python/py-framefilter.c: Fix indentation. * python/py-inferior.c: Fix indentation. * python/py-infthread.c: Fix indentation. * python/py-objfile.c: Fix indentation. * python/py-prettyprint.c: Fix indentation. * python/py-registers.c: Fix indentation. * python/py-signalevent.c: Fix indentation. * python/py-stopevent.c: Fix indentation. * python/py-stopevent.h: Fix indentation. * python/py-threadevent.c: Fix indentation. * python/py-tui.c: Fix indentation. * python/py-unwind.c: Fix indentation. * python/py-value.c: Fix indentation. * python/py-xmethods.c: Fix indentation. * python/python-internal.h: Fix indentation. * python/python.c: Fix indentation. * ravenscar-thread.c: Fix indentation. * record-btrace.c: Fix indentation. * record-full.c: Fix indentation. * record.c: Fix indentation. * reggroups.c: Fix indentation. * regset.h: Fix indentation. * remote-fileio.c: Fix indentation. * remote.c: Fix indentation. * reverse.c: Fix indentation. * riscv-linux-tdep.c: Fix indentation. * riscv-ravenscar-thread.c: Fix indentation. * riscv-tdep.c: Fix indentation. * rl78-tdep.c: Fix indentation. * rs6000-aix-tdep.c: Fix indentation. * rs6000-lynx178-tdep.c: Fix indentation. * rs6000-nat.c: Fix indentation. * rs6000-tdep.c: Fix indentation. * rust-lang.c: Fix indentation. * rx-tdep.c: Fix indentation. * s12z-tdep.c: Fix indentation. * s390-linux-tdep.c: Fix indentation. * score-tdep.c: Fix indentation. * ser-base.c: Fix indentation. * ser-mingw.c: Fix indentation. * ser-uds.c: Fix indentation. * ser-unix.c: Fix indentation. * serial.c: Fix indentation. * sh-linux-tdep.c: Fix indentation. * sh-nbsd-tdep.c: Fix indentation. * sh-tdep.c: Fix indentation. * skip.c: Fix indentation. * sol-thread.c: Fix indentation. * solib-aix.c: Fix indentation. * solib-darwin.c: Fix indentation. * solib-frv.c: Fix indentation. * solib-svr4.c: Fix indentation. * solib.c: Fix indentation. * source.c: Fix indentation. * sparc-linux-tdep.c: Fix indentation. * sparc-nbsd-tdep.c: Fix indentation. * sparc-obsd-tdep.c: Fix indentation. * sparc-ravenscar-thread.c: Fix indentation. * sparc-tdep.c: Fix indentation. * sparc64-linux-tdep.c: Fix indentation. * sparc64-nbsd-tdep.c: Fix indentation. * sparc64-obsd-tdep.c: Fix indentation. * sparc64-tdep.c: Fix indentation. * stabsread.c: Fix indentation. * stack.c: Fix indentation. * stap-probe.c: Fix indentation. * stubs/ia64vms-stub.c: Fix indentation. * stubs/m32r-stub.c: Fix indentation. * stubs/m68k-stub.c: Fix indentation. * stubs/sh-stub.c: Fix indentation. * stubs/sparc-stub.c: Fix indentation. * symfile-mem.c: Fix indentation. * symfile.c: Fix indentation. * symfile.h: Fix indentation. * symmisc.c: Fix indentation. * symtab.c: Fix indentation. * symtab.h: Fix indentation. * target-float.c: Fix indentation. * target.c: Fix indentation. * target.h: Fix indentation. * tic6x-tdep.c: Fix indentation. * tilegx-linux-tdep.c: Fix indentation. * tilegx-tdep.c: Fix indentation. * top.c: Fix indentation. * tracefile-tfile.c: Fix indentation. * tracepoint.c: Fix indentation. * tui/tui-disasm.c: Fix indentation. * tui/tui-io.c: Fix indentation. * tui/tui-regs.c: Fix indentation. * tui/tui-stack.c: Fix indentation. * tui/tui-win.c: Fix indentation. * tui/tui-winsource.c: Fix indentation. * tui/tui.c: Fix indentation. * typeprint.c: Fix indentation. * ui-out.h: Fix indentation. * unittests/copy_bitwise-selftests.c: Fix indentation. * unittests/memory-map-selftests.c: Fix indentation. * utils.c: Fix indentation. * v850-tdep.c: Fix indentation. * valarith.c: Fix indentation. * valops.c: Fix indentation. * valprint.c: Fix indentation. * valprint.h: Fix indentation. * value.c: Fix indentation. * value.h: Fix indentation. * varobj.c: Fix indentation. * vax-tdep.c: Fix indentation. * windows-nat.c: Fix indentation. * windows-tdep.c: Fix indentation. * xcoffread.c: Fix indentation. * xml-syscall.c: Fix indentation. * xml-tdesc.c: Fix indentation. * xstormy16-tdep.c: Fix indentation. * xtensa-config.c: Fix indentation. * xtensa-linux-nat.c: Fix indentation. * xtensa-linux-tdep.c: Fix indentation. * xtensa-tdep.c: Fix indentation. gdbserver/ChangeLog: * ax.cc: Fix indentation. * dll.cc: Fix indentation. * inferiors.h: Fix indentation. * linux-low.cc: Fix indentation. * linux-nios2-low.cc: Fix indentation. * linux-ppc-ipa.cc: Fix indentation. * linux-ppc-low.cc: Fix indentation. * linux-x86-low.cc: Fix indentation. * linux-xtensa-low.cc: Fix indentation. * regcache.cc: Fix indentation. * server.cc: Fix indentation. * tracepoint.cc: Fix indentation. gdbsupport/ChangeLog: * common-exceptions.h: Fix indentation. * event-loop.cc: Fix indentation. * fileio.cc: Fix indentation. * filestuff.cc: Fix indentation. * gdb-dlfcn.cc: Fix indentation. * gdb_string_view.h: Fix indentation. * job-control.cc: Fix indentation. * signals.cc: Fix indentation. Change-Id: I4bad7ae6be0fbe14168b8ebafb98ffe14964a695 |
|||
17417fb0ec |
gdb, gdbsupport: add debug_prefixed_printf, remove boilerplate functions
The *_debug_print_1 functions are all very similar, the only difference being the subsystem name. Remove them all and make the logging macros use a new debug_prefixed_printf function directly. gdb/ChangeLog: * infrun.c (infrun_debug_printf_1): Remove. (displaced_debug_printf_1): Remove. (stop_all_threads): Use debug_prefixed_printf. * infrun.h (infrun_debug_printf_1): Remove. (infrun_debug_printf): Use debug_prefixed_printf. (displaced_debug_printf_1): Remove. (displaced_debug_printf): Use debug_prefixed_printf. * linux-nat.c (linux_nat_debug_printf_1): Remove. (linux_nat_debug_printf): Use debug_prefixed_printf. gdbsupport/ChangeLog: * common-debug.cc (debug_prefixed_printf): New. * common-debug.h (debug_prefixed_printf): New declaration. * event-loop.cc (event_loop_debug_printf_1): Remove. * event-loop.h (event_loop_debug_printf_1): Remove. (event_loop_debug_printf): Use debug_prefixed_printf. (event_loop_ui_debug_printf): Use debug_prefixed_printf. Change-Id: Ib323087c7257f0060121d302055c41eb64aa60c6 |
|||
136821d9f6 |
gdb: introduce displaced_debug_printf
Move all debug prints of the "displaced" category to use a new displaced_debug_printf macro, like what was done for infrun and others earlier. The debug output for one displaced step one amd64 looks like: [displaced] displaced_step_prepare_throw: stepping process 3367044 now [displaced] displaced_step_prepare_throw: saved 0x555555555042: 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 f0 50 [displaced] amd64_displaced_step_copy_insn: copy 0x555555555131->0x555555555042: b8 00 00 00 00 5d c3 0f 1f 84 00 00 00 00 00 f3 [displaced] displaced_step_prepare_throw: displaced pc to 0x555555555042 [displaced] resume_1: run 0x555555555042: b8 00 00 00 [displaced] displaced_step_restore: restored process 3367044 0x555555555042 [displaced] amd64_displaced_step_fixup: fixup (0x555555555131, 0x555555555042), insn = 0xb8 0x00 ... [displaced] amd64_displaced_step_fixup: relocated %rip from 0x555555555047 to 0x555555555136 On test case needed to be updated because it relied on the specific formatting of the message. gdb/ChangeLog: * infrun.h (displaced_debug_printf): New macro. Replace displaced debug prints throughout to use it. (displaced_debug_printf_1): New declaration. (displaced_step_dump_bytes): Return string, remove ui_file parameter, update all callers. * infrun.c (displaced_debug_printf_1): New function. (displaced_step_dump_bytes): Return string, remove ui_file parameter gdb/testsuite/ChangeLog: * gdb.arch/amd64-disp-step-avx.exp: Update displaced step debug expected output. Change-Id: Ie78837f56431f6f98378790ba1e6051337bf6533 |
|||
b78b3a297b |
gdb/infrun: disable pagination in fetch_inferior_event
Having pagination enabled when handling an inferior event gives the user an option to quit, which causes early exit in GDB's flow and may lead to half-baked state. For instance, here is a case where we quit in the middle of handling an inferior exit: $ gdb ./a.out Reading symbols from ./a.out... (gdb) set height 2 (gdb) run Starting program: ./a.out --Type <RET> for more, q to quit, c to continue without paging--q Quit Couldn't get registers: No such process. (gdb) set height unlimited Couldn't get registers: No such process. (gdb) info threads Id Target Id Frame * 1 process 27098 Couldn't get registers: No such process. Couldn't get registers: No such process. (gdb) Or suppose having a multi-threaded program like below: static void * fun (void *dummy) { int a = 1; /* break-here */ return NULL; } int main (void) { pthread_t thread; pthread_create (&thread, NULL, fun, NULL); pthread_join (thread, NULL); return 0; } If we define a breakpoint at line "break-here", we expect only Thread 2 to hit it. $ gdb ./a.out Reading symbols from ./a.out... (gdb) break 7 Breakpoint 1 at 0x1182: file mt.c, line 7. (gdb) set height 2 (gdb) run Starting program: ./a.out [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff77c4700 (LWP 23048)] --Type <RET> for more, q to quit, c to continue without paging--q Quit (gdb) set height unlimited (gdb) info thread Id Target Id Frame * 1 Thread 0x7ffff7fe3740 (LWP 23044) "a.out" 0x00007ffff7bbed2d in ... 2 Thread 0x7ffff77c4700 (LWP 23048) "a.out" fun (dummy=0x0) at mt.c:7 (gdb) The prompt for continuation was triggered because Thread 2 hit the breakpoint. (If we had hit 'c', we were going to see that stop event, but we didn't.) The context did not switch to Thread 2. GDB also did not execute several other things it would normally do in infrun.c:normal_stop after outputting "[Switching to Thread ...]" (but it seems harmless in this case). If we 'continue' at this state, both threads run until termination, and we don't see the breakpoint hit event ever. Here is another related and more complicated scenario that leads to a GDB crash. Create two inferiors, one sitting on top of a native target, and the other on a remote target, so that we have a multi-target setting, like so: (gdb) i inferiors Num Description Connection Executable 1 process 13786 1 (native) a.out * 2 process 13806 2 (remote ...) target:a.out Next, resume both inferiors to run until termination: (gdb) set schedule-multiple on (gdb) set height 2 (gdb) continue Continuing. --Type <RET> for more, q to quit, c to continue without paging--[Inferior 2 (process 13806) exited normally] terminate called after throwing an instance of 'gdb_exception_error' Aborted Here, GDB first received a termination event from Inferior 1. GDB attempted to print this event, triggering a "prompt for continue", and GDB started polling for events, hoping to get an input from the user. However, the exit event from Inferior 2 was received instead. So, GDB started processing an exit event while being in the middle of processing another exit event. It was not ready for this situation and eventually crashed. To address these cases, temporarily disable pagination in fetch_inferior_event. This doesn't affect commands like 'info threads', 'backtrace', or 'thread apply'. Regression-tested on X86_64 Linux. gdb/ChangeLog: 2020-10-30 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (fetch_inferior_event): Temporarily disable pagination. gdb/testsuite/ChangeLog: 2020-10-30 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.base/paginate-after-ctrl-c-running.exp: Update with no pagination behavior. * gdb.base/paginate-bg-execution.exp: Ditto. * gdb.base/paginate-inferior-exit.exp: Ditto. * gdb.base/double-prompt-target-event-error.c: Remove. * gdb.base/double-prompt-target-event-error.exp: Remove. |
|||
79952e6963 |
Make scoped_restore_current_thread's cdtors exception free (RFC)
If the remote target closes while we're reading registers/memory for restoring the selected frame in scoped_restore_current_thread's dtor, the corresponding TARGET_CLOSE_ERROR error is swallowed by the scoped_restore_current_thread's dtor, because letting exceptions escape from a dtor is bad. It isn't great to lose that errors like that, though. I've been thinking about how to avoid it, and I came up with this patch. The idea here is to make scoped_restore_current_thread's dtor do as little as possible, to avoid any work that might throw in the first place. And to do that, instead of having the dtor call restore_selected_frame, which re-finds the previously selected frame, just record the frame_id/level of the desired selected frame, and have get_selected_frame find the frame the next time it is called. In effect, this implements most of Cagney's suggestion, here: /* On demand, create the selected frame and then return it. If the selected frame can not be created, this function prints then throws an error. When MESSAGE is non-NULL, use it for the error message, otherwize use a generic error message. */ /* FIXME: cagney/2002-11-28: At present, when there is no selected frame, this function always returns the current (inner most) frame. It should instead, when a thread has previously had its frame selected (but not resumed) and the frame cache invalidated, find and then return that thread's previously selected frame. */ extern struct frame_info *get_selected_frame (const char *message); The only thing missing to fully implement that would be to make reinit_frame_cache just clear selected_frame instead of calling select_frame(NULL), and the call select_frame(NULL) explicitly in the places where we really wanted reinit_frame_cache to go back to the current frame too. That can done separately, though, I'm not proposing to do that in this patch. Note that this patch renames restore_selected_frame to lookup_selected_frame, and adds a new restore_selected_frame function that doesn't throw, to be paired with the also-new save_selected_frame function. There's a restore_selected_frame function in infrun.c that I think can be replaced by the new one in frame.c. Also done in this patch is make the get_selected_frame's parameter be optional, so that we don't have to pass down nullptr explicitly all over the place. lookup_selected_frame should really move from thread.c to frame.c, but I didn't do that here, just to avoid churn in the patch while it collects comments. I did make it extern and declared it in frame.h already, preparing for the move. I will do the move as a follow up patch if people agree with this approach. Incidentally, this patch alone would fix the crashes fixed by the previous patches in the series, because with this, scoped_restore_current_thread's constructor doesn't throw either. gdb/ChangeLog: * blockframe.c (block_innermost_frame): Use get_selected_frame. * frame.c (scoped_restore_selected_frame::scoped_restore_selected_frame): Use save_selected_frame. Save language as well. (scoped_restore_selected_frame::~scoped_restore_selected_frame): Use restore_selected_frame, and restore language as well. (selected_frame_id, selected_frame_level): New. (selected_frame): Update comments. (save_selected_frame, restore_selected_frame): New. (get_selected_frame): Use lookup_selected_frame. (get_selected_frame_if_set): Delete. (select_frame): Record selected_frame_level and selected_frame_id. * frame.h (scoped_restore_selected_frame) <m_level, m_lang>: New fields. (get_selected_frame): Make 'message' parameter optional. (get_selected_frame_if_set): Delete declaration. (select_frame): Update comments. (save_selected_frame, restore_selected_frame) (lookup_selected_frame): Declare. * gdbthread.h (scoped_restore_current_thread) <m_lang>: New field. * infrun.c (struct infcall_control_state) <selected_frame_level>: New field. (save_infcall_control_state): Use save_selected_frame. (restore_selected_frame): Delete. (restore_infcall_control_state): Use restore_selected_frame. * stack.c (select_frame_command_core, frame_command_core): Use get_selected_frame. * thread.c (restore_selected_frame): Rename to ... (lookup_selected_frame): ... this and make extern. Select the current frame if the frame level is -1. (scoped_restore_current_thread::restore): Also restore the language. (scoped_restore_current_thread::~scoped_restore_current_thread): Don't try/catch. (scoped_restore_current_thread::scoped_restore_current_thread): Save the language as well. Use save_selected_frame. Change-Id: I73fd1cfc40d8513c28e5596383b7ecd8bcfe700f |
|||
40a5376690 |
gdb: remove parameter of gdbarch_displaced_step_hw_singlestep
I noticed that the closure parameter of gdbarch_displaced_step_hw_singlestep is never used by any implementation of the method, so this patch removes it. gdb/ChangeLog: * gdbarch.sh (displaced_step_hw_singlestep): Remove closure parameter. * aarch64-tdep.c (aarch64_displaced_step_hw_singlestep): Likewise. * aarch64-tdep.h (aarch64_displaced_step_hw_singlestep): Likewise. * arch-utils.c (default_displaced_step_hw_singlestep): Likewise. * arch-utils.h (default_displaced_step_hw_singlestep): Likewise. * rs6000-tdep.c (ppc_displaced_step_hw_singlestep): Likewise. * s390-tdep.c (s390_displaced_step_hw_singlestep): Likewise. * gdbarch.c: Re-generate. * gdbarch.h: Re-generate. * infrun.c (resume_1): Adjust. Change-Id: I7354f0b22afc2692ebff0cd700a462db8f389fc1 |
|||
324956617c |
gdb: make jit.c use the inferior_created inferior parameter
Use the inferior parameter now available in jit_inferior_created_hook. It is passed down to jit_inferior_init, which uses it as much as possible instead of the current inferior or current program space. gdb/ChangeLog: * jit.c (jit_reader_load_command): Pass current inferior. (jit_inferior_init): Change parameter type to inferior, use it. (jit_inferior_created): Remove. (jit_inferior_created_hook): Pass inferior parameter down. (_initialize_jit): Use jit_inferior_created_hook instead of jit_inferior_created. * jit.h (jit_inferior_created_hook): Add inferior parameter. * infrun.c (follow_exec): Pass inferior to jit_inferior_created_hook. Change-Id: If3a2114a933370dd313d5abd623136d273cdb8fa |
|||
a46d184353 |
gdb: fix two comments in infrun
These comments are stale, they refer to non-existent parameters. Fix that. gdb/ChangeLog: * infrun.c (displaced_step_in_progress_thread): Fix comment. (displaced_step_in_progress): Fix comment. Change-Id: I7a39f1338fbfbf73153b49cbca0345d495d12762 |
|||
c4464adef2 |
gdb: change some int to bool in infrun.c
Change these int-used-as-a-bool to bool. I searched for "static int" in that file and changed what I found. gdb/ChangeLog: * infrun.c (currently_stepping): Change int to bool (maybe_software_singlestep): Likewise. (show_stop_on_solib_events): Likewise. (stepping_past_nonsteppable_watchpoint): Likewise. (displaced_step_in_progress_any_inferior): Likewise. (displaced_step_in_progress_thread): Likewise. (keep_going_stepped_thread): Likewise. (thread_still_needs_step_over): Likewise. (start_step_over): Likewise. (do_target_resume): Likewise. (resume_1): Likewise. (clear_proceed_status): Likewise. (thread_still_needs_step_over_bp): Likewise. (proceed): Likewise. (switch_back_to_stepped_thread): Likewise. (adjust_pc_after_break): Likewise. (stepped_in_from): Likewise. (handle_stop_requested): Likewise. (handle_syscall_event): Likewise. (handle_no_resumed): Likewise. (handle_inferior_event): Likewise. (finish_step_over): Likewise. (handle_signal_stop): Likewise. (process_event_stop_test): Likewise. Change-Id: I897527c4a3da5e647f9d97f7d4477649985b8b77 |
|||
2eb20436fa |
gdb: fix comment of get_displaced_stepping_state
The comment mentions PID instead of INF, fix that. gdb/ChangeLog: * infrun.c (get_displaced_stepping_state): Fix comment. Change-Id: Id9554807c50792db1fcdb7c14590397d1fa6f8f7 |
|||
d3a071228e |
gdb: don't pass TARGET_WNOHANG to targets that can't async (PR 26642)
Debugging with "maintenance set target-async off" on Linux has been broken since 5b6d1e4fa4f ("Multi-target support"). The issue is easy to reproduce: $ ./gdb -q --data-directory=data-directory -nx ./test Reading symbols from ./test... (gdb) maintenance set target-async off (gdb) start Temporary breakpoint 1 at 0x1151: file test.c, line 5. Starting program: /home/simark/build/binutils-gdb/gdb/test ... and it hangs there. The difference between pre-5b6d1e4fa4f and 5b6d1e4fa4f is that fetch_inferior_event now calls target_wait with TARGET_WNOHANG for non-async-capable targets, whereas it didn't before. For non-async-capable targets, this is how it's expected to work when resuming execution: 1. we call resume 2. the infrun async handler is marked in prepare_to_wait, to immediately wake up the event loop when we get back to it 3. fetch_inferior_event calls the target's wait method without TARGET_WNOHANG, effectively blocking until the target has something to report However, since we call the target's wait method with TARGET_WNOHANG, this happens: 1. we call resume 2. the infrun async handler is marked in prepare_to_wait, to immediately wake up the event loop when we get back to it 3. fetch_inferior_event calls the target's wait method with TARGET_WNOHANG, the target has nothing to report yet 4. we go back to blocking on the event loop 5. SIGCHLD finally arrives, but the event loop is not woken up, because we are not in async mode. Normally, we should have been stuck in waitpid the SIGCHLD would have unblocked us. We end up in this situation because these two necessary conditions are met: 1. GDB uses the TARGET_WNOHANG option with a target that can't do async. I don't think this makes sense. I mean, it's technically possible, the doc for TARGET_WNOHANG is: /* Return immediately if there's no event already queued. If this options is not requested, target_wait blocks waiting for an event. */ TARGET_WNOHANG = 1, ... which isn't in itself necessarily incompatible with synchronous targets. It could be possible for a target to support non-blocking polls, while not having a way to asynchronously wake up the event loop, which is also necessary to support async. But as of today, we don't expect GDB and sync targets to work this way. 2. The linux-nat target, even in the mode where it emulates a synchronous target (with "maintenance set target-async off") respects TARGET_WNOHANG. Other non-async targets, such as windows_nat_target, simply don't check / support TARGET_WNOHANG, so their wait method is always blocking. Fix the first issue by avoiding using TARGET_WNOHANG on non-async targets, in do_target_wait_1. Add an assert in target_wait to verify it doesn't happen. The new test gdb.base/maint-target-async-off.exp is a simple test that just tries running to main and then to the end of the program, with "maintenance set target-async off". gdb/ChangeLog: PR gdb/26642 * infrun.c (do_target_wait_1): Clear TARGET_WNOHANG if the target can't do async. * target.c (target_wait): Assert that we don't pass TARGET_WNOHANG to a target that can't async. gdb/testsuite/ChangeLog: PR gdb/26642 * gdb.base/maint-target-async-off.c: New test. * gdb.base/maint-target-async-off.exp: New test. Change-Id: I69ad3a14598863d21338a8c4e78700a58ce7ad86 |
|||
ba98841943 |
gdb: move debug_prefixed_vprintf here
The following patch needs to output debug prints from gdbsupport code. Move debug_prefixed_vprintf so that it is possible to use it from gdbsupport. gdb/ChangeLog: * debug.c (debug_prefixed_vprintf): Move to gdbsupport. * debug.h: Remove. * infrun.c: Include gdbsupport/common-debug.h. * linux-nat.c: Likewise. gdbsupport/ChangeLog: * common-debug.cc (debug_prefixed_vprintf): Move here. * common-debug.h (debug_prefixed_vprintf): Move here. Change-Id: I5170065fc10a7a49c0f1bba67c691decb2cf3bcb |
|||
db20ebdfae |
gdb: give names to async event/signal handlers
Assign names to async event/signal handlers. They will be used in debug messages when file handlers are invoked. Unlike in the previous patch, the names are not copied in the structure, since we don't need to (all names are string literals for the moment). gdb/ChangeLog: * async-event.h (create_async_signal_handler): Add name parameter. (create_async_event_handler): Likewise. * async-event.c (struct async_signal_handler) <name>: New field. (struct async_event_handler) <name>: New field. (create_async_signal_handler): Assign name. (create_async_event_handler): Assign name. * event-top.c (async_init_signals): Pass name when creating handler. * infrun.c (_initialize_infrun): Likewise. * record-btrace.c (record_btrace_push_target): Likewise. * record-full.c (record_full_open): Likewise. * remote-notif.c (remote_notif_state_allocate): Likewise. * remote.c (remote_target::open_1): Likewise. * tui/tui-win.c (tui_initialize_win): Likewise. Change-Id: Icd9d9f775542ae5fc2cd148c12f481e7885936d5 |
|||
a7aba2668a |
gdb: remove arguments from inferior_created observable
I noticed that non of the listeners of the inferior_created observable used either of the arguments. Remove them. This in turn allows removing the target parameter of post_create_inferior. Tested only by rebuilding. gdb/ChangeLog: * observable.h <inferior_created>: Remove parameters. Update all listeners. * inferior.h (post_create_inferior): Remove target parameter. Update all callers. Change-Id: I8944cefdc4447ed5347dc927b75abf1e7a0e27e6 |
|||
9aed480c3a |
Turn target_have_steppable_watchpoint into function
This changes the object-like macro target_have_steppable_watchpoint into an inline function. gdb/ChangeLog 2020-09-28 Tom Tromey <tom@tromey.com> * infrun.c (displaced_step_fixup, thread_still_needs_step_over) (handle_signal_stop): Update. * procfs.c (procfs_target::insert_watchpoint): Update. * target.h (target_have_steppable_watchpoint): Now a function. |
|||
8a3ecb79b0 |
Turn target_can_lock_scheduler into a function
This changes the object-like macro target_can_lock_scheduler into an inline function. gdb/ChangeLog 2020-09-28 Tom Tromey <tom@tromey.com> * infrun.c (set_schedlock_func): Update. * target.h (target_can_lock_scheduler): Now a function. |
|||
55f6301ac0 |
Remove target_has_execution macro
This removes the object-like macro target_has_execution, replacing it with a function call. target_has_execution_current is also now handled by this function. gdb/ChangeLog 2020-09-28 Tom Tromey <tom@tromey.com> * inferior.h (class inferior) <has_execution>: Update. * windows-tdep.c (windows_solib_create_inferior_hook): Update. * valops.c (find_function_in_inferior) (value_allocate_space_in_inferior): Update. * top.c (kill_or_detach): Update. * target.c (target_preopen, set_target_permissions): Update. (target_has_execution_current): Remove. * sparc64-tdep.c (adi_examine_command, adi_assign_command): Update. * solib.c (update_solib_list, reload_shared_libraries): Update. * solib-svr4.c (svr4_solib_create_inferior_hook): Update. * solib-dsbt.c (enable_break): Update. * score-tdep.c (score7_fetch_inst): Update. * rs6000-nat.c (rs6000_nat_target::xfer_shared_libraries): Update. * remote.c (remote_target::start_remote) (remote_target::remote_check_symbols, remote_target::open_1) (remote_target::remote_detach_1, remote_target::verify_memory) (remote_target::xfer_partial, remote_target::read_description) (remote_target::get_min_fast_tracepoint_insn_len): Update. * record-full.c (record_full_open_1): Update. * record-btrace.c (record_btrace_target_open): Update. * objc-lang.c (lookup_objc_class, lookup_child_selector) (value_nsstring): Update. * linux-thread-db.c (add_thread_db_info) (thread_db_find_new_threads_silently, check_thread_db_callback) (try_thread_db_load_1, record_thread): Update. * linux-tdep.c (linux_info_proc, linux_vsyscall_range_raw): Update. * linux-fork.c (checkpoint_command): Update. * infrun.c (set_non_stop, set_observer_mode) (check_multi_target_resumption, for_each_just_stopped_thread) (maybe_remove_breakpoints, normal_stop) (class infcall_suspend_state): Update. * infcmd.c (ERROR_NO_INFERIOR, kill_if_already_running) (info_program_command, attach_command): Update. * infcall.c (call_function_by_hand_dummy): Update. * inf-loop.c (inferior_event_handler): Update. * gcore.c (gcore_command, derive_heap_segment): Update. * exec.c (exec_file_command): Update. * eval.c (evaluate_subexp): Update. * compile/compile.c (compile_to_object): Update. * cli/cli-dump.c (restore_command): Update. * breakpoint.c (update_watchpoint) (update_inserted_breakpoint_locations) (insert_breakpoint_locations, get_bpstat_thread): Update. * target.h (target_has_execution): Remove macro. (target_has_execution_current): Don't declare. (target_has_execution): Rename from target_has_execution_1. Add argument default. |
|||
05374cfd90 |
Turn target_can_execute_reverse into function
This changes target_can_execute_reverse from an object-like macro to an inline function. gdb/ChangeLog 2020-09-28 Tom Tromey <tom@tromey.com> * mi/mi-main.c (exec_reverse_continue) (mi_cmd_list_target_features): Update. * infrun.c (set_exec_direction_func): Update. * target.c (default_execution_direction): Update. * reverse.c (exec_reverse_once): Update. * target.h (target_can_execute_reverse): Now a function. |
|||
841de12014 |
Remove target_has_stack macro
This removes the target_has_stack object-like macro, replacing it with the underlying function. gdb/ChangeLog 2020-09-28 Tom Tromey <tom@tromey.com> * windows-tdep.c (tlb_make_value): Update. * tui/tui-regs.c (tui_data_window::show_registers): Update. * thread.c (scoped_restore_current_thread::restore) (scoped_restore_current_thread::scoped_restore_current_thread) (thread_command): Update. * stack.c (backtrace_command_1, frame_apply_level_command) (frame_apply_all_command, frame_apply_command): Update. * infrun.c (siginfo_make_value, restore_infcall_control_state): Update. * gcore.c (derive_stack_segment): Update. * frame.c (get_current_frame, has_stack_frames): Update. * auxv.c (info_auxv_command): Update. * ada-tasks.c (ada_build_task_list): Update. * target.c (target_has_stack): Rename from target_has_stack_1. * target.h (target_has_stack): Remove macro. (target_has_stack): Rename from target_has_stack_1. |
|||
b60cea74de |
Make target_wait options use enum flags
This changes TARGET_WNOHANG to be a member of an enum, rather than a define, and also adds a DEF_ENUM_FLAGS_TYPE for this type. Then, it changes target_wait and the various target wait methods to use this type rather than "int". This didn't catch any bugs, but it seems like a decent cleanup nevertheless. I did not change deprecated_target_wait_hook, since that's only used out-of-tree (by Insight), and there didn't seem to be a need. I can't build some of these targets, so I modified them on a best-effort basis. I don't think this patch should go in before the release branch is made. gdb/ChangeLog 2020-09-18 Tom Tromey <tromey@adacore.com> * windows-nat.c (struct windows_nat_target) <wait>: Update. (windows_nat_target::wait): Update. * target/wait.h (enum target_wait_flag): New. Use DEF_ENUM_FLAGS_TYPE. * target/target.h (target_wait): Change type of options. * target.h (target_options_to_string, default_target_wait): Update. (struct target_ops) <wait>: Change type of options. * target.c (target_wait, default_target_wait, do_option): Change type of "options". (target_options_to_string): Likewise. * target-delegates.c: Rebuild. * target-debug.h (target_debug_print_target_wait_flags): Rename from target_debug_print_options. * sol-thread.c (class sol_thread_target) <wait>: Update. (sol_thread_target::wait): Update. * rs6000-nat.c (class rs6000_nat_target) <wait>: Update. (rs6000_nat_target::wait): Update. * remote.c (class remote_target) <wait, wait_ns, wait_as>: Update. (remote_target::wait_ns, remote_target::wait_as): Change type of "options". (remote_target::wait): Update. * remote-sim.c (struct gdbsim_target) <wait>: Update. (gdbsim_target::wait): Update. * record-full.c (class record_full_base_target) <wait>: Update. (record_full_wait_1): Change type of "options". (record_full_base_target::wait): Update. * record-btrace.c (class record_btrace_target) <wait>: Update. (record_btrace_target::wait): Update. * ravenscar-thread.c (struct ravenscar_thread_target) <wait>: Update. (ravenscar_thread_target::wait): Update. * procfs.c (class procfs_target) <wait>: Update. (procfs_target::wait): Update. * obsd-nat.h (class obsd_nat_target) <wait>: Update. * obsd-nat.c (obsd_nat_target::wait): Update. * nto-procfs.c (struct nto_procfs_target) <wait>: Update. (nto_procfs_target::wait): Update. * nbsd-nat.h (struct nbsd_nat_target) <wait>: Update. * nbsd-nat.c (nbsd_wait): Change type of "options". (nbsd_nat_target::wait): Update. * linux-thread-db.c (class thread_db_target) <wait>: Update. (thread_db_target::wait): Update. * linux-nat.h (class linux_nat_target) <wait>: Update. * linux-nat.c (linux_nat_target::wait): Update. (linux_nat_wait_1): Update. * infrun.c (do_target_wait_1, do_target_wait): Change type of "options". * inf-ptrace.h (struct inf_ptrace_target) <wait>: Update. * inf-ptrace.c (inf_ptrace_target::wait): Update. * go32-nat.c (struct go32_nat_target) <wait>: Update. (go32_nat_target::wait): Update. * gnu-nat.h (struct gnu_nat_target) <wait>: Update. * gnu-nat.c (gnu_nat_target::wait): Update. * fbsd-nat.h (class fbsd_nat_target) <wait>: Update. * fbsd-nat.c (fbsd_nat_target::wait): Update. * darwin-nat.h (class darwin_nat_target) <wait>: Update. * darwin-nat.c (darwin_nat_target::wait): Update. * bsd-uthread.c (struct bsd_uthread_target) <wait>: Update. (bsd_uthread_target::wait): Update. * aix-thread.c (class aix_thread_target) <wait>: Update. (aix_thread_target::wait): Update. gdbserver/ChangeLog 2020-09-18 Tom Tromey <tromey@adacore.com> * netbsd-low.h (class netbsd_process_target) <wait>: Update. * netbsd-low.cc (netbsd_waitpid, netbsd_wait) (netbsd_process_target::wait): Change type of target_options. * win32-low.h (class win32_process_target) <wait>: Update. * win32-low.cc (win32_process_target::wait): Update. * target.h (class process_stratum_target) <wait>: Update. (mywait): Update. * target.cc (mywait, target_wait): Change type of "options". * linux-low.h (class linux_process_target) <wait, wait_1>: Update. * linux-low.cc (linux_process_target::wait) (linux_process_target::wait_1): Update. |
|||
fe83066292 |
Match demangled name in "skip"
PR gdb/26598 notes that, before commit bcfe6157ca28 ("Use the linkage name if it exists"), the "skip" command would match the demangled name of a symbol, but now only matches the linkage name. This patch fixes this regression. I looked at all calls to function_name_is_marked_for_skip, and only one used the linkage name. 2020-09-16 Tom Tromey <tromey@adacore.com> PR gdb/26598: * infrun.c (fill_in_stop_func): Use find_pc_partial_function_sym. gdb/testsuite/ChangeLog 2020-09-16 Tom Tromey <tromey@adacore.com> PR gdb/26598: * gdb.base/skipcxx.exp: New file. * gdb.base/skipcxx.cc: New file. |
|||
8087c3fa8b |
Fix GDB build in infrun.c when configured with unit tests disabled
I noticed this while testing the GDB in the context of the upcoming GDB 10 release branching, because part of the process involves setting development to False, which in turn changes the default for including unittest to false as well. As a result, without this patch, we get compilation errors in infrun.c such as: infrun.c:9219:5: error: `scoped_mock_context' was not declared in this scope This patch fixes it by bracketing the unitttest in namespace selftest with an #if GDB_SELF_TEST. gdb/ChangeLog: * infrun.c (namespace selftests): Only define #if GDB_SELF_TEST. Tested on x86_64-linux, with and without self-tests. |
|||
7f08fd5186 |
gdb/infrun: use switch_to_target_no_thread to switch the target
Use the available `switch_to_target_no_thread` function to switch the target. This is a refactoring. gdb/ChangeLog: 2020-09-07 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (fetch_inferior_event): Use `switch_to_target_no_thread` to switch the target. |
|||
c426fddb87 |
gdb: add debug_prefixed_vprintf
To help ensure that all debug statements have the same format, introduce the debug_prefixed_vprintf helper. Implement linux_nat_debug_printf_1 and infrun_debug_printf_1 with it. I would eventually like to style the module and function name with some color, to help them stick out, but I don't really know how to do that yet, it can always be done later. gdb/ChangeLog: * debug.h: New file. * debug.c (debug_prefixed_vprintf): New function. * infrun.c (infrun_debug_printf_1): Use debug_prefixed_vprintf. * linux-nat.c (linux_nat_debug_printf_1): Likewise. Change-Id: Iccc290a2dc6b5fffcbe1c2866ed8d804ad380764 |
|||
1eb8556f5a |
gdb: add infrun_debug_printf macro
Introduce this macro to print debug statements in the infrun.c file, same idea as what was done in 9327494e0eeb ("gdb: add linux_nat_debug_printf macro"). Although in this case, there are places outside infrun.c that print debug statements if debug_infrun is set. So the macro has to be declared in the header file, so that it can be used in these other files. Note one special case. In stop_all_threads, I've used an explicit if (debug_infrun) infrun_debug_printf_1 ("stop_all_threads", "done"); for the message in the SCOPE_EXIT. Otherwise, the message appears like this: [infrun] operator(): done Until we find a better solution for extracting a meaningful function name for lambda functions, I think it's fine to handle these special cases manually, they are quite rare. Some tests need to be updated, because they rely on some infrun debug statements. gdb/ChangeLog: * infrun.h (infrun_debug_printf_1): New function declaration. (infrun_debug_printf): New macro. * infrun.c (infrun_debug_printf_1): Use infrun_debug_printf throughout. (infrun_debug_printf): New function. * breakpoint.c (should_be_inserted): Use infrun_debug_printf. (handle_jit_event): Likewise. gdb/testsuite/ChangeLog: * gdb.base/gdb-sigterm.exp (do_test): Update expected regexp. * gdb.threads/signal-while-stepping-over-bp-other-thread.exp: Likewise. * gdb.threads/stepi-random-signal.exp: Likewise. Change-Id: I66433c8a9caa64c8525ab57c593022b9d1956d5c |
|||
33bf4c5c10 |
gdb: fix typo "breapoint" -> "breakpoint"
gdb/ChangeLog: 2020-08-20 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (process_event_stop_test): Fix typo "breapoint". gdb/testsuite/ChangeLog: 2020-08-20 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.base/print-file-var.exp: Fix typo "breapoint". * gdb.trace/strace.exp: Ditto. |
|||
b161a60d1f |
gdb: pass target to thread_ptid_changed observable
I noticed what I think is a potential bug. I did not observe it nor was I able to reproduce it using actual debugging. It's quite unlikely, because it involves multi-target and ptid clashes. I added selftests that demonstrate it though. The thread_ptid_changed observer says that thread with OLD_PTID now has NEW_PTID. Now, if for some reason we happen to have two targets defining a thread with OLD_PTID, the observers don't know which thread this is about. regcache::regcache_thread_ptid_changed changes all regcaches with OLD_PTID. If there is a regcache for a thread with ptid OLD_PTID, but that belongs to a different target, this regcache will be erroneously changed. Similarly, infrun_thread_ptid_changed updates inferior_ptid if inferior_ptid matches OLD_PTID. But if inferior_ptid currently refers not to the thread is being changed, but to a thread with the same ptid belonging to a different target, then inferior_ptid will erroneously be changed. This patch adds a `process_stratum_target *` parameter to the `thread_ptid_changed` observable and makes the two observers use it. Tests for both are added, which would fail if the corresponding fix wasn't done. gdb/ChangeLog: * observable.h (thread_ptid_changed): Add parameter `process_stratum_target *`. * infrun.c (infrun_thread_ptid_changed): Add parameter `process_stratum_target *` and use it. (selftests): New namespace. (infrun_thread_ptid_changed): New function. (_initialize_infrun): Register selftest. * regcache.c (regcache_thread_ptid_changed): Add parameter `process_stratum_target *` and use it. (regcache_thread_ptid_changed): New function. (_initialize_regcache): Register selftest. * thread.c (thread_change_ptid): Pass target to thread_ptid_changed observable. Change-Id: I0599e61224b6d154a7b55088a894cb88298c3c71 |
|||
4cec0c6689 |
Retire the now-unused gdbarch handle_segmentation_fault hook.
* gdbarch.c: Regenerate. * gdbarch.h: Regenerate. * gdbarch.sh (handle_segmentation_fault): Remove method. * infrun.c (handle_segmentation_fault): Remove. (print_signal_received_reason): Remove call to handle_segmentation_fault. |
|||
272bb05cc5 |
Add a new gdbarch hook to report additional signal information.
This is a more general version of the existing handle_segmentation_fault hook that is able to report information for an arbitrary signal, not just SIGSEGV. gdb/ChangeLog: * gdbarch.c: Regenerate. * gdbarch.h: Regenerate. * gdbarch.sh (report_signal_info): New method. * infrun.c (print_signal_received_reason): Invoke gdbarch report_signal_info hook if present. |
|||
b3e3a4c114 |
Fix GDB busy loop when interrupting non-stop program (PR 26199)
When interrupting a program in non-stop, the program gets interrupted correctly, but GDB busy loops (the event loop is always woken up). Here is how to reproduce it: 1. Start GDB: ./gdb -nx --data-directory=data-directory -ex "set non-stop 1" --args /bin/sleep 60 2. Run the program with "run" 3. Interrupt with ^C. 4. Look into htop, see GDB taking 100% CPU Debugging `handle_file_event`, we see that the event source that wakes up the event loop is the linux-nat one: (top-gdb) p file_ptr.proc $5 = (handler_func *) 0xb9cccd <handle_target_event(int, gdb_client_data)> ^^^^^^^^^^^^^^^^^^^ | \-- the linux-nat callback Debugging fetch_inferior_event and do_target_wait, we see that we don't actually call `wait` on the linux-nat target, because inferior_matches returns false: auto inferior_matches = [&wait_ptid] (inferior *inf) { return (inf->process_target () != NULL && (threads_are_executing (inf->process_target ()) || threads_are_resumed_pending_p (inf)) && ptid_t (inf->pid).matches (wait_ptid)); }; because `threads_are_executing` is false. What happens is: 1. User types ctrl-c, that writes in the linux-nat pipe, waking up the event source. 2. linux-nat's wait gets called, the SIGINT event is returned, but before returning, it marks the pipe again, in order for wait to get called again: /* If we requested any event, and something came out, assume there may be more. If we requested a specific lwp or process, also assume there may be more. */ if (target_is_async_p () && ((ourstatus->kind != TARGET_WAITKIND_IGNORE && ourstatus->kind != TARGET_WAITKIND_NO_RESUMED) || ptid != minus_one_ptid)) async_file_mark (); 3. The SIGINT event is handled, the program is stopped, the stop notification is printed. 4. The event loop is woken up again because of the `async_file_mark` of step 2. 5. Because `inferior_matches` returns false, we never call linux-nat's wait, so the pipe stays readable. 6. Goto 4. Pedro says: This commit fixes it by letting do_target_wait call target_wait even if threads_are_executing is false. This will normally result in the target returning TARGET_WAITKIND_NO_RESUMED, and _not_ marking its event source again. This results in infrun only calling into the target only once (i.e., breaking the busy loop). Note that the busy loop bug didn't trigger in all-stop mode because all-stop handles this by unregistering the target from the event loop as soon as it was all stopped -- see inf-loop.c:inferior_event_handler's INF_EXEC_COMPLETE handling. If we remove that non-stop check from inferior_event_handler, and replace the target_has_execution check for threads_are_executing instead, it also fixes the issue for non-stop. I considered that as the final solution, but decided that the solution proposed here instead is just simpler and more future-proof design. With the TARGET_WAITKIND_NO_RESUMED handling fixes done in the previous patches, I think it should be possible to always keep the target registered in the event loop, meaning we could eliminate the target_async(0) call from inferior_event_handler as well as most of the target_async(1) calls in the target backends. That would allow in the future e.g., the remote target reporting asynchronous notifications even if all threads are stopped. I haven't attempted that, though. gdb/ChangeLog: yyyy-mm-dd Simon Marchi <simon.marchi@polymtl.ca> Pedro Alves <pedro@palves.net> PR gdb/26199 * infrun.c (threads_are_resumed_pending_p): Delete. (do_target_wait): Remove threads_are_executing and threads_are_resumed_pending_p checks from the inferior_matches lambda. Update comments. |
|||
d6cc5d980a |
Make handle_no_resumed transfer terminal
Let's consider the same use case as in the previous commit: Say you have two inferiors 1 and 2, each connected to a different target, A and B. Now say you set inferior 2 running, with "continue &". Now you select a thread of inferior 1, say thread 1.2, and continue in the foreground. All other threads of inferior 1 are left stopped. Thread 1.2 exits, and thus target A has no other resumed thread, so it reports TARGET_WAITKIND_NO_RESUMED. At this point, because the threads of inferior 2 are still executing the TARGET_WAITKIND_NO_RESUMED event is ignored. Now, the user types Ctrl-C. Because GDB had previously put inferior 1 in the foreground, the kernel sends the SIGINT to that inferior. However, no thread in that inferior is executing right now, so ptrace never intercepts the SIGINT -- it is never dequeued by any thread. The result is that GDB's CLI is stuck. There's no way to get back the prompt (unless inferior 2 happens to report some event). The fix in this commit is to make handle_no_resumed give the terminal to some other inferior that still has threads executing so that a subsequent Ctrl-C reaches that target first (and then GDB intercepts the SIGINT). This is a bit hacky, but seems like the best we can do with the current design. I think that putting all native inferiors in their own session would help fixing this in a clean way, since with that a Ctrl-C on GDB's terminal will _always_ reach GDB first, and then GDB can decide how to pause the inferior. But that's a much larger change. The testcase added by the following patch needs this fix. gdb/ChangeLog: PR gdb/26199 * infrun.c (handle_no_resumed): Transfer terminal to inferior with executing threads. |
|||
7d3badc6a8 |
Fix handle_no_resumed w/ multiple targets
handle_no_resumed is currently not considering multiple targets. Say you have two inferiors 1 and 2, each connected to a different target, A and B. Now say you set inferior 2 running, with "continue &". Now you select a thread of inferior 1, say thread 1.2, and continue in the foreground. All other threads of inferior 1 are left stopped. Thread 1.2 exits, and thus target A has no other resumed thread, so it reports TARGET_WAITKIND_NO_RESUMED. At this point, if both inferiors were running in the same target, handle_no_resumed would realize that threads of inferior 2 are still executing, so the TARGET_WAITKIND_NO_RESUMED event should be ignored. But because handle_no_resumed only walks the threads of the current target, it misses noticing that threads of inferior 2 are still executing. The fix is just to walk over all threads of all targets. A testcase covering the use case above will be added in a following patch. It can't be added yet because it depends on yet another fix to handle_no_resumed not included here. gdb/ChangeLog: PR gdb/26199 * infrun.c (handle_no_resumed): Handle multiple targets. |
|||
42bd97a6b1 |
Avoid constant stream of TARGET_WAITKIND_NO_RESUMED
If we hit the synchronous execution command case described by handle_no_resumed, and handle_no_resumed determines that the event should be ignored, because it found a thread that is executing, we end up in prepare_to_wait. There, if the current target is not registered in the event loop right now, we call mark_infrun_async_event_handler. With that event handler marked, the event loop calls again into fetch_inferior_event, which calls target_wait, which returns TARGET_WAITKIND_NO_RESUMED, and we end up in handle_no_resumed, again ignoring the event and marking infrun_async_event_handler. The result is that GDB is now always keeping the CPU 100% busy in this loop, even though it continues to be able to react to input and to real target events, because we still go through the event-loop. The problem is that marking of the infrun_async_event_handler in prepare_to_wait. That is there to handle targets that don't support asynchronous execution. So the correct predicate is whether async execution is supported, not whether the target is async right now. gdb/ChangeLog: PR gdb/26199 * infrun.c (prepare_to_wait): Check target_can_async_p instead of target_is_async_p. |
|||
b1a35af270 |
gdb: remove unused fetch_inferior_event and inferior_event_handler parameters
I noticed that fetch_inferior_event receives the client_data parameter from its caller, inferior_event_handler, but doesn't actually need it. This patch removes it. In turn, inferior_event_handler doesn't use its parameter, so remove it too. The `data` argument used when registering remote_async_inferior_event_handler is changed to NULL, to avoid confusion. It could make people think that the value passed is used somewhere, when in fact it's not. gdb/ChangeLog: * inf-loop.c (inferior_event_handler): Remove client_data param. * inf-loop.h (inferior_event_handler): Likewise. * infcmd.c (step_1): Adjust. * infrun.c (proceed): Adjust. (fetch_inferior_event): Remove client_data param. (infrun_async_inferior_event_handler): Adjust. * infrun.h (fetch_inferior_event): Remove `void *` param. * linux-nat.c (handle_target_event): Adjust. * record-btrace.c (record_btrace_handle_async_inferior_event): Adjust. * record-full.c (record_full_async_inferior_event_handler): Adjust. * remote.c (remote_async_inferior_event_handler): Adjust. Change-Id: I3c2aa1eb0ea3e0985df096660d2dcd794674f2ea |
|||
18493a005a |
Don't write to inferior_ptid in infrun.c
gdb/ChangeLog: 2020-06-18 Pedro Alves <palves@redhat.com> * infrun.c (generic_mourn_inferior): Use switch_to_thread instead of writing to inferior_ptid. (scoped_restore_exited_inferior): Delete. (handle_vfork_child_exec_or_exit): Simplify using scoped_restore_current_pspace_and_thread. Use switch_to_thread instead of writing to inferior_ptid. (THREAD_STOPPED_BY): Delete. (thread_stopped_by_watchpoint, thread_stopped_by_sw_breakpoint) (thread_stopped_by_hw_breakpoint): Delete. (save_waitstatus): Use scoped_restore_current_thread+switch_to_thread, and call target_stopped_by_watchpoint instead of thread_stopped_by_watchpoint, target_stopped_by_sw_breakpoint instead of thread_stopped_by_sw_breakpoint, and target_stopped_by_hw_breakpoint instead of thread_stopped_by_hw_breakpoint. (handle_inferior_event) <TARGET_WAITKIND_EXITED/TARGET_WAITKIND_SIGNALLED>: Don't write to inferior_ptid directly, nor set_current_inferior/set_current_program_space. Use switch_to_thread / switch_to_inferior_no_thread instead. |
|||
2dab0c7ba0 |
Remove ALL_UIS
Continuing my goal of removing the "ALL_*" iterator macros, this removes ALL_UIS, replacing it with an iterator adaptor. gdb/ChangeLog 2020-05-16 Tom Tromey <tom@tromey.com> * top.c (quit_force): Update. * infrun.c (handle_no_resumed): Update. * top.h (all_uis): New function. (ALL_UIS): Remove. |
|||
29d6859f09 |
gdb: infrun: consume multiple events at each pass in stop_all_threads
[Simon: I send this patch on behalf of Laurent Morichetti, I added the commit message and performance measurement stuff. Also, this patch is better viewed with "git show -w".] stop_all_threads, in infrun.c, is used to stop all running threads on targets that are always non-stop. It's used, for example, when the program hits a breakpoint while GDB is set to "non-stop off". It sends a stop request for each running thread, then collects one wait event for each. Since new threads can spawn while we are stopping the threads, it's written in a way where it makes multiple such "send stop requests to running threads & collect wait events" passes. The function completes when it has made two passes where it hasn't seen any running threads. With the way it's written right now is, it iterates on the thread list, sending a stop request for each running thread. It then waits for a single event, after which it iterates through the thread list again. It sends stop requests for any running threads that's been created since the last iteration. It then consumes another single wait event. This makes it so we iterate on O(n^2) threads in total, where n is the number of threads. This patch changes the function to reduce it to O(n). This starts to have an impact when dealing with multiple thousands of threads (see numbers below). At each pass, we know the number of outstanding stop requests we have sent, for which we need to collect a stop event. We can therefore loop to collect this many stop events before proceeding to the next pass and iterate on the thread list again. To check the performance improvements with this patch, I made an x86/Linux program with a large number of idle threads (varying from 1000 to 10000). The program's main thread hits a breakpoint once all these threads have started, which causes stop_all_threads to be called to stop all these threads. I measured (by patching stop_all_threads): - the execution time of stop_all_threads - the total number of threads we iterate on during the complete execution of the function (the total number of times we execute the "for (thread_info *t : all_non_exited_threads ())" loop) These are the execution times, in milliseconds: # threads before after 1000 226 106 2000 997 919 3000 3461 2323 4000 4330 3570 5000 8642 6600 6000 9918 8039 7000 12662 10930 8000 16652 11222 9000 21561 15875 10000 26613 20019 Note that I very unscientifically executed each case only once. These are the number of loop executions: # threads before after 1000 1003002 3003 2000 4006002 6003 3000 9009002 9003 4000 16012002 12003 5000 25015002 15003 6000 36018002 18003 7000 49021002 21003 8000 64024002 24003 9000 81027002 27003 10000 100030002 30003 This last table shows pretty well the O(n^2) vs O(n) behaviors. Reg-tested on x86 GNU/Linux (Ubuntu 16.04). gdb/ChangeLog: YYYY-MM-DD Laurent Morichetti <Laurent.Morichetti@amd.com> YYYY-MM-DD Simon Marchi <simon.marchi@efficios.com> * infrun.c (stop_all_threads): Collect multiple wait events at each pass. |
|||
a05575d39a |
gdb/infrun: handle already-exited threads when attempting to stop
In stop_all_threads, GDB sends signals to other threads in an attempt to stop them. While in a typical scenario the expected wait status is TARGET_WAITKIND_STOPPED, it is possible that the thread GDB attempted to stop has already terminated. If so, a waitstatus other than TARGET_WAITKIND_STOPPED would be received. Handle this case appropriately. If a wait status that denotes thread termination is ignored, GDB goes into an infinite loop in stop_all_threads. E.g.: $ gdb ./a.out (gdb) start ... (gdb) add-inferior -exec ./a.out ... (gdb) inferior 2 ... (gdb) start ... (gdb) set schedule-multiple on (gdb) set debug infrun 2 (gdb) continue Continuing. infrun: clear_proceed_status_thread (process 10449) infrun: clear_proceed_status_thread (process 10453) infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT) infrun: proceed: resuming process 10449 infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 10449] at 0x55555555514e infrun: infrun_async(1) infrun: prepare_to_wait infrun: proceed: resuming process 10453 infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 10453] at 0x55555555514e infrun: prepare_to_wait infrun: Found 2 inferiors, starting at #0 infrun: target_wait (-1.0.0, status) = infrun: 10449.10449.0 [process 10449], infrun: status->kind = exited, status = 0 infrun: handle_inferior_event status->kind = exited, status = 0 [Inferior 1 (process 10449) exited normally] infrun: stop_waiting infrun: stop_all_threads infrun: stop_all_threads, pass=0, iterations=0 infrun: process 10453 executing, need stop infrun: target_wait (-1.0.0, status) = infrun: 10453.10453.0 [process 10453], infrun: status->kind = exited, status = 0 infrun: stop_all_threads status->kind = exited, status = 0 process 10453 infrun: process 10453 executing, already stopping infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [process -1], infrun: status->kind = no-resumed infrun: infrun_async(0) infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping infrun: stop_all_threads status->kind = no-resumed process -1 infrun: process 10453 executing, already stopping ... And this polling goes on forever. This patch prevents the infinite looping behavior. For the same scenario above, we obtain the following behavior: ... (gdb) continue Continuing. infrun: clear_proceed_status_thread (process 31229) infrun: clear_proceed_status_thread (process 31233) infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT) infrun: proceed: resuming process 31229 infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 31229] at 0x55555555514e infrun: infrun_async(1) infrun: prepare_to_wait infrun: proceed: resuming process 31233 infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 31233] at 0x55555555514e infrun: prepare_to_wait infrun: Found 2 inferiors, starting at #0 infrun: target_wait (-1.0.0, status) = infrun: 31229.31229.0 [process 31229], infrun: status->kind = exited, status = 0 infrun: handle_inferior_event status->kind = exited, status = 0 [Inferior 1 (process 31229) exited normally] infrun: stop_waiting infrun: stop_all_threads infrun: stop_all_threads, pass=0, iterations=0 infrun: process 31233 executing, need stop infrun: target_wait (-1.0.0, status) = infrun: 31233.31233.0 [process 31233], infrun: status->kind = exited, status = 0 infrun: stop_all_threads status->kind = exited, status = 0 process 31233 infrun: saving status status->kind = exited, status = 0 for 31233.31233.0 infrun: process 31233 not executing infrun: stop_all_threads, pass=1, iterations=1 infrun: process 31233 not executing infrun: stop_all_threads done (gdb) The exit event from Inferior 1 is received and shown to the user. The exit event from Inferior 2 is not displayed, but kept pending. (gdb) info inferiors Num Description Connection Executable * 1 <null> a.out 2 process 31233 1 (native) a.out (gdb) inferior 2 [Switching to inferior 2 [process 31233] (a.out)] [Switching to thread 2.1 (process 31233)] Couldn't get registers: No such process. (gdb) continue Continuing. infrun: clear_proceed_status_thread (process 31233) infrun: clear_proceed_status_thread: thread process 31233 has pending wait status status->kind = exited, status = 0 (currently_stepping=0). infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT) infrun: proceed: resuming process 31233 infrun: resume: thread process 31233 has pending wait status status->kind = exited, status = 0 (currently_stepping=0). infrun: prepare_to_wait infrun: Using pending wait status status->kind = exited, status = 0 for process 31233. infrun: target_wait (-1.0.0, status) = infrun: 31233.31233.0 [process 31233], infrun: status->kind = exited, status = 0 infrun: handle_inferior_event status->kind = exited, status = 0 [Inferior 2 (process 31233) exited normally] infrun: stop_waiting (gdb) info inferiors Num Description Connection Executable 1 <null> a.out * 2 <null> a.out (gdb) When a process exits and we leave the process exit event pending, we need to make sure that at least one thread is left listed in the inferior's thread list. This is necessary in order to make sure we have a thread that we can later resume, so the process exit event can be collected/reported. When native debugging, the GNU/Linux back end already makes sure that the last LWP isn't deleted. When remote debugging against GNU/Linux GDBserver, the GNU/Linux GDBserver backend also makes sure that the last thread isn't deleted until the process exit event is reported to GDBserver core. However, between the backend reporting the process exit event to GDBserver core, and GDB consuming the event, GDB may update the thread list and find no thread left in the process. The process exit event will be pending somewhere in GDBserver's stop reply queue, or gdb/remote.c's queue, or whathever other event queue inbetween GDBserver and infrun.c's handle_inferior_event. This patch tweaks remote.c's target_update_thread_list implementation to avoid deleting the last thread of an inferior. In the past, this case of inferior-with-no-threads led to a special case at the bottom of handle_no_resumed, where it reads: /* Note however that we may find no resumed thread because the whole process exited meanwhile (thus updating the thread list results in an empty thread list). In this case we know we'll be getting a process exit event shortly. */ for (inferior *inf : all_non_exited_inferiors (ecs->target)) In current master, that code path is still reachable with the gdb.threads/continue-pending-after-query.exp testcase, when tested against GDBserver, with "maint set target-non-stop" forced "on". With this patch, the scenario that loop was concerned about is still properly handled, because the loop above it finds the process's last thread with "executing" set to true, and thus the handle_no_resumed function still returns true. Since GNU/Linux native and remote are the only targets that support non-stop mode, and with this patch, we always make sure the inferior has at least one thread, this patch also removes that "inferior with no threads" special case handling from handle_no_resumed. Since remote.c now has a special case where we treat a thread that has already exited as if it was still alive, we might need to tweak remote.c's target_thread_alive implementation to return true for that thread without querying the remote side (which would say "no, not alive"). After inspecting all the target_thread_alive calls in the codebase, it seems that only the one from prune_threads could result in that thread being accidentally deleted. There's only one call to prune_threads in GDB's common code, so this patch handles this by replacing the prune_threads call with a delete_exited_threads call. This seems like an improvement anyway, because we'll still be doing what the comment suggests we want to do, and, we avoid remote protocol traffic. Regression-tested on X86_64 Linux. gdb/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> Tom de Vries <tdevries@suse.de> Pedro Alves <palves@redhat.com> PR threads/25478 * infrun.c (stop_all_threads): Do NOT ignore TARGET_WAITKIND_NO_RESUMED, TARGET_WAITKIND_THREAD_EXITED, TARGET_WAITKIND_EXITED, TARGET_WAITKIND_SIGNALLED wait statuses received. (handle_no_resumed): Remove code handling a live inferior with no threads. * remote.c (has_single_non_exited_thread): New. (remote_target::update_thread_list): Do not delete a thread if is the last thread of the process. * thread.c (thread_select): Call delete_exited_threads instead of prune_threads. gdb/testsuite/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> Pedro Alves <palves@redhat.com> * gdb.multi/multi-exit.c: New file. * gdb.multi/multi-exit.exp: New file. * gdb.multi/multi-kill.c: New file. * gdb.multi/multi-kill.exp: New file. |
|||
6ad8291970 |
gdb/infrun: enable/disable thread events of all targets in stop_all_threads
In stop_all_threads, the thread events of the current top target are enabled at the beginning of the function and then disabled at the end (at scope exit time). Because there may be multiple targets whose thread lists will be updated and whose threads are stopped, enable/disable thread events for all targets. This update caused a change in the annotations. In particular, a "frames-invalid" annotation is printed one more time due to switching the current inferior. Hence, gdb.base/annota1.exp and gdb.cp/annota2.exp tests are also updated. Regression-tested on X86_64 Linux using the default board file and the native-extended-gdbserver board file. gdb/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (stop_all_threads): Enable/disable thread events of all targets. Move a debug message denoting the end of the function into the SCOPED_EXIT block. gdb/testsuite/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.base/annota1.exp: Update the expected output. * gdb.cp/annota2.exp: Ditto. |
|||
293b3ebcba |
gdb/infrun: extract out a code piece into 'mark_non_executing_threads' function
This is a refactoring. The extracted function is placed deliberately before 'stop_all_threads' because the function will be re-used there in a subsequent patch for handling an exit status kind received from a thread that GDB attempted to stop. gdb/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (handle_inferior_event): Extract out a piece of code into... (mark_non_executing_threads): ...this new function. Change-Id: I2b088f4a724f4260cb37068264964525cf62a118 |
|||
7ca9b62a2b |
gdb/infrun: move a 'regcache_read_pc' call down to first use
In infrun.c's resume_1 function, move the definition of the local variable PC down to its first use. This is useful if the thread we want to resume is already gone with a pending exit event, because we avoid the error we would see otherwise when trying to read the PC. gdb/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (resume_1): Move a 'regcache_read_pc' call down to first use. |
|||
fc75c28ba1 |
gdb: protect some 'regcache_read_pc' calls
It possible that a thread whose PC we attempt to read is already dead. In this case, 'regcache_read_pc' errors out. This impacts the "proceed" execution flow, where GDB quits early before having a chance to check if there exists a pending event. To remedy, keep going with a 0 value for the PC if 'regcache_read_pc' fails. Because the value of PC before resuming a thread is mostly used for storing and checking the next time the thread stops, this tolerance is expected to be harmless for a dead thread/process. gdb/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * regcache.c (regcache_read_pc_protected): New function implementation that returns 0 if the PC cannot read via 'regcache_read_pc'. * infrun.c (proceed): Call 'regcache_read_pc_protected' instead of 'regcache_read_pc'. (keep_going_pass_signal): Ditto. gdbsupport/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * common-regcache.h (regcache_read_pc_protected): New function declaration. |
|||
bf4cb9bee2 |
[gdb] Fix stepping over fork with follow-fork-mode child and gcc-8
When running test-case gdb.threads/fork-child-threads.exp with gcc-8 instead of gcc-7, we have: ... (gdb) next^M [Attaching after Thread 0x7ffff7fae740 (LWP 27574) fork to child process \ 27578]^M [New inferior 2 (process 27578)]^M [Detaching after fork from parent process 27574]^M [Inferior 1 (process 27574) detached]^M [Thread debugging using libthread_db enabled]^M Using host libthread_db library "/lib64/libthread_db.so.1".^M [Switching to Thread 0x7ffff7fae740 (LWP 27578)]^M -main () at src/gdb/testsuite/gdb.threads/fork-child-threads.c:41^M +main () at src/gdb/testsuite/gdb.threads/fork-child-threads.c:34^M -41 i = pthread_create (&thread, NULL, start, NULL);^M +34 switch (fork ())^M -(gdb) PASS: gdb.threads/fork-child-threads.exp: next over fork +(gdb) FAIL: gdb.threads/fork-child-threads.exp: next over fork ... This is due to the fact that gcc-8 generates more precise line info, making the instruction after the call to fork a "recommended breakpoint location". However, it is a bug because next is supposed to move to the next source line. The problem is that in process_event_stop_test we hit this code: ... if ((ecs->event_thread->suspend.stop_pc == stop_pc_sal.pc) && (ecs->event_thread->current_line != stop_pc_sal.line || ecs->event_thread->current_symtab != stop_pc_sal.symtab)) { if (stop_pc_sal.is_stmt) { /* We are at the start of a different line. So stop. Note that we don't stop if we step into the middle of a different line. That is said to make things like for (;;) statements work better. */ if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: stepped to a different line\n"); end_stepping_range (ecs); return; } ... because current_line and current_symtab have initial values: ... (gdb) p ecs->event_thread->current_line $8 = 0 (gdb) p ecs->event_thread->current_symtab $9 = (symtab *) 0x0 ... Fix this in follow_fork by copying current_line and current_symtab from parent thread to child thread. Tested on x86_64-linux, with gcc 7.5.0 and gcc 10.0.1. gdb/ChangeLog: 2020-05-08 Tom de Vries <tdevries@suse.de> * infrun.c (follow_fork): Copy current_line and current_symtab to child thread. |
|||
d43b7a2d57 |
gdb/infrun: switch the context before 'displaced_step_restore'
In infrun.c's 'displaced_step_fixup', as part of the 'finish_step_over' flow, switch to the eventing thread *before* calling 'displaced_step_restore', because down in the flow ptid-dependent memory accesses are used via current_inferior() and current_top_target(). Without this patch, the problem is exposed with the scenario below: $ gdb -q (gdb) maint set target-non-stop on (gdb) file a.out Reading symbols from a.out... (gdb) set remote exec-file a.out (gdb) target extended-remote | gdbserver --once --multi - ... (gdb) add-inferior [New inferior 2] Added inferior 2 on connection 1 (extended-remote ...) (gdb) inferior 2 [Switching to inferior 2 [<null>] (<noexec>)] (gdb) file a.out Reading symbols from a.out... (gdb) set remote exec-file a.out (gdb) run ... Cannot access memory at address 0x555555555042 (gdb) The problem is, down inside 'displaced_step_restore', GDB wants to access the memory for inferior 2 because of an internal breakpoint. However, the current inferior and inferior_ptid are out of sync. While inferior_ptid correctly points to the process of inf 2 that was just started, current_inferior points to inf 1. Then, the attempt to access the memory fails, because target_has_execution results in false since inf 1 was not started. I was not able to simplify the failing scenario, but it shows the problem. After this patch, we get ... same steps above... (gdb) run ... [Inferior 2 (process 28652) exited normally] (gdb) Regression-tested on X86_64 Linux with `make check`s default board file and also `--target_board=native-extended-gdbserver`. In fact, the bug fixed by this patch was exposed when using the native-extended-gdbserver board file. gdb/ChangeLog: 2020-04-21 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (displaced_step_fixup): Switch to the event_thread before calling displaced_step_restore, not after. gdb/testsuite/ChangeLog: 2020-04-21 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.multi/run-only-second-inf.c: New file. * gdb.multi/run-only-second-inf.exp: New file. |
|||
08feed99cb |
Change get_objfile_arch to a method on objfile
This changes get_objfile_arch to be a new inline method, objfile::arch. To my surprise, this function came up while profiling DWARF psymbol reading. Making this change improved performance from 1.986 seconds to 1.869 seconds. Both measurements were done by taking the mean of 10 runs on a fixed copy of the gdb executable. gdb/ChangeLog 2020-04-18 Tom Tromey <tom@tromey.com> * xcoffread.c (enter_line_range, scan_xcoff_symtab): Update. * value.c (value_fn_field): Update. * valops.c (find_function_in_inferior) (value_allocate_space_in_inferior): Update. * tui/tui-winsource.c (tui_update_source_windows_with_line): Update. * tui/tui-source.c (tui_source_window::set_contents): Update. * symtab.c (lookup_global_or_static_symbol) (find_function_start_sal_1, skip_prologue_sal) (print_msymbol_info, find_gnu_ifunc, symbol_arch): Update. * symmisc.c (dump_msymbols, dump_symtab_1) (maintenance_print_one_line_table): Update. * symfile.c (init_entry_point_info, section_is_mapped) (list_overlays_command, simple_read_overlay_table) (simple_overlay_update_1): Update. * stap-probe.c (handle_stap_probe): Update. * stabsread.c (dbx_init_float_type, define_symbol) (read_one_struct_field, read_enum_type, read_range_type): Update. * source.c (info_line_command): Update. * python/python.c (gdbpy_source_objfile_script) (gdbpy_execute_objfile_script): Update. * python/py-type.c (save_objfile_types): Update. * python/py-objfile.c (py_free_objfile): Update. * python/py-inferior.c (python_new_objfile): Update. * psymtab.c (psym_find_pc_sect_compunit_symtab, dump_psymtab) (dump_psymtab_addrmap_1, maintenance_info_psymtabs) (maintenance_check_psymtabs): Update. * printcmd.c (info_address_command): Update. * objfiles.h (struct objfile) <arch>: New method, from get_objfile_arch. (get_objfile_arch): Don't declare. * objfiles.c (get_objfile_arch): Remove. (filter_overlapping_sections): Update. * minsyms.c (msymbol_is_function): Update. * mi/mi-symbol-cmds.c (mi_cmd_symbol_list_lines) (output_nondebug_symbol): Update. * mdebugread.c (parse_symbol, basic_type, parse_partial_symbols) (mdebug_expand_psymtab): Update. * machoread.c (macho_add_oso_symfile): Update. * linux-tdep.c (linux_infcall_mmap, linux_infcall_munmap): Update. * linux-fork.c (checkpoint_command): Update. * linespec.c (convert_linespec_to_sals): Update. * jit.c (finalize_symtab): Update. * infrun.c (insert_exception_resume_from_probe): Update. * ia64-tdep.c (ia64_find_unwind_table): Update. * hppa-tdep.c (internalize_unwinds): Update. * gdbtypes.c (get_type_arch, init_float_type, objfile_type): Update. * gcore.c (call_target_sbrk): Update. * elfread.c (record_minimal_symbol, elf_symtab_read) (elf_rel_plt_read, elf_gnu_ifunc_record_cache) (elf_gnu_ifunc_resolve_by_got): Update. * dwarf2/read.c (create_addrmap_from_index) (create_addrmap_from_aranges, dw2_find_pc_sect_compunit_symtab) (read_debug_names_from_section) (process_psymtab_comp_unit_reader, add_partial_symbol) (add_partial_subprogram, process_full_comp_unit) (read_file_scope, read_func_scope, read_lexical_block_scope) (read_call_site_scope, dwarf2_ranges_read) (dwarf2_record_block_ranges, dwarf2_add_field) (mark_common_block_symbol_computed, read_tag_pointer_type) (read_tag_string_type, dwarf2_init_float_type) (dwarf2_init_complex_target_type, read_base_type) (partial_die_info::read, partial_die_info::read) (read_attribute_value, dwarf_decode_lines_1, new_symbol) (dwarf2_fetch_die_loc_sect_off): Update. * dwarf2/loc.c (dwarf2_find_location_expression) (class dwarf_evaluate_loc_desc, rw_pieced_value) (dwarf2_evaluate_loc_desc_full, dwarf2_locexpr_baton_eval) (dwarf2_loc_desc_get_symbol_read_needs) (locexpr_describe_location_piece, locexpr_describe_location_1) (loclist_describe_location): Update. * dwarf2/index-write.c (write_debug_names): Update. * dwarf2/frame.c (dwarf2_build_frame_info): Update. * dtrace-probe.c (dtrace_process_dof): Update. * dbxread.c (read_dbx_symtab, dbx_end_psymtab) (process_one_symbol): Update. * ctfread.c (ctf_init_float_type, read_base_type): Update. * coffread.c (coff_symtab_read, enter_linenos, decode_base_type) (coff_read_enum_type): Update. * cli/cli-cmds.c (edit_command, list_command): Update. * buildsym.c (buildsym_compunit::finish_block_internal): Update. * breakpoint.c (create_overlay_event_breakpoint) (create_longjmp_master_breakpoint) (create_std_terminate_master_breakpoint) (create_exception_master_breakpoint, get_sal_arch): Update. * block.c (block_gdbarch): Update. * annotate.c (annotate_source_line): Update. |
|||
400b5eca00 |
Move event-loop.[ch] to gdbsupport/
This moves event-loop.[ch] to gdbsupport/ and updates the uses in gdb. gdb/ChangeLog 2020-04-13 Tom Tromey <tom@tromey.com> * run-on-main-thread.c: Update include. * unittests/main-thread-selftests.c: Update include. * tui/tui-win.c: Update include. * tui/tui-io.c: Update include. * tui/tui-interp.c: Update include. * tui/tui-hooks.c: Update include. * top.h: Update include. * top.c: Update include. * ser-base.c: Update include. * remote.c: Update include. * remote-notif.c: Update include. * remote-fileio.c: Update include. * record-full.c: Update include. * record-btrace.c: Update include. * python/python.c: Update include. * posix-hdep.c: Update include. * mingw-hdep.c: Update include. * mi/mi-main.c: Update include. * mi/mi-interp.c: Update include. * main.c: Update include. * linux-nat.c: Update include. * interps.c: Update include. * infrun.c: Update include. * inf-loop.c: Update include. * event-top.c: Update include. * event-loop.c: Move to ../gdbsupport/. * event-loop.h: Move to ../gdbsupport/. * async-event.h: Update include. * Makefile.in (COMMON_SFILES, HFILES_NO_SRCDIR): Update. gdbsupport/ChangeLog 2020-04-13 Tom Tromey <tom@tromey.com> * event-loop.h: Move from ../gdb/. * event-loop.cc: Move from ../gdb/. |
|||
93b54c8ed3 |
Introduce async-event.[ch]
This patch splits out some gdb-specific code from event-loop, into new files async-event.[ch]. Strictly speaking this code could perhaps be put into gdbsupport/, but because gdbserver does not currently use it, it seemed better, for size reasons, to split it out. gdb/ChangeLog 2020-04-13 Tom Tromey <tom@tromey.com> * tui/tui-win.c: Include async-event.h. * remote.c: Include async-event.h. * remote-notif.c: Include async-event.h. * record-full.c: Include async-event.h. * record-btrace.c: Include async-event.h. * infrun.c: Include async-event.h. * event-top.c: Include async-event.h. * event-loop.h: Move some declarations to async-event.h. * event-loop.c: Don't include ser-event.h or top.h. Move some code to async-event.c. * async-event.h: New file. * async-event.c: New file. * Makefile.in (COMMON_SFILES): Add async-event.c. (HFILES_NO_SRCDIR): Add async-event.h. |
|||
06cc9596e8 |
Move gdb_select.h to gdbsupport/
This moves gdb_select.h to gdbsupport/, so it can be used by other code there. gdb/ChangeLog 2020-04-13 Tom Tromey <tom@tromey.com> * gdb_select.h: Move to ../gdbsupport/. * event-loop.c: Update include path. * top.c: Update include path. * ser-base.c: Update include path. * ui-file.c: Update include path. * ser-tcp.c: Update include path. * guile/scm-ports.c: Update include path. * posix-hdep.c: Update include path. * ser-unix.c: Update include path. * gdb_usleep.c: Update include path. * mingw-hdep.c: Update include path. * inflow.c: Update include path. * infrun.c: Update include path. * event-top.c: Update include path. gdbsupport/ChangeLog 2020-04-13 Tom Tromey <tom@tromey.com> * gdb_select.h: Move from ../gdb/. |
|||
53cccef118 |
gdb/infrun: stop all threads if there exists a non-stop target
Stop all threads not only if the current target is non-stop, but also if there exists a non-stop target. The multi-target patch (5b6d1e4fa4f "Multi-target support") made the following change to gdb/inf-child.c: void inf_child_target::maybe_unpush_target () { - if (!inf_child_explicitly_opened && !have_inferiors ()) + if (!inf_child_explicitly_opened) unpush_target (this); } If we are in all-stop mode with multiple inferiors, and an exit event is received from an inferior, target_mourn_inferior() gets to this point and without the have_inferiors() check, the target is unpushed. This leads to having exec_ops as the top target. Here is a test scenario. Two executables, ./a.out returns immediately; ./sleepy just sleeps. $ gdb ./sleepy (gdb) start ... (gdb) add-inferior -exec ./a.out ... (gdb) inferior 2 [Switching to inferior 2.. (gdb) start ... (gdb) set schedule-multiple on (gdb) set debug infrun 1 (gdb) continue At this point, the exit event is received from ./a.out. Normally, this would lead to stop_all_threads() to also stop ./sleepy, but this doesn't happen, because target_is_non_stop_p() returns false. And it returns false because the top target is no longer the process target; it is the exec_ops. This patch modifies 'stop_waiting' to call 'stop_all_threads' if there exists a non-stop target, not just when the current top target is non-stop. Tested on X86_64 Linux. gdb/ChangeLog: 2020-04-01 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * infrun.c (stop_all_threads): Update assertion, plus when stopping threads, take into account that we might be trying to stop an all-stop target. (stop_waiting): Call 'stop_all_threads' if there exists a non-stop target. gdb/testsuite/ChangeLog: 2020-04-01 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.multi/stop-all-on-exit.c: New test. * gdb.multi/stop-all-on-exit.exp: New file. |