This repository has been archived by the owner on Aug 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 234
style updates and more! #3
Merged
palmer-dabbelt
merged 6 commits into
riscvarchive:riscv-rebase-2015.10.08
from
vapier:riscv-rebase-2015.10.08
Nov 30, 2015
Merged
style updates and more! #3
palmer-dabbelt
merged 6 commits into
riscvarchive:riscv-rebase-2015.10.08
from
vapier:riscv-rebase-2015.10.08
Nov 30, 2015
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This was copied blindly from the earlier port (mips?) and doesn't make sense for riscv targets. Drop it.
The -mrvc flag will enable EF_RISCV_RVC, but the -mno-rvc flag does not clear it. Make sure the bit setting is not one way.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Nov 30, 2015
Hi, I build GDB with -fsanitize=address, and run testsuite. In gdb.base/callfuncs.exp, I see the following error, p t_float_values(0.0,0.0) ================================================================= ==8088==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000cb650 at pc 0x6e195c bp 0x7fff164f9770 sp 0x7fff164f9768 READ of size 16 at 0x6020000cb650 thread T0^ #0 0x6e195b in regcache_raw_write /home/yao/SourceCode/gnu/gdb/git/gdb/regcache.c:912 #1 0x6e1e52 in regcache_cooked_write /home/yao/SourceCode/gnu/gdb/git/gdb/regcache.c:945 #2 0x466d69 in pass_in_v /home/yao/SourceCode/gnu/gdb/git/gdb/aarch64-tdep.c:1101 #3 0x467512 in pass_in_v_or_stack /home/yao/SourceCode/gnu/gdb/git/gdb/aarch64-tdep.c:1196 #4 0x467d7d in aarch64_push_dummy_call /home/yao/SourceCode/gnu/gdb/git/gdb/aarch64-tdep.c:1335 The code in pass_in_v read contents from V registers (128 bit), but the data passed through V registers can be less than 128 bit. In this case, float is passed. So writing V registers contents into contents buff will cause overflow. In this patch, we add an array reg[V_REGISTER_SIZE], which is to hold the contents from V registers, and then copy useful bits to buf. gdb: 2015-11-18 Yao Qi <[email protected]> * aarch64-tdep.c (pass_in_v): Add argument len. Add local array reg. Callers updated.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Nov 30, 2015
This patch fixes the GDB internal error on AArch64 when running watchpoint-fork.exp top?bt 15 internal_error (file=file@entry=0x79d558 "../../binutils-gdb/gdb/linux-nat.c", line=line@entry=4866, fmt=0x793b20 "%s: Assertion `%s' failed.") at ../../binutils-gdb/gdb/common/errors.c:51 #1 0x0000000000495bc4 in linux_nat_thread_address_space (t=<optimized out>, ptid=<error reading variable: Cannot access memory at address 0x1302>) at ../../binutils-gdb/gdb/linux-nat.c:4866 #2 0x00000000005db2c8 in delegate_thread_address_space (self=<optimized out>, arg1=<error reading variable: Cannot access memory at address 0x1302>) at ../../binutils-gdb/gdb/target-delegates.c:2447 #3 0x00000000005e8c7c in target_thread_address_space (ptid=<error reading variable: Cannot access memory at address 0x1302>) at ../../binutils-gdb/gdb/target.c:2727 #4 0x000000000054eef8 in get_thread_arch_regcache (ptid=..., gdbarch=0xad51e0) at ../../binutils-gdb/gdb/regcache.c:529 #5 0x000000000054efcc in get_thread_regcache (ptid=...) at ../../binutils-gdb/gdb/regcache.c:546 #6 0x000000000054f120 in get_thread_regcache_for_ptid (ptid=...) at ../../binutils-gdb/gdb/regcache.c:560 #7 0x00000000004a2278 in aarch64_point_is_aligned (is_watchpoint=0, addr=34168, len=2) at ../../binutils-gdb/gdb/nat/aarch64-linux-hw-point.c:122 #8 0x00000000004a2e68 in aarch64_handle_breakpoint (type=hw_execute, addr=34168, len=2, is_insert=0, state=0xae8880) at ../../binutils-gdb/gdb/nat/aarch64-linux-hw-point.c:465 #9 0x000000000048edf0 in aarch64_linux_remove_hw_breakpoint (self=<optimized out>, gdbarch=<optimized out>, bp_tgt=<optimized out>) at ../../binutils-gdb/gdb/aarch64-linux-nat.c:657 #10 0x00000000005da8dc in delegate_remove_hw_breakpoint (self=<optimized out>, arg1=<optimized out>, arg2=<optimized out>) at ../../binutils-gdb/gdb/target-delegates.c:492 #11 0x0000000000536a24 in bkpt_remove_location (bl=<optimized out>) at ../../binutils-gdb/gdb/breakpoint.c:13065 #12 0x000000000053351c in remove_breakpoint_1 (bl=0xb3fe70, is=is@entry=mark_inserted) at ../../binutils-gdb/gdb/breakpoint.c:4026 #13 0x000000000053ccc0 in detach_breakpoints (ptid=...) at ../../binutils-gdb/gdb/breakpoint.c:3930 #14 0x00000000005a3ac0 in handle_inferior_event_1 (ecs=0x7ffffff048) at ../../binutils-gdb/gdb/infrun.c:5042 After the fork, GDB will physically remove the breakpoints from the child process (in frame #14), but at that time, GDB doesn't create an inferior yet for child, but inferior_ptid is set to child's ptid (in frame #13). In aarch64_point_is_aligned, we'll get the regcache of current_lwp_ptid to determine if the current process is 32-bit or 64-bit, so the inferior can't be found, and the internal error is caused. I don't find a better fix other than not checking alignment on removing breakpoint. gdb: 2015-11-27 Yao Qi <[email protected]> * nat/aarch64-linux-hw-point.c (aarch64_dr_state_remove_one_point): Don't assert on alignment. (aarch64_handle_breakpoint): Only check alignment when IS_INSERT is true.
Thanks a bunch! |
palmer-dabbelt
pushed a commit
that referenced
this pull request
Feb 12, 2016
Hi, AddressSanitizer reports an error like this, (gdb) PASS: gdb.base/call-ar-st.exp: continue to tbreak9 print print_long_arg_list(a, b, c, d, e, f, *struct1, *struct2, *struct3, *struct4, *flags, *flags_combo, *three_char, *five_char, *int_char_combo, *d1, *d2, *d3, *f1, *f2, *f3) ================================================================= ==6236==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200008eb50 at pc 0x89e432 bp 0x7fffa3df9080 sp 0x7fffa3df9078 READ of size 5 at 0x60200008eb50 thread T0 #0 0x89e431 in memory_xfer_partial gdb/target.c:1264 #1 0x89e6c7 in target_xfer_partial gdb/target.c:1320 #2 0x89f267 in target_write_partial gdb/target.c:1595^M #3 0x8a014b in target_write_with_progress gdb/target.c:1889^M #4 0x8a0262 in target_write gdb/target.c:1914^M #5 0x89ee59 in target_write_memory gdb/target.c:1492^M #6 0x9a1c74 in write_memory gdb/corefile.c:393^M #7 0x467ea5 in aarch64_push_dummy_call gdb/aarch64-tdep.c:1388 The problem is that an instance of stack_item_t is created to adjust stack for alignment, the item.len is correct, but item.data is buf, which is wrong, because item.len can be greater than the length of buf. This patch sets item.data to NULL, and only update sp (no inferior memory writes on stack for this item). gdb: 2015-12-17 Yao Qi <[email protected]> * aarch64-tdep.c (struct stack_item_t): Update comments. (pass_on_stack): Set item.data to NULL. (aarch64_push_dummy_call): Call write_memory if si->data isn't NULL.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Feb 12, 2016
…al is ours I see a timeout in gdb.base/random-signal.exp, Continuing.^M PASS: gdb.base/random-signal.exp: continue ^CPython Exception <type 'exceptions.KeyboardInterrupt'> <type exceptions.KeyboardInterrupt'>: ^M FAIL: gdb.base/random-signal.exp: stop with control-c (timeout) it can be reproduced by running random-signal.exp with native-gdbserver in a loop, like this, and the fail will be shown in about 20 runs, $ (set -e; while true; do make check RUNTESTFLAGS="--target_board=native-gdbserver random-signal.exp"; done) In the test, the program is being single-stepped for software watchpoint, and in each internal stop, python unwinder sniffer is used, #0 pyuw_sniffer (self=<optimised out>, this_frame=<optimised out>, cache_ptr=0xd554f8) at /home/yao/SourceCode/gnu/gdb/git/gdb/python/py-unwind.c:608 #1 0x00000000006a10ae in frame_unwind_try_unwinder (this_frame=this_frame@entry=0xd554e0, this_cache=this_cache@entry=0xd554f8, unwinder=0xecd540) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame-unwind.c:107 #2 0x00000000006a143f in frame_unwind_find_by_frame (this_frame=this_frame@entry=0xd554e0, this_cache=this_cache@entry=0xd554f8) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame-unwind.c:163 #3 0x000000000069dc6b in compute_frame_id (fi=0xd554e0) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:454 #4 get_prev_frame_if_no_cycle (this_frame=this_frame@entry=0xd55410) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1781 #5 0x000000000069fdb9 in get_prev_frame_always_1 (this_frame=0xd55410) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1955 #6 get_prev_frame_always (this_frame=this_frame@entry=0xd55410) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1971 #7 0x00000000006a04b1 in get_prev_frame (this_frame=this_frame@entry=0xd55410) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:2213 when GDB goes to python extension, or other language extension, the SIGINT handler is changed, and is restored when GDB leaves extension language. GDB only stays in extension language for a very short period in this case, but if ctrl-c is pressed at that moment, python extension will handle the SIGINT, and exceptions.KeyboardInterrupt is shown. Language extension is used in GDB side rather than inferior side, so GDB should only change SIGINT handler for extension language when the terminal is ours (not inferior's). This is what this patch does. With this patch applied, I run random-signal.exp in a loop for 18 hours, and no fail is shown. gdb: 2016-01-08 Yao Qi <[email protected]> * extension.c: Include target.h. (set_active_ext_lang): Only call install_gdb_sigint_handler, check_quit_flag, and set_quit_flag if target_terminal_is_ours returns false. (restore_active_ext_lang): Likewise. * target.c (target_terminal_is_ours): New function. * target.h (target_terminal_is_ours): Declare.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Feb 12, 2016
I see GDB crashes in dprintf.exp on aarch64-linux testing, (gdb) PASS: gdb.base/dprintf.exp: agent: break 29 set dprintf-style agent^M (gdb) PASS: gdb.base/dprintf.exp: agent: set dprintf style to agent continue^M Continuing. ASAN:SIGSEGV ================================================================= ==22475==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x000000494820 sp 0x7fff389b83a0 bp 0x62d000082417 T0) #0 0x49481f in remote_add_target_side_commands /home/yao/SourceCode/gnu/gdb/git/gdb/remote.c:9190^M #1 0x49e576 in remote_add_target_side_commands /home/yao/SourceCode/gnu/gdb/git/gdb/remote.c:9174^M #2 0x49e576 in remote_insert_breakpoint /home/yao/SourceCode/gnu/gdb/git/gdb/remote.c:9240^M #3 0x5278b7 in insert_bp_location /home/yao/SourceCode/gnu/gdb/git/gdb/breakpoint.c:2734^M #4 0x52ac09 in insert_breakpoint_locations /home/yao/SourceCode/gnu/gdb/git/gdb/breakpoint.c:3159^M #5 0x52ac09 in update_global_location_list /home/yao/SourceCode/gnu/gdb/git/gdb/breakpoint.c:12686 the root cause of this problem in this case is about linespec and symtab which produces additional incorrect location and a NULL is added to bp_tgt->tcommands. I posted a patch https://sourceware.org/ml/gdb-patches/2015-12/msg00321.html to fix it in linespec (the fix causes regression), but GDB still shouldn't add NULL into bp_tgt->tcommands. The logic of build_target_command_list looks odd to me. If we get something wrong in parse_cmd_to_aexpr (it returns NULL), we shouldn't continue, instead we should set flag null_command_or_parse_error. This is what this patch does. In the meantime, we find build_target_condition_list has the same problem, so fix it too. gdb: 2016-01-28 Yao Qi <[email protected]> * breakpoint.c (build_target_command_list): Don't call continue if aexpr is NULL. (build_target_condition_list): Likewise.
zizztux
pushed a commit
to zizztux/riscv-binutils-gdb
that referenced
this pull request
Aug 11, 2016
I see the following error in testing aarch64 GDB debugging arm program. (gdb) PASS: gdb.reverse/readv-reverse.exp: set breakpoint at marker2 continue Continuing. ================================================================= ==32273==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x000000ce4c00 in thread T0 #0 0x2ba5615645c7 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x545c7)^M riscvarchive#1 0x4be8b5 in VEC_CORE_ADDR_cleanup /home/yao/SourceCode/gnu/gdb/git/gdb/common/gdb_vecs.h:34^M riscvarchive#2 0x5e6d95 in do_my_cleanups /home/yao/SourceCode/gnu/gdb/git/gdb/common/cleanups.c:154^M riscvarchive#3 0x64c99a in fetch_inferior_event /home/yao/SourceCode/gnu/gdb/git/gdb/infrun.c:3975^M riscvarchive#4 0x678437 in inferior_event_handler /home/yao/SourceCode/gnu/gdb/git/gdb/inf-loop.c:44^M riscvarchive#5 0x5078f6 in remote_async_serial_handler /home/yao/SourceCode/gnu/gdb/git/gdb/remote.c:13223^M riscvarchive#6 0x4cecfd in run_async_handler_and_reschedule /home/yao/SourceCode/gnu/gdb/git/gdb/ser-base.c:137^M riscvarchive#7 0x676864 in gdb_wait_for_event /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:834^M riscvarchive#8 0x676a27 in gdb_do_one_event /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:323^M riscvarchive#9 0x676aed in start_event_loop /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:347^M riscvarchive#10 0x6706d2 in captured_command_loop /home/yao/SourceCode/gnu/gdb/git/gdb/main.c:318^M riscvarchive#11 0x66db8c in catch_errors /home/yao/SourceCode/gnu/gdb/git/gdb/exceptions.c:240^M riscvarchive#12 0x6716dd in captured_main /home/yao/SourceCode/gnu/gdb/git/gdb/main.c:1157^M riscvarchive#13 0x66db8c in catch_errors /home/yao/SourceCode/gnu/gdb/git/gdb/exceptions.c:240^M riscvarchive#14 0x671b7a in gdb_main /home/yao/SourceCode/gnu/gdb/git/gdb/main.c:1165^M riscvarchive#15 0x467684 in main /home/yao/SourceCode/gnu/gdb/git/gdb/gdb.c:32^M riscvarchive#16 0x2ba563ed7ec4 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)^M riscvarchive#17 0x4676b2 (/scratch/yao/gdb/build-git/aarch64-linux-gnu/gdb/gdb+0x4676b2) looks we should discard cleanup if function arm_linux_software_single_step returns early, or create cleanup when it is needed. gdb: 2016-02-16 Yao Qi <[email protected]> * arm-linux-tdep.c (arm_linux_software_single_step): Assign 'old_chain' later.
zizztux
pushed a commit
to zizztux/riscv-binutils-gdb
that referenced
this pull request
Aug 11, 2016
I see the following GDBserver internal error in two cases, gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected. unsuspend LWP 17200, suspended=-1 1. step over a breakpoint on fork/vfork syscall instruction, 2. step over a breakpoint on clone syscall instruction and child threads hits a breakpoint, the stack backtrace is #0 internal_error (file=file@entry=0x44c4c0 "gdb/gdbserver/linux-low.c", line=line@entry=1922, fmt=fmt@entry=0x44c7d0 "unsuspend LWP %ld, suspended=%d\n") at gdb/gdbserver/../common/errors.c:51 riscvarchive#1 0x0000000000424014 in lwp_suspended_decr (lwp=<optimised out>, lwp=<optimised out>) at gdb/gdbserver/linux-low.c:1922 riscvarchive#2 0x000000000042403a in unsuspend_one_lwp (entry=<optimised out>, except=0x66e8c0) at gdb/gdbserver/linux-low.c:2885 riscvarchive#3 0x0000000000405f45 in find_inferior (list=<optimised out>, func=func@entry=0x424020 <unsuspend_one_lwp>, arg=arg@entry=0x66e8c0) at gdb/gdbserver/inferiors.c:243 riscvarchive#4 0x00000000004297de in unsuspend_all_lwps (except=0x66e8c0) at gdb/gdbserver/linux-low.c:2895 riscvarchive#5 linux_wait_1 (ptid=..., ourstatus=ourstatus@entry=0x665ec0 <last_status>, target_options=target_options@entry=0) at gdb/gdbserver/linux-low.c:3632 riscvarchive#6 0x000000000042a764 in linux_wait (ptid=..., ourstatus=0x665ec0 <last_status>, target_options=0) at gdb/gdbserver/linux-low.c:3770 riscvarchive#7 0x0000000000411163 in mywait (ptid=..., ourstatus=ourstatus@entry=0x665ec0 <last_status>, options=options@entry=0, connected_wait=connected_wait@entry=1) at gdb/gdbserver/target.c:214 riscvarchive#8 0x000000000040b1f2 in resume (actions=0x66f800, num_actions=1) at gdb/gdbserver/server.c:2757 riscvarchive#9 0x000000000040f660 in handle_v_cont (own_buf=0x66a630 "vCont;c:p45e9.-1") at gdb/gdbserver/server.c:2719 when GDBserver steps over a thread, other threads have been suspended, the "stepping" thread may create new thread, but GDBserver doesn't set it suspend count to 1. When GDBserver unsuspend threads, the child's suspend count goes to -1, and the assert is triggered. In fact, GDBserver has already taken care of suspend count of new thread when GDBserver is suspending all threads except the one GDBserver wants to step over by https://sourceware.org/ml/gdb-patches/2015-07/msg00946.html + /* If we're suspending all threads, leave this one suspended + too. */ + if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS) + { + if (debug_threads) + debug_printf ("HEW: leaving child suspended\n"); + child_lwp->suspended = 1; + } but that is not enough, because new thread is still can be spawned in the thread which is being stepped over. This patch extends the condition that GDBserver set child's suspend count to one if it is suspending threads or stepping over the thread. gdb/gdbserver: 2016-03-03 Yao Qi <[email protected]> PR server/19736 * linux-low.c (handle_extended_wait): Set child suspended if event_lwp->bp_reinsert isn't zero.
zizztux
pushed a commit
to zizztux/riscv-binutils-gdb
that referenced
this pull request
Aug 11, 2016
Fix this GDB crash: $ gdb -ex "set architecture mips:10000" Segmentation fault (core dumped) Backtrace: Program received signal SIGSEGV, Segmentation fault. 0x0000000000495b1b in mips_gdbarch_init (info=..., arches=0x0) at /home/pedro/gdb/mygit/cxx-convertion/src/gdb/mips-tdep.c:8436 8436 if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour (top-gdb) bt #0 0x0000000000495b1b in mips_gdbarch_init (info=..., arches=0x0) at .../src/gdb/mips-tdep.c:8436 riscvarchive#1 0x00000000007348a6 in gdbarch_find_by_info (info=...) at .../src/gdb/gdbarch.c:5155 riscvarchive#2 0x000000000073563c in gdbarch_update_p (info=...) at .../src/gdb/arch-utils.c:522 riscvarchive#3 0x0000000000735585 in set_architecture (ignore_args=0x0, from_tty=1, c=0x26bc870) at .../src/gdb/arch-utils.c:496 riscvarchive#4 0x00000000005f29fd in do_sfunc (c=0x26bc870, args=0x0, from_tty=1) at .../src/gdb/cli/cli-decode.c:121 riscvarchive#5 0x00000000005fd3f3 in do_set_command (arg=0x7fffffffdcdd "mips:10000", from_tty=1, c=0x26bc870) at .../src/gdb/cli/cli-setshow.c:455 riscvarchive#6 0x0000000000836157 in execute_command (p=0x7fffffffdcdd "mips:10000", from_tty=1) at .../src/gdb/top.c:460 riscvarchive#7 0x000000000071abfb in catch_command_errors (command=0x835f6b <execute_command>, arg=0x7fffffffdccc "set architecture mips:10000", from_tty=1) at .../src/gdb/main.c:368 riscvarchive#8 0x000000000071bf4f in captured_main (data=0x7fffffffd750) at .../src/gdb/main.c:1132 riscvarchive#9 0x0000000000716737 in catch_errors (func=0x71af44 <captured_main>, func_args=0x7fffffffd750, errstring=0x106b9a1 "", mask=RETURN_MASK_ALL) at .../src/gdb/exceptions.c:240 riscvarchive#10 0x000000000071bfe6 in gdb_main (args=0x7fffffffd750) at .../src/gdb/main.c:1164 riscvarchive#11 0x000000000040a6ad in main (argc=4, argv=0x7fffffffd858) at .../src/gdb/gdb.c:32 (top-gdb) We already check whether info.abfd is NULL before all other bfd_get_flavour calls in the same function. Just this one case was missing. (This was exposed by a WIP test that tries all "set architecture ARCH" values.) gdb/ChangeLog: 2016-03-07 Pedro Alves <[email protected]> * mips-tdep.c (mips_gdbarch_init): Check whether info.abfd is NULL before calling bfd_get_flavour.
zizztux
pushed a commit
to zizztux/riscv-binutils-gdb
that referenced
this pull request
Aug 11, 2016
immediate_quit used to be necessary back when prompt_for_continue used blocking fread, but nowadays it uses gdb_readline_wrapper, which is implemented in terms of a nested event loop, which already knows how to react to SIGINT: #0 throw_it (reason=RETURN_QUIT, error=GDB_NO_ERROR, fmt=0x9d6d7e "Quit", ap=0x7fffffffcb88) at .../src/gdb/common/common-exceptions.c:324 riscvarchive#1 0x00000000007bab5d in throw_vquit (fmt=0x9d6d7e "Quit", ap=0x7fffffffcb88) at .../src/gdb/common/common-exceptions.c:366 riscvarchive#2 0x00000000007bac9f in throw_quit (fmt=0x9d6d7e "Quit") at .../src/gdb/common/common-exceptions.c:385 riscvarchive#3 0x0000000000773a2d in quit () at .../src/gdb/utils.c:1039 riscvarchive#4 0x000000000065d81b in async_request_quit (arg=0x0) at .../src/gdb/event-top.c:893 riscvarchive#5 0x000000000065c27b in invoke_async_signal_handlers () at .../src/gdb/event-loop.c:949 riscvarchive#6 0x000000000065aeef in gdb_do_one_event () at .../src/gdb/event-loop.c:280 riscvarchive#7 0x0000000000770838 in gdb_readline_wrapper (prompt=0x7fffffffcd40 "---Type <return> to continue, or q <return> to quit---") at .../src/gdb/top.c:873 The need for the QUIT in stdin_event_handler is then exposed by the gdb.base/double-prompt-target-event-error.exp test, which has: # We're now stopped in a pagination query while handling a # target event (printing where the program stopped). Quitting # the pagination should result in only one prompt being # output. send_gdb "\003p 1\n" Without that change we'd get: Continuing. ---Type <return> to continue, or q <return> to quit---PASS: gdb.base/double-prompt-target-event-error.exp: ctrlc target event: continue: continue to pagination ^CpQuit (gdb) 1 Undefined command: "1". Try "help". (gdb) PASS: gdb.base/double-prompt-target-event-error.exp: ctrlc target event: continue: first prompt ERROR: Undefined command "". UNRESOLVED: gdb.base/double-prompt-target-event-error.exp: ctrlc target event: continue: no double prompt Vs: Continuing. ---Type <return> to continue, or q <return> to quit---PASS: gdb.base/double-prompt-target-event-error.exp: ctrlc target event: continue: continue to pagination ^CQuit (gdb) p 1 $1 = 1 (gdb) PASS: gdb.base/double-prompt-target-event-error.exp: ctrlc target event: continue: first prompt PASS: gdb.base/double-prompt-target-event-error.exp: ctrlc target event: continue: no double prompt gdb/ChangeLog: 2016-04-12 Pedro Alves <[email protected]> * event-top.c (stdin_event_handler): Call QUIT; (prompt_for_continue): Don't run with immediate_quit set.
zizztux
pushed a commit
to zizztux/riscv-binutils-gdb
that referenced
this pull request
Aug 11, 2016
Nowadays, read_memory may throw NOT_AVAILABLE_ERROR (it is done by patch http://sourceware.org/ml/gdb-patches/2013-08/msg00625.html) however, read_stack and read_code still throws MEMORY_ERROR only. This causes PR 19947, that is prologue unwinder is unable unwind because code memory isn't available, but MEMORY_ERROR is thrown, while unwinder catches NOT_AVAILABLE_ERROR. #0 memory_error (err=err@entry=TARGET_XFER_E_IO, memaddr=memaddr@entry=140737349781158) at /home/yao/SourceCode/gnu/gdb/git/gdb/corefile.c:217 riscvarchive#1 0x000000000065f5ba in read_code (memaddr=memaddr@entry=140737349781158, myaddr=myaddr@entry=0x7fffffffd7b0 "\340\023<\001", len=len@entry=1) at /home/yao/SourceCode/gnu/gdb/git/gdb/corefile.c:288 riscvarchive#2 0x000000000065f7b5 in read_code_unsigned_integer (memaddr=memaddr@entry=140737349781158, len=len@entry=1, byte_order=byte_order@entry=BFD_ENDIAN_LITTLE) at /home/yao/SourceCode/gnu/gdb/git/gdb/corefile.c:363 riscvarchive#3 0x00000000004717e0 in amd64_analyze_prologue (gdbarch=gdbarch@entry=0x13c13e0, pc=140737349781158, current_pc=140737349781165, cache=cache@entry=0xda0cb0) at /home/yao/SourceCode/gnu/gdb/git/gdb/amd64-tdep.c:2267 riscvarchive#4 0x0000000000471f6d in amd64_frame_cache_1 (cache=0xda0cb0, this_frame=0xda0bf0) at /home/yao/SourceCode/gnu/gdb/git/gdb/amd64-tdep.c:2437 riscvarchive#5 amd64_frame_cache (this_frame=0xda0bf0, this_cache=<optimised out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/amd64-tdep.c:2508 riscvarchive#6 0x000000000047214d in amd64_frame_this_id (this_frame=<optimised out>, this_cache=<optimised out>, this_id=0xda0c50) at /home/yao/SourceCode/gnu/gdb/git/gdb/amd64-tdep.c:2541 riscvarchive#7 0x00000000006b94c4 in compute_frame_id (fi=0xda0bf0) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:481 riscvarchive#8 get_prev_frame_if_no_cycle (this_frame=this_frame@entry=0xda0b20) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1809 riscvarchive#9 0x00000000006bb6c9 in get_prev_frame_always_1 (this_frame=0xda0b20) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1983 riscvarchive#10 get_prev_frame_always (this_frame=this_frame@entry=0xda0b20) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1999 riscvarchive#11 0x00000000006bbe11 in get_prev_frame (this_frame=this_frame@entry=0xda0b20) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:2241 riscvarchive#12 0x00000000006bc13c in unwind_to_current_frame (ui_out=<optimised out>, args=args@entry=0xda0b20) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1485 The fix is to let read_stack and read_code throw NOT_AVAILABLE_ERROR too, in order to align with read_memory. gdb: 2016-05-04 Yao Qi <[email protected]> PR gdb/19947 * corefile.c (read_memory): Rename it to ... (read_memory_object): ... it. Add parameter object. (read_memory): Call read_memory_object. (read_stack): Likewise. (read_code): Likewise.
zizztux
pushed a commit
to zizztux/riscv-binutils-gdb
that referenced
this pull request
Aug 11, 2016
As reported in PR 19998, after type ctrl-c, GDB hang there and does not send interrupt. It causes a fail in gdb.base/interrupt.exp. All targets support remote fileio should be affected. When we type ctrc-c, SIGINT is handled by remote_fileio_sig_set, as shown below, #0 remote_fileio_sig_set (sigint_func=0x4495d0 <remote_fileio_ctrl_c_signal_handler(int)>) at /home/yao/SourceCode/gnu/gdb/git/gdb/remote-fileio.c:325 riscvarchive#1 0x00000000004495de in remote_fileio_ctrl_c_signal_handler (signo=<optimised out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/remote-fileio.c:349 riscvarchive#2 <signal handler called> riscvarchive#3 0x00007ffff647ed83 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:81 riscvarchive#4 0x00000000005530ce in interruptible_select (n=10, readfds=readfds@entry=0x7fffffffd730, writefds=writefds@entry=0x0, exceptfds=exceptfds@entry=0x0, timeout=timeout@entry=0x0) at /home/yao/SourceCode/gnu/gdb/git/gdb/event-top.c:1017 riscvarchive#5 0x000000000061ab20 in stdio_file_read (file=<optimised out>, buf=0x12d02e0 "\n\022-\001", length_buf=16383) at /home/yao/SourceCode/gnu/gdb/git/gdb/ui-file.c:577 riscvarchive#6 0x000000000044a4dc in remote_fileio_func_read (buf=0x12c0360 "") at /home/yao/SourceCode/gnu/gdb/git/gdb/remote-fileio.c:583 riscvarchive#7 0x0000000000449598 in do_remote_fileio_request (uiout=<optimised out>, buf_arg=buf_arg@entry=0x12c0340) at /home/yao/SourceCode/gnu/gdb/git/gdb/remote-fileio.c:1179 we don't set quit_serial_event, do { res = gdb_select (n, readfds, writefds, exceptfds, timeout); } while (res == -1 && errno == EINTR); if (res == 1 && FD_ISSET (fd, readfds)) { errno = EINTR; return -1; } return res; we can't go out of the loop above, and that is why GDB can't send interrupt. Recently, we stop throwing exception from SIGINT handler (remote_fileio_ctrl_c_signal_handler) https://sourceware.org/ml/gdb-patches/2016-03/msg00372.html, which is correct, because gdb_select is interruptible. However, in the same patch series, we add interruptible_select later as a wrapper to gdb_select, https://sourceware.org/ml/gdb-patches/2016-03/msg00375.html and it is not interruptible (because of the loop in it) unless select/poll-able file descriptors are marked. This fix in this patch is to call quit_serial_event_set, so that we can go out of the loop above, return -1 and set errno to EINTR. 2016-06-01 Yao Qi <[email protected]> PR remote/19998 * remote-fileio.c (remote_fileio_ctrl_c_signal_handler): Call quit_serial_event_set.
zizztux
pushed a commit
to zizztux/riscv-binutils-gdb
that referenced
this pull request
Aug 11, 2016
This patch adds some sanity check that reinsert breakpoints must be there when doing step-over on software single step target. The check triggers an assert when running forking-threads-plus-breakpoint.exp on arm-linux target, gdb/gdbserver/linux-low.c:4714: A problem internal to GDBserver has been detected.^M int finish_step_over(lwp_info*): Assertion `has_reinsert_breakpoints ()' failed. the error happens when GDBserver has already resumed a thread of process A for step-over (and wait for it hitting reinsert breakpoint), but receives detach request for process B from GDB, which is shown in the backtrace below, (gdb) bt riscvarchive#2 0x000228aa in finish_step_over (lwp=0x12bbd98) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4703 riscvarchive#3 0x00025a50 in finish_step_over (lwp=0x12bbd98) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4749 riscvarchive#4 complete_ongoing_step_over () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4760 riscvarchive#5 linux_detach (pid=25228) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:1503 riscvarchive#6 0x00012bae in process_serial_event () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3974 riscvarchive#7 handle_serial_event (err=<optimized out>, client_data=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:4347 riscvarchive#8 0x00016d68 in handle_file_event (event_file_desc=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:429 riscvarchive#9 0x000173ea in process_event () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:184 riscvarchive#10 start_event_loop () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:547 riscvarchive#11 0x0000aa2c in captured_main (argv=<optimized out>, argc=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3719 riscvarchive#12 main (argc=<optimized out>, argv=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3804 the sanity check tries to find the reinsert breakpoint from process B, but nothing is found. It is wrong, we need to search in process A, since we started step-over of a thread of process A. (gdb) p lwp->thread->entry.id $3 = {pid = 25120, lwp = 25131, tid = 0} (gdb) p current_thread->entry.id $4 = {pid = 25228, lwp = 25228, tid = 0} This patch switched current_thread to the thread we are doing step-over in finish_step_over. gdb/gdbserver: 2016-06-17 Yao Qi <[email protected]> * linux-low.c (maybe_hw_step): New function. (linux_resume_one_lwp_throw): Call maybe_hw_step. (finish_step_over): Switch current_thread to lwp temporarily, and assert has_reinsert_breakpoints returns true. (proceed_one_lwp): Call maybe_hw_step. * mem-break.c (has_reinsert_breakpoints): New function. * mem-break.h (has_reinsert_breakpoints): Declare.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Oct 10, 2016
When I run process-dies-while-detaching.exp with GDBserver, I see many warnings printed by GDBserver, ptrace(regsets_fetch_inferior_registers) PID=26183: No such process ptrace(regsets_fetch_inferior_registers) PID=26183: No such process ptrace(regsets_fetch_inferior_registers) PID=26184: No such process ptrace(regsets_fetch_inferior_registers) PID=26184: No such process regsets_fetch_inferior_registers is called when GDBserver resumes each lwp. #2 0x0000000000428260 in regsets_fetch_inferior_registers (regsets_info=0x4690d0 <aarch64_regsets_info>, regcache=0x31832020) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:5412 #3 0x00000000004070e8 in get_thread_regcache (thread=0x31832940, fetch=fetch@entry=1) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/regcache.c:58 #4 0x0000000000429c40 in linux_resume_one_lwp_throw (info=<optimized out>, signal=0, step=0, lwp=0x31832830) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4463 #5 linux_resume_one_lwp (lwp=0x31832830, step=<optimized out>, signal=<optimized out>, info=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4573 The is the case that threads are disappeared when GDB/GDBserver resumes them. We check errno for ESRCH, and don't print error messages, like what we are doing in regsets_store_inferior_registers. gdb/gdbserver: 2016-08-04 Yao Qi <[email protected]> * linux-low.c (regsets_fetch_inferior_registers): Check errno is ESRCH or not.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Oct 10, 2016
… out value With something like: struct A { int bitfield:4; } var; If 'var' ends up wholly-optimized out, printing 'var.bitfield' crashes gdb here: (top-gdb) bt #0 0x000000000058b89f in extract_unsigned_integer (addr=0x2 <error: Cannot access memory at address 0x2>, len=2, byte_order=BFD_ENDIAN_LITTLE) at /home/pedro/gdb/mygit/src/gdb/findvar.c:109 #1 0x00000000005a187a in unpack_bits_as_long (field_type=0x16cff70, valaddr=0x0, bitpos=16, bitsize=12) at /home/pedro/gdb/mygit/src/gdb/value.c:3347 #2 0x00000000005a1b9d in unpack_value_bitfield (dest_val=0x1b5d9d0, bitpos=16, bitsize=12, valaddr=0x0, embedded_offset=0, val=0x1b5d8d0) at /home/pedro/gdb/mygit/src/gdb/value.c:3441 #3 0x00000000005a2a5f in value_fetch_lazy (val=0x1b5d9d0) at /home/pedro/gdb/mygit/src/gdb/value.c:3958 #4 0x00000000005a10a7 in value_primitive_field (arg1=0x1b5d8d0, offset=0, fieldno=0, arg_type=0x16d04c0) at /home/pedro/gdb/mygit/src/gdb/value.c:3161 #5 0x00000000005b01e5 in do_search_struct_field (name=0x1727c60 "bitfield", arg1=0x1b5d8d0, offset=0, type=0x16d04c0, looking_for_baseclass=0, result_ptr=0x7fffffffcaf8, [...] unpack_value_bitfield is already optimized-out/unavailable -aware: (...) VALADDR points to the contents of VAL. If the VAL's contents required to extract the bitfield from are unavailable/optimized out, DEST_VAL is correspondingly marked unavailable/optimized out. however, it is not considering the case of the value having no contents buffer at all, as can happen through allocate_optimized_out_value. gdb/ChangeLog: 2016-08-09 Pedro Alves <[email protected]> * value.c (unpack_value_bitfield): Skip unpacking if the parent has no contents buffer to begin with. gdb/testsuite/ChangeLog: 2016-08-09 Pedro Alves <[email protected]> * gdb.dwarf2/bitfield-parent-optimized-out.exp: New file.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Oct 10, 2016
If I build gdb with -fsanitize=address and run tests, I get error, malformed linespec error: unexpected colon^M (gdb) PASS: gdb.linespec/ls-errs.exp: lang=C: break : break :=================================================================^M ==3266==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000051451 at pc 0x2b5797a972a8 bp 0x7fffd8e0f3c0 sp 0x7fffd8e0f398^M READ of size 2 at 0x602000051451 thread T0 #0 0x2b5797a972a7 in __interceptor_strlen (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x322a7)^M #1 0x7bd004 in compare_filenames_for_search(char const*, char const*) /home/yao/SourceCode/gnu/gdb/git/gdb/symtab.c:316^M #2 0x7bd310 in iterate_over_some_symtabs(char const*, char const*, int (*)(symtab*, void*), void*, compunit_symtab*, compunit_symtab*) /home/yao/SourceCode/gnu/gdb/git/gdb/symtab.c:411^M #3 0x7bd775 in iterate_over_symtabs(char const*, int (*)(symtab*, void*), void*) /home/yao/SourceCode/gnu/gdb/git/gdb/symtab.c:481^M #4 0x7bda15 in lookup_symtab(char const*) /home/yao/SourceCode/gnu/gdb/git/gdb/symtab.c:527^M #5 0x7d5e2a in make_file_symbol_completion_list_1 /home/yao/SourceCode/gnu/gdb/git/gdb/symtab.c:5635^M #6 0x7d61e1 in make_file_symbol_completion_list(char const*, char const*, char const*) /home/yao/SourceCode/gnu/gdb/git/gdb/symtab.c:5684^M #7 0x88dc06 in linespec_location_completer /home/yao/SourceCode/gnu/gdb/git/gdb/completer.c:288 .... 0x602000051451 is located 0 bytes to the right of 1-byte region [0x602000051450,0x602000051451)^M mallocated by thread T0 here: #0 0x2b5797ab97ef in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x547ef)^M #1 0xbbfb8d in xmalloc /home/yao/SourceCode/gnu/gdb/git/gdb/common/common-utils.c:43^M #2 0x88dabd in linespec_location_completer /home/yao/SourceCode/gnu/gdb/git/gdb/completer.c:273^M #3 0x88e5ef in location_completer(cmd_list_element*, char const*, char const*) /home/yao/SourceCode/gnu/gdb/git/gdb/completer.c:531^M #4 0x8902e7 in complete_line_internal /home/yao/SourceCode/gnu/gdb/git/gdb/completer.c:964^ The code in question is here file_to_match = (char *) xmalloc (colon - text + 1); strncpy (file_to_match, text, colon - text + 1); it is likely that file_to_match is not null-terminated. The patch is to strncpy 'colon - text' bytes and explicitly set '\0'. gdb: 2016-08-19 Yao Qi <[email protected]> * completer.c (linespec_location_completer): Make file_to_match null-terminated.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Oct 10, 2016
This test case verifies that GDB will not attempt to invoke a python unwinder recursively. At the moment, the behavior exhibited by GDB looks like this: (gdb) source py-recurse-unwind.py Python script imported (gdb) b ccc Breakpoint 1 at 0x4004bd: file py-recurse-unwind.c, line 23. (gdb) run Starting program: py-recurse-unwind TestUnwinder: Recursion detected - returning early. TestUnwinder: Recursion detected - returning early. TestUnwinder: Recursion detected - returning early. TestUnwinder: Recursion detected - returning early. Breakpoint 1, ccc (arg=<unavailable>) at py-recurse-unwind.c:23 23 } (gdb) bt #-1 ccc (arg=<unavailable>) at py-recurse-unwind.c:23 Backtrace stopped: previous frame identical to this frame (corrupt stack?) [I've shortened pathnames for easier reading.] The desired / expected behavior looks like this: (gdb) source py-recurse-unwind.py Python script imported (gdb) b ccc Breakpoint 1 at 0x4004bd: file py-recurse-unwind.c, line 23. (gdb) run Starting program: py-recurse-unwind Breakpoint 1, ccc (arg=789) at py-recurse-unwind.c:23 23 } (gdb) bt #0 ccc (arg=789) at py-recurse-unwind.c:23 #1 0x00000000004004d5 in bbb (arg=456) at py-recurse-unwind.c:28 #2 0x00000000004004ed in aaa (arg=123) at py-recurse-unwind.c:34 #3 0x00000000004004fe in main () at py-recurse-unwind.c:40 Note that GDB's problems go well beyond the fact that it invokes the unwinder recursively. In the process it messes up some internal state (the frame stash) leading to display of (only) the sentinel frame in the backtrace. gdb/testsuite/ChangeLog: * gdb.python/py-recurse-unwind.c: New file. * gdb.python/py-recurse-unwind.py: New file. * gdb.python/py-recurse-unwind.exp: New file.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Oct 11, 2016
Even though this was supposedly in the gdb 7.2 timeframe, the testcase in PR11094 crashes current GDB with a segfault: Program received signal SIGSEGV, Segmentation fault. 0x00000000005ee894 in event_location_to_string (location=0x0) at src/gdb/location.c:412 412 if (EL_STRING (location) == NULL) (top-gdb) bt #0 0x00000000005ee894 in event_location_to_string (location=0x0) at src/gdb/location.c:412 #1 0x000000000057411a in print_breakpoint_location (b=0x18288e0, loc=0x0) at src/gdb/breakpoint.c:6201 #2 0x000000000057483f in print_one_breakpoint_location (b=0x18288e0, loc=0x182cf10, loc_number=0, last_loc=0x7fffffffd258, allflag=1) at src/gdb/breakpoint.c:6473 #3 0x00000000005751e1 in print_one_breakpoint (b=0x18288e0, last_loc=0x7fffffffd258, allflag=1) at src/gdb/breakpoint.c:6707 #4 0x000000000057589c in breakpoint_1 (args=0x0, allflag=1, filter=0x0) at src/gdb/breakpoint.c:6947 #5 0x0000000000575aa8 in maintenance_info_breakpoints (args=0x0, from_tty=0) at src/gdb/breakpoint.c:7026 [...] This is GDB trying to print the location spec of the JIT event breakpoint, but that's an internal breakpoint without one. If I add a NULL check, then we see that the JIT breakpoint is now pending (because its location has shlib_disabled set): (gdb) maint info breakpoints Num Type Disp Enb Address What [...] -8 jit events keep y <PENDING> inf 1 [...] But that's incorrect. GDB should have managed to recreate the JIT breakpoint's location for the second run. So the problem is elsewhere. The problem is that if the JIT loads at the same address on the second run, we never recreate the JIT breakpoint, because we hit this early return: static int jit_breakpoint_re_set_internal (struct gdbarch *gdbarch, struct jit_program_space_data *ps_data) { [...] if (ps_data->cached_code_address == addr) return 0; [...] delete_breakpoint (ps_data->jit_breakpoint); [...] ps_data->jit_breakpoint = create_jit_event_breakpoint (gdbarch, addr); Fix this by deleting the breakpoint and discarding the cached code address when the objfile where the previous JIT breakpoint was found is deleted/unloaded in the first place. The test that was originally added for PR11094 doesn't trip on this because: #1 - It doesn't test the case of the JIT descriptor's address _not_ changing between reruns. #2 - And then it doesn't do "maint info breakpoints", or really anything with the JIT at all. #3 - and even then, to trigger the problem the JIT descriptor needs to be in a separate library, while the current test puts it in the main program. The patch extends the test to cover all combinations of these scenarios. gdb/ChangeLog: 2016-10-06 Pedro Alves <[email protected]> * jit.c (free_objfile_data): Delete the JIT breakpoint and clear the cached code address. gdb/testsuite/ChangeLog: 2016-10-06 Pedro Alves <[email protected]> * gdb.base/jit-simple-dl.c: New file. * gdb.base/jit-simple-jit.c: New file, factored out from ... * gdb.base/jit-simple.c: ... this. * gdb.base/jit-simple.exp (jit_run): Delete. (build_jit): New proc. (jit_test_reread): Recompile either the main program or the shared library, depending on what is being tested. Skip changing address if caller wants to. Compare before/after addresses. If testing standalone, explicitly load the binary. Test "maint info breakpoints". (top level): Add "standalone vs shared lib" and "change address" vs "same address" axes.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Nov 1, 2016
Nowadays, if we build GDB with -fsanitize=address, we can get the asan error below, (gdb) quit ================================================================= ==9723==ERROR: AddressSanitizer: alloc-dealloc-mismatch (malloc vs operator delete) on 0x60200003bf70 #0 0x7f88f3837527 in operator delete(void*) (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x55527) #1 0xac8e13 in __gnu_cxx::new_allocator<void (*)()>::deallocate(void (**)(), unsigned long) /usr/include/c++/4.9/ext/new_allocator.h:110 #2 0xac8cc2 in __gnu_cxx::__alloc_traits<std::allocator<void (*)()> >::deallocate(std::allocator<void (*)()>&, void (**)(), unsigned long) /usr/include/c++/4.9/ext/alloc_traits.h:185 .... 0x60200003bf70 is located 0 bytes inside of 8-byte region [0x60200003bf70,0x60200003bf78) allocated by thread T0 here: #0 0x7f88f38367ef in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x547ef) #1 0xbd2762 in operator new(unsigned long) /home/yao/SourceCode/gnu/gdb/git/gdb/common/new-op.c:42 #2 0xac8edc in __gnu_cxx::new_allocator<void (*)()>::allocate(unsigned long, void const*) /usr/include/c++/4.9/ext/new_allocator.h:104 #3 0xac8d81 in __gnu_cxx::__alloc_traits<std::allocator<void (*)()> >::allocate(std::allocator<void (*)()>&, unsigned long) /usr/include/c++/4.9/ext/alloc_traits.h:182 The reason for this is that we override operator new but don't override operator delete. This patch does the override if the code is NOT compiled with asan. gdb: 2016-10-25 Yao Qi <[email protected]> PR gdb/20716 * common/new-op.c (__has_feature): New macro. Don't override operator new if asan is used.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Nov 1, 2016
Currently GDB never sends more than one action per vCont packet, when connected in non-stop mode. A follow up patch will change that, and it exposed a gdbserver problem with the vCont handling. For example, this in non-stop mode: => vCont;s:p1.1;c <= OK Should be equivalent to: => vCont;s:p1.1 <= OK => vCont;c <= OK But gdbserver currently doesn't handle this. In the latter case, "vCont;c" makes gdbserver clobber the previous step request. This patch fixes that. Note the server side must ignore resume actions for the thread that has a pending %Stopped notification (and any other threads with events pending), until GDB acks the notification with vStopped. Otherwise, e.g., the following case is mishandled: #1 => g (or any other packet) #2 <= [registers] #3 <= %Stopped T05 thread:p1.2 #4 => vCont s:p1.1;c #5 <= OK Above, the server must not resume thread p1.2 when it processes the vCont. GDB can't know that p1.2 stopped until it acks the %Stopped notification. (Otherwise it wouldn't send a default "c" action.) (The vCont documentation already specifies this.) Finally, special care must also be given to handling fork/vfork events. A (v)fork event actually tells us that two processes stopped -- the parent and the child. Until we follow the fork, we must not resume the child. Therefore, if we have a pending fork follow, we must not send a global wildcard resume action (vCont;c). We can still send process-wide wildcards though. (The comments above will be added as code comments to gdb in a follow up patch.) gdb/gdbserver/ChangeLog: 2016-10-26 Pedro Alves <[email protected]> * linux-low.c (handle_extended_wait): Link parent/child fork threads. (linux_wait_1): Unlink them. (linux_set_resume_request): Ignore resume requests for already-resumed and unhandled fork child threads. * linux-low.h (struct lwp_info) <fork_relative>: New field. * server.c (in_queued_stop_replies_ptid, in_queued_stop_replies): New functions. (handle_v_requests) <vCont>: Don't call require_running. * server.h (in_queued_stop_replies): New declaration.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Nov 1, 2016
Most of the time, the trace should be in one piece. This case is handled fine by GDB. In some cases, however, there may be gaps in the trace. They result from trace decode errors or from overflows. A gap in the trace means we lost an unknown amount of trace. Gaps can be very small, such as a few instructions in the same function, or they can be rather big. We may, for example, lose a few function calls or returns. The trace may continue in a different function and we likely don't know how we got there. Even though we can't say how the program executed across a gap, higher levels may not be impacted too much by it. Let's assume we have functions a-e and a trace that looks roughly like this: a \ b b \ / c <gap> c / d d \ / e Even though we can't say for sure, it is likely that b and c are the same function instance before and after the gap. This patch is trying to connect the c and b function segments across the gap. This will add a to the back trace of b on the right hand side. The changes are reflected in GDB's internal representation of the trace and will improve: - the output of "record function-call-history /c" - the output of "backtrace" in replay mode - source stepping in replay mode will be improved indirectly via the improved back trace I don't have an automated test for this patch; decode errors will be fixed and overflows occur sporadically and are quite rare. I tested it by hacking GDB to provoke a decode error and on the expected gap in the gdb.btrace/dlopen.exp test. The issue is that we can't predict where we will be able to re-sync in case of errors. For the expected decode error in gdb.btrace/dlopen.exp, for example, we may be able to re-sync somewhere in dlclose, in test, in main, or not at all. Here's one example run of gdb.btrace/dlopen.exp with and without this patch. (gdb) info record Active record target: record-btrace Recording format: Intel Processor Trace. Buffer size: 16kB. warning: Non-contiguous trace at instruction 66608 (offset = 0xa83, pc = 0xb7fdcc31). warning: Non-contiguous trace at instruction 66652 (offset = 0xa9b, pc = 0xb7fdcc31). warning: Non-contiguous trace at instruction 66770 (offset = 0xacb, pc = 0xb7fdcc31). warning: Non-contiguous trace at instruction 66966 (offset = 0xb60, pc = 0xb7ff5ee4). warning: Non-contiguous trace at instruction 66994 (offset = 0xb74, pc = 0xb7ff5f24). warning: Non-contiguous trace at instruction 67334 (offset = 0xbac, pc = 0xb7ff5e6d). warning: Non-contiguous trace at instruction 69022 (offset = 0xc04, pc = 0xb7ff60b3). warning: Non-contiguous trace at instruction 69116 (offset = 0xc1c, pc = 0xb7ff60b3). warning: Non-contiguous trace at instruction 69504 (offset = 0xc74, pc = 0xb7ff605d). warning: Non-contiguous trace at instruction 83648 (offset = 0xecc, pc = 0xb7ff6134). warning: Decode error (-13) at instruction 83876 (offset = 0xf48, pc = 0xb7fd6380): no memory mapped at this address. warning: Non-contiguous trace at instruction 83876 (offset = 0x11b7, pc = 0xb7ff1c70). Recorded 83948 instructions in 912 functions (12 gaps) for thread 1 (process 12996). (gdb) record instruction-history 83876, +2 83876 => 0xb7fec46f <call_init.part.0+95>: call *%eax [decode error (-13): no memory mapped at this address] [disabled] 83877 0xb7ff1c70 <_dl_close_worker.part.0+1584>: nop Without the patch, the trace is disconnected and the backtrace is short: (gdb) record goto 83876 #0 0xb7fec46f in call_init.part () from /lib/ld-linux.so.2 (gdb) backtrace #0 0xb7fec46f in call_init.part () from /lib/ld-linux.so.2 #1 0xb7fec5d0 in _dl_init () from /lib/ld-linux.so.2 #2 0xb7ff0fe3 in dl_open_worker () from /lib/ld-linux.so.2 Backtrace stopped: not enough registers or memory available to unwind further (gdb) record goto 83877 #0 0xb7ff1c70 in _dl_close_worker.part.0 () from /lib/ld-linux.so.2 (gdb) backtrace #0 0xb7ff1c70 in _dl_close_worker.part.0 () from /lib/ld-linux.so.2 #1 0xb7ff287a in _dl_close () from /lib/ld-linux.so.2 #2 0xb7fc3d5d in dlclose_doit () from /lib/libdl.so.2 #3 0xb7fec354 in _dl_catch_error () from /lib/ld-linux.so.2 #4 0xb7fc43dd in _dlerror_run () from /lib/libdl.so.2 #5 0xb7fc3d98 in dlclose () from /lib/libdl.so.2 #6 0x0804860a in test () #7 0x08048628 in main () With the patch, GDB is able to connect the trace pieces and we get a full backtrace. (gdb) record goto 83876 #0 0xb7fec46f in call_init.part () from /lib/ld-linux.so.2 (gdb) backtrace #0 0xb7fec46f in call_init.part () from /lib/ld-linux.so.2 #1 0xb7fec5d0 in _dl_init () from /lib/ld-linux.so.2 #2 0xb7ff0fe3 in dl_open_worker () from /lib/ld-linux.so.2 #3 0xb7fec354 in _dl_catch_error () from /lib/ld-linux.so.2 #4 0xb7ff02e2 in _dl_open () from /lib/ld-linux.so.2 #5 0xb7fc3c65 in dlopen_doit () from /lib/libdl.so.2 #6 0xb7fec354 in _dl_catch_error () from /lib/ld-linux.so.2 #7 0xb7fc43dd in _dlerror_run () from /lib/libdl.so.2 #8 0xb7fc3d0e in dlopen@@GLIBC_2.1 () from /lib/libdl.so.2 #9 0xb7ff28ee in _dl_runtime_resolve () from /lib/ld-linux.so.2 #10 0x0804841c in ?? () #11 0x08048470 in dlopen@plt () #12 0x080485a3 in test () #13 0x08048628 in main () (gdb) record goto 83877 #0 0xb7ff1c70 in _dl_close_worker.part.0 () from /lib/ld-linux.so.2 (gdb) backtrace #0 0xb7ff1c70 in _dl_close_worker.part.0 () from /lib/ld-linux.so.2 #1 0xb7ff287a in _dl_close () from /lib/ld-linux.so.2 #2 0xb7fc3d5d in dlclose_doit () from /lib/libdl.so.2 #3 0xb7fec354 in _dl_catch_error () from /lib/ld-linux.so.2 #4 0xb7fc43dd in _dlerror_run () from /lib/libdl.so.2 #5 0xb7fc3d98 in dlclose () from /lib/libdl.so.2 #6 0x0804860a in test () #7 0x08048628 in main () It worked nicely in this case but it may, of course, also lead to weird connections; it is a heuristic, after all. It works best when the gap is small and the trace pieces are long. gdb/ * btrace.c (bfun_s): New typedef. (ftrace_update_caller): Print caller in debug dump. (ftrace_get_caller, ftrace_match_backtrace, ftrace_fixup_level) (ftrace_compute_global_level_offset, ftrace_connect_bfun) (ftrace_connect_backtrace, ftrace_bridge_gap, btrace_bridge_gaps): New. (btrace_compute_ftrace_bts): Pass vector of gaps. Collect gaps. (btrace_compute_ftrace_pt): Likewise. (btrace_compute_ftrace): Split into this, ... (btrace_compute_ftrace_1): ... this, and ... (btrace_finalize_ftrace): ... this. Call btrace_bridge_gaps.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Nov 1, 2016
…event The tail end of linux_wait_1 isn't expecting that the select_event_lwp machinery can pick a whole-process exit event to report to GDB. When that happens, both gdb and gdbserver end up quite confused: ... (gdb) [Thread 24971.24971] #1 stopped. 0x0000003615a011f0 in ?? () c& Continuing. (gdb) [New Thread 24971.24981] [New Thread 24983.24983] [New Thread 24971.24982] [Thread 24983.24983] #3 stopped. 0x0000003615ebc7cc in __libc_fork () at ../nptl/sysdeps/unix/sysv/linux/fork.c:130 130 pid = ARCH_FORK (); [New Thread 24984.24984] Error in re-setting breakpoint -16: PC register is not available Error in re-setting breakpoint -17: PC register is not available Error in re-setting breakpoint -18: PC register is not available Error in re-setting breakpoint -19: PC register is not available Error in re-setting breakpoint -24: PC register is not available Error in re-setting breakpoint -25: PC register is not available Error in re-setting breakpoint -26: PC register is not available Error in re-setting breakpoint -27: PC register is not available Error in re-setting breakpoint -28: PC register is not available Error in re-setting breakpoint -29: PC register is not available Error in re-setting breakpoint -30: PC register is not available PC register is not available (gdb) gdb/gdbserver/ChangeLog: 2015-08-06 Pedro Alves <[email protected]> * linux-low.c (add_lwp): Set waitstatus to TARGET_WAITKIND_IGNORE. (linux_thread_alive): Use lwp_is_marked_dead. (extended_event_reported): Delete. (linux_wait_1): Check if waitstatus is TARGET_WAITKIND_IGNORE instead of extended_event_reported. (mark_lwp_dead): Don't set the 'dead' flag. Store the waitstatus as well. (lwp_is_marked_dead): New function. (lwp_running): Use lwp_is_marked_dead. * linux-low.h: Delete 'dead' field, and update 'waitstatus's comment.
palmer-dabbelt
pushed a commit
that referenced
this pull request
Nov 1, 2016
Making all-stop run on top of non-stop caused a small regression in behavior. This was observed on x86_64-linux. The attached testcase is in C whereas the investigation was done with an Ada program, but it's the same scenario, and using a C testcase allows wider testing. Basically: I am debugging a single-threaded program, and currently stopped inside a function provided by a shared-library, at a line calling a subprogram provided by a second shared library, and trying to "next" over that function call. Before we changed the default all-stop behavior, we had: 7 Impl_Initialize; -- Stop here and try "next" over this line (gdb) n 8 return 5; <<-- OK But now, "next" just stops much earlier: (gdb) n 0x00007ffff7bd8560 in impl.initialize@plt () from /[...]/lib/libpck.so What happens is that next stops at a call instruction, which calls the function's PLT, and GDB fails to notice that the inferior stepped into a subroutine, and so decides that we're done. We can see another symptom of the same issue by looking at the backtrace at the point GDB stopped: (gdb) bt #0 0x00007ffff7bd8560 in impl.initialize@plt () from /[...]/lib/libpck.so #1 0x00000000f7bd86f9 in ?? () #2 0x00007fffffffdf50 in ?? () #3 0x0000000000401893 in a () at /[...]/a.adb:7 Backtrace stopped: frame did not save the PC With a functioning GDB, the backtrace looks like the following instead: #0 0x00007ffff7bd8560 in impl.initialize@plt () from /[...]/lib/libpck.so #1 0x00007ffff7bd86f9 in sub () at /[...]/pck.adb:7 #2 0x0000000000401893 in a () at /[...]/a.adb:7 Note how, for frame #1, the address looks quite similar, except for the high-order bits not being set: #1 0x00007ffff7bd86f9 in sub () at /[...]/pck.adb:7 <<<-- OK #1 0x00000000f7bd86f9 in ?? () <<<-- WRONG ^^^^ |||| Wrong Investigating this further led me to displaced stepping. As we are "next"-ing from a location where a breakpoint is inserted, we need to step out of it, and since we're on non-stop mode, we need to do it using displaced stepping. And looking at amd64-tdep.c:amd64_displaced_step_fixup, I found the code that handles the return address: regcache_cooked_read_unsigned (regs, AMD64_RSP_REGNUM, &rsp); retaddr = read_memory_unsigned_integer (rsp, retaddr_len, byte_order); retaddr = (retaddr - insn_offset) & 0xffffffffUL; The mask used to compute retaddr looks wrong to me, keeping only 4 bytes instead of 8, and explains why the high order bits of the backtrace are unset. What happens is that, after the displaced stepping has completed, GDB restores that return address at the location where the program expects it. But because the top half bits of the address have been masked out, the return address is now invalid. The incorrect behavior of the "next" command and the backtrace at that location are the first symptoms of that. Another symptom is that this actually alters the behavior of the program, where a "cont" from there soon leads to a SEGV when the inferior tries to jump back to that incorrect return address: (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x00000000f7bd86f9 in ?? () ^^^^^^^^^^^^^^^^^^ This patch fixes the issue by using a mask that seems more appropriate for this architecture. gdb/ChangeLog: * amd64-tdep.c (amd64_displaced_step_fixup): Fix the mask used to compute RETADDR. gdb/testsuite/ChangeLog: * gdb.base/dso2dso-dso2.c, gdb.base/dso2dso-dso2.h, gdb.base/dso2dso-dso1.c, gdb.base/dso2dso-dso1.h, gdb.base/dso2dso.c, gdb.base/dso2dso.exp: New files. Tested on x86_64-linux, no regression.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Mar 5, 2021
When running test-case gdb.arch/i386-gnu-cfi.exp with target board unix/-m32, I get: ... (gdb) up 3^M 79 abort.c: No such file or directory.^M (gdb) FAIL: gdb.arch/i386-gnu-cfi.exp: shift up to the modified frame ... The preceding backtrace looks like this: ... (gdb) bt^M #0 0xf7fcf549 in __kernel_vsyscall ()^M riscvarchive#1 0xf7ce8896 in __libc_signal_restore_set (set=0xffffc3bc) at \ ../sysdeps/unix/sysv/linux/internal-signals.h:104^M riscvarchive#2 __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:47^M riscvarchive#3 0xf7cd0314 in __GI_abort () at abort.c:79^M riscvarchive#4 0x0804919f in gate (gate=0x8049040 <abort@plt>, data=0x0) at gate.c:3^M riscvarchive#5 0x08049176 in main () at i386-gnu-cfi.c:27^M ... with function gate at position riscvarchive#4, while on another system where the test passes, I see instead function gate at position riscvarchive#3. Fix this by capturing the position of function gate in the backtrace, and using that in the rest of the test instead of hardcoded constant 3. Tested on x86_64-linux. gdb/testsuite/ChangeLog: 2021-01-28 Tom de Vries <[email protected]> * gdb.arch/i386-gnu-cfi.exp: Capture the position of function gate in the backtrace, and use that in the rest of the test instead of hardcoded constant 3. Use "frame" instead of "up" for robustness.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Mar 5, 2021
With "target extended-remote" + "maint set target-non-stop", attaching hangs like so: (gdb) attach 1244450 Attaching to process 1244450 [New Thread 1244450.1244450] [New Thread 1244450.1244453] [New Thread 1244450.1244454] [New Thread 1244450.1244455] [New Thread 1244450.1244456] [New Thread 1244450.1244457] [New Thread 1244450.1244458] [New Thread 1244450.1244459] [New Thread 1244450.1244461] [New Thread 1244450.1244462] [New Thread 1244450.1244463] * hang * Attaching to the hung GDB shows that GDB is busy in an infinite loop in stop_all_threads: (top-gdb) bt #0 stop_all_threads () at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:4755 riscvarchive#1 0x000055555597b424 in stop_waiting (ecs=0x7fffffffd930) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:7738 riscvarchive#2 0x0000555555976fba in handle_signal_stop (ecs=0x7fffffffd930) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:5868 riscvarchive#3 0x0000555555975f6a in handle_inferior_event (ecs=0x7fffffffd930) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:5527 riscvarchive#4 0x0000555555971da4 in fetch_inferior_event () at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:3910 riscvarchive#5 0x00005555559540b2 in inferior_event_handler (event_type=INF_REG_EVENT) at /home/pedro/gdb/binutils-gdb/src/gdb/inf-loop.c:42 riscvarchive#6 0x000055555597e825 in infrun_async_inferior_event_handler (data=0x0) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:9162 riscvarchive#7 0x0000555555687d1d in check_async_event_handlers () at /home/pedro/gdb/binutils-gdb/src/gdb/async-event.c:328 riscvarchive#8 0x0000555555e48284 in gdb_do_one_event () at /home/pedro/gdb/binutils-gdb/src/gdbsupport/event-loop.cc:216 riscvarchive#9 0x00005555559e7512 in start_event_loop () at /home/pedro/gdb/binutils-gdb/src/gdb/main.c:347 riscvarchive#10 0x00005555559e765d in captured_command_loop () at /home/pedro/gdb/binutils-gdb/src/gdb/main.c:407 riscvarchive#11 0x00005555559e8f80 in captured_main (data=0x7fffffffdb70) at /home/pedro/gdb/binutils-gdb/src/gdb/main.c:1239 riscvarchive#12 0x00005555559e8ff2 in gdb_main (args=0x7fffffffdb70) at /home/pedro/gdb/binutils-gdb/src/gdb/main.c:1254 riscvarchive#13 0x0000555555627c86 in main (argc=12, argv=0x7fffffffdc88) at /home/pedro/gdb/binutils-gdb/src/gdb/gdb.c:32 The problem is that the remote sends stops for all the threads: Packet received: l/home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.threads/attach-non-stop/attach-non-stop Sending packet: $vStopped#55...Packet received: T0006:f06e25edec7f0000;07:f06e25edec7f0000;10:f14190ccf4550000;thread:p12fd22.12fd2f;core:15; Sending packet: $vStopped#55...Packet received: T0006:f0dea5f0ec7f0000;07:f0dea5f0ec7f0000;10:e84190ccf4550000;thread:p12fd22.12fd27;core:4; Sending packet: $vStopped#55...Packet received: T0006:f0ee25f1ec7f0000;07:f0ee25f1ec7f0000;10:f14190ccf4550000;thread:p12fd22.12fd26;core:5; Sending packet: $vStopped#55...Packet received: T0006:f0bea5efec7f0000;07:f0bea5efec7f0000;10:f14190ccf4550000;thread:p12fd22.12fd29;core:1; Sending packet: $vStopped#55...Packet received: T0006:f0ce25f0ec7f0000;07:f0ce25f0ec7f0000;10:e84190ccf4550000;thread:p12fd22.12fd28;core:a; Sending packet: $vStopped#55...Packet received: T0006:f07ea5edec7f0000;07:f07ea5edec7f0000;10:e84190ccf4550000;thread:p12fd22.12fd2e;core:f; Sending packet: $vStopped#55...Packet received: T0006:f0ae25efec7f0000;07:f0ae25efec7f0000;10:df4190ccf4550000;thread:p12fd22.12fd2a;core:6; Sending packet: $vStopped#55...Packet received: T0006:0000000000000000;07:c0e8a381fe7f0000;10:bf43b4f1ec7f0000;thread:p12fd22.12fd22;core:2; Sending packet: $vStopped#55...Packet received: T0006:f0fea5f1ec7f0000;07:f0fea5f1ec7f0000;10:df4190ccf4550000;thread:p12fd22.12fd25;core:8; Sending packet: $vStopped#55...Packet received: T0006:f09ea5eeec7f0000;07:f09ea5eeec7f0000;10:e84190ccf4550000;thread:p12fd22.12fd2b;core:b; Sending packet: $vStopped#55...Packet received: OK But then wait_one never consumes them, always hitting this path: 4473 if (nfds == 0) 4474 { 4475 /* No waitable targets left. All must be stopped. */ 4476 return {NULL, minus_one_ptid, {TARGET_WAITKIND_NO_RESUMED}}; 4477 } Resulting in GDB constanly calling target_stop to stop threads, but the remote target never reporting back the stops to infrun. That TARGET_WAITKIND_NO_RESUMED path shown above is always taken because here, in wait_one too, just above: 4428 for (inferior *inf : all_inferiors ()) 4429 { 4430 process_stratum_target *target = inf->process_target (); 4431 if (target == NULL 4432 || !target->is_async_p () ^^^^^^^^^^^^^^^^^^^^^ 4433 || !target->threads_executing) 4434 continue; ... the remote target is not async. And in turn that happened because extended_remote_target::attach misses enabling async in the target-non-stop path. A testcase exercising this will be added in a following patch. gdb/ChangeLog: * remote.c (extended_remote_target::attach): Set target async in the target-non-stop path too.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Mar 9, 2021
…PR gdb/27147) PR 27147 shows that on sparc64, GDB is unable to properly unwind: Expected result (from GDB 9.2): #0 0x0000000000108de4 in puts () riscvarchive#1 0x0000000000100950 in hello () at gdb-test.c:4 riscvarchive#2 0x0000000000100968 in main () at gdb-test.c:8 Actual result (from GDB latest git): #0 0x0000000000108de4 in puts () riscvarchive#1 0x0000000000100950 in hello () at gdb-test.c:4 Backtrace stopped: previous frame inner to this frame (corrupt stack?) The first failing commit is 5b6d1e4 ("Multi-target support"). The cause of the change in behavior is due to (thanks for Andrew Burgess for finding this): - inferior_ptid is no longer set on entry of target_ops::wait, whereas it was set to something valid previously - deep down in linux_nat_target::wait (see stack trace below), we fetch the registers of the event thread - on sparc64, fetching registers involves reading memory (in sparc_supply_rwindow, see stack trace below) - reading memory (target_ops::xfer_partial) relies on inferior_ptid being set to the thread from which we want to read memory This is where things go wrong: #0 linux_nat_target::xfer_partial (this=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, annex=0x0, readbuf=0x7feffe3b000 "", writebuf=0x0, offset=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3697 riscvarchive#1 0x00000100007f5b10 in raw_memory_xfer_partial (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, readbuf=0x7feffe3b000 "", writebuf=0x0, memaddr=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:912 riscvarchive#2 0x00000100007f60e8 in memory_xfer_partial_1 (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, readbuf=0x7feffe3b000 "", writebuf=0x0, memaddr=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1043 riscvarchive#3 0x00000100007f61b4 in memory_xfer_partial (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, readbuf=0x7feffe3b000 "", writebuf=0x0, memaddr=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1072 riscvarchive#4 0x00000100007f6538 in target_xfer_partial (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, annex=0x0, readbuf=0x7feffe3b000 "", writebuf=0x0, offset=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1129 riscvarchive#5 0x00000100007f7094 in target_read_partial (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, annex=0x0, buf=0x7feffe3b000 "", offset=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1375 riscvarchive#6 0x00000100007f721c in target_read (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, annex=0x0, buf=0x7feffe3b000 "", offset=8791798050744, len=8) at /home/simark/src/binutils-gdb/gdb/target.c:1415 riscvarchive#7 0x00000100007f69d4 in target_read_memory (memaddr=8791798050744, myaddr=0x7feffe3b000 "", len=8) at /home/simark/src/binutils-gdb/gdb/target.c:1218 riscvarchive#8 0x0000010000758520 in sparc_supply_rwindow (regcache=0x10000fea4f0, sp=8791798050736, regnum=-1) at /home/simark/src/binutils-gdb/gdb/sparc-tdep.c:1960 riscvarchive#9 0x000001000076208c in sparc64_supply_gregset (gregmap=0x10000be3190 <sparc64_linux_ptrace_gregmap>, regcache=0x10000fea4f0, regnum=-1, gregs=0x7feffe3b230) at /home/simark/src/binutils-gdb/gdb/sparc64-tdep.c:1974 riscvarchive#10 0x0000010000751b64 in sparc_fetch_inferior_registers (regcache=0x10000fea4f0, regnum=80) at /home/simark/src/binutils-gdb/gdb/sparc-nat.c:170 riscvarchive#11 0x0000010000759d68 in sparc64_linux_nat_target::fetch_registers (this=0x10000fa2c40 <the_sparc64_linux_nat_target>, regcache=0x10000fea4f0, regnum=80) at /home/simark/src/binutils-gdb/gdb/sparc64-linux-nat.c:38 riscvarchive#12 0x00000100008146ec in target_fetch_registers (regcache=0x10000fea4f0, regno=80) at /home/simark/src/binutils-gdb/gdb/target.c:3287 riscvarchive#13 0x00000100006a8c5c in regcache::raw_update (this=0x10000fea4f0, regnum=80) at /home/simark/src/binutils-gdb/gdb/regcache.c:584 riscvarchive#14 0x00000100006a8d94 in readable_regcache::raw_read (this=0x10000fea4f0, regnum=80, buf=0x7feffe3b7c0 "") at /home/simark/src/binutils-gdb/gdb/regcache.c:598 riscvarchive#15 0x00000100006a93b8 in readable_regcache::cooked_read (this=0x10000fea4f0, regnum=80, buf=0x7feffe3b7c0 "") at /home/simark/src/binutils-gdb/gdb/regcache.c:690 riscvarchive#16 0x00000100006b288c in readable_regcache::cooked_read<unsigned long, void> (this=0x10000fea4f0, regnum=80, val=0x7feffe3b948) at /home/simark/src/binutils-gdb/gdb/regcache.c:777 riscvarchive#17 0x00000100006a9b44 in regcache_cooked_read_unsigned (regcache=0x10000fea4f0, regnum=80, val=0x7feffe3b948) at /home/simark/src/binutils-gdb/gdb/regcache.c:791 riscvarchive#18 0x00000100006abf3c in regcache_read_pc (regcache=0x10000fea4f0) at /home/simark/src/binutils-gdb/gdb/regcache.c:1295 riscvarchive#19 0x0000010000507920 in save_stop_reason (lp=0x10000fc5b10) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:2612 riscvarchive#20 0x00000100005095a4 in linux_nat_filter_event (lwpid=520983, status=1407) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3050 riscvarchive#21 0x0000010000509f9c in linux_nat_wait_1 (ptid=..., ourstatus=0x7feffe3c8f0, target_options=...) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3194 riscvarchive#22 0x000001000050b1d0 in linux_nat_target::wait (this=0x10000fa2c40 <the_sparc64_linux_nat_target>, ptid=..., ourstatus=0x7feffe3c8f0, target_options=...) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3432 riscvarchive#23 0x00000100007f8ac0 in target_wait (ptid=..., status=0x7feffe3c8f0, options=...) at /home/simark/src/binutils-gdb/gdb/target.c:2000 riscvarchive#24 0x00000100004ac17c in do_target_wait_1 (inf=0x1000116d280, ptid=..., status=0x7feffe3c8f0, options=...) at /home/simark/src/binutils-gdb/gdb/infrun.c:3464 riscvarchive#25 0x00000100004ac3b8 in operator() (__closure=0x7feffe3c678, inf=0x1000116d280) at /home/simark/src/binutils-gdb/gdb/infrun.c:3527 riscvarchive#26 0x00000100004ac7cc in do_target_wait (wait_ptid=..., ecs=0x7feffe3c8c8, options=...) at /home/simark/src/binutils-gdb/gdb/infrun.c:3540 riscvarchive#27 0x00000100004ad8c4 in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:3880 riscvarchive#28 0x0000010000485568 in inferior_event_handler (event_type=INF_REG_EVENT) at /home/simark/src/binutils-gdb/gdb/inf-loop.c:42 riscvarchive#29 0x000001000050d394 in handle_target_event (error=0, client_data=0x0) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:4060 riscvarchive#30 0x0000010000ab5c8c in handle_file_event (file_ptr=0x10001207270, ready_mask=1) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:575 riscvarchive#31 0x0000010000ab6334 in gdb_wait_for_event (block=0) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:701 riscvarchive#32 0x0000010000ab487c in gdb_do_one_event () at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:212 riscvarchive#33 0x0000010000542668 in start_event_loop () at /home/simark/src/binutils-gdb/gdb/main.c:348 riscvarchive#34 0x000001000054287c in captured_command_loop () at /home/simark/src/binutils-gdb/gdb/main.c:408 riscvarchive#35 0x0000010000544e84 in captured_main (data=0x7feffe3d188) at /home/simark/src/binutils-gdb/gdb/main.c:1242 riscvarchive#36 0x0000010000544f2c in gdb_main (args=0x7feffe3d188) at /home/simark/src/binutils-gdb/gdb/main.c:1257 riscvarchive#37 0x00000100000c1f14 in main (argc=4, argv=0x7feffe3d548) at /home/simark/src/binutils-gdb/gdb/gdb.c:32 There is a target_read_memory call in sparc_supply_rwindow, whose return value is not checked. That call fails, because inferior_ptid does not contain a valid ptid, and uninitialized buffer contents is used. Ultimately it results in a corrupt stop_pc. target_ops::fetch_registers can be (and should remain, in my opinion) independent of inferior_ptid, because the ptid of the thread from which to fetch registers can be obtained from the regcache. In other words, implementations of target_ops::fetch_registers should not rely on inferior_ptid having a sensible value on entry. The sparc64_linux_nat_target::fetch_registers case is special, because it calls a target method that is dependent on the inferior_ptid value (target_read_inferior, and ultimately target_ops::xfer_partial). So I would say it's the responsibility of sparc64_linux_nat_target::fetch_registers to set up inferior_ptid correctly prior to calling target_read_inferior. This patch makes sparc64_linux_nat_target::fetch_registers (and store_registers, since it works the same) temporarily set inferior_ptid. If we ever make target_ops::xfer_partial independent of inferior_ptid, setting inferior_ptid won't be necessary, we'll simply pass down the ptid as a parameter in some way. I chose to set/restore inferior_ptid in sparc_fetch_inferior_registers, because I am not convinced that doing so in an inner location (in sparc_supply_rwindow for instance) would always be correct. We have access to the ptid in sparc_supply_rwindow (from the regcache), so we _could_ set inferior_ptid there. However, I don't want to just set inferior_ptid, as that would make it not desync'ed with `current_thread ()` and `current_inferior ()`. It's preferable to use switch_to_thread instead, as that switches all the global "current" stuff in a coherent way. But doing so requires a `thread_info *`, and getting a `thread_info *` from a ptid requires a `process_stratum_target *`. We could use `current_inferior()->process_target()` in sparc_supply_rwindow for this (using target_read_memory uses the current inferior's target stack anyway). However, sparc_supply_rwindow is also used in the context of BSD uthreads, where a thread stratum target defines threads. I presume the ptid in the regcache would be the ptid of the uthread, defined by the thread stratum target (bsd_uthread_target). Using `current_inferior()->process_target()` would look up a ptid defined by the thread stratum target using the process stratum target. I don't think it would give good results. So I prefer playing it safe and looking up the thread earlier, in sparc_fetch_inferior_registers. I added some assertions (in sparc_supply_rwindow and others) to verify that the regcache's ptid matches inferior_ptid. That verifies that the caller has properly set the correct global context. This would have caught (though a failed assertion) the current problem. gdb/ChangeLog: PR gdb/27147 * sparc-nat.h (sparc_fetch_inferior_registers): Add process_stratum_target parameter, sparc_store_inferior_registers): update callers. * sparc-nat.c (sparc_fetch_inferior_registers, sparc_store_inferior_registers): Add process_stratum_target parameter. Switch current thread before calling sparc_supply_gregset / sparc_collect_rwindow. (sparc_store_inferior_registers): Likewise. * sparc-obsd-tdep.c (sparc32obsd_supply_uthread): Add assertion. (sparc32obsd_collect_uthread): Likewise. * sparc-tdep.c (sparc_supply_rwindow, sparc_collect_rwindow): Add assertion. * sparc64-obsd-tdep.c (sparc64obsd_collect_uthread, sparc64obsd_supply_uthread): Add assertion. Change-Id: I16c658cd70896cea604516714f7e2428fbaf4301
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Mar 30, 2021
When testing with "maint set target-non-stop on", gdb.server/bkpt-other-inferior.exp sometimes fails like so: (gdb) inferior 2 [Switching to inferior 2 [process 368191] (<noexec>)] [Switching to thread 2.1 (Thread 368191.368191)] [remote] Sending packet: $m7ffff7fd0100,1#5b [remote] Packet received: 48 [remote] Sending packet: $m7ffff7fd0100,1#5b [remote] Packet received: 48 [remote] Sending packet: $m7ffff7fd0100,9#63 [remote] Packet received: 4889e7e8e80c000049 #0 0x00007ffff7fd0100 in ?? () (gdb) PASS: gdb.server/bkpt-other-inferior.exp: inf 2: switch to inferior break -q main Breakpoint 2 at 0x1138: file /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.server/server.c, line 21. (gdb) PASS: gdb.server/bkpt-other-inferior.exp: inf 2: set breakpoint delete breakpoints Delete all breakpoints? (y or n) y (gdb) [remote] wait: enter [remote] wait: exit FAIL: gdb.server/bkpt-other-inferior.exp: inf 2: delete all breakpoints in delete_breakpoints (timeout) ERROR: breakpoints not deleted Remote debugging from host ::1, port 55876 monitor exit The problem is here: (gdb) [remote] wait: enter The testcase isn't expecting any output after the prompt. Why is that "[remote] wait" output? What happens is that "delete breakpoints" queries the user, and `query` disables/reenables target async, which results in the remote target's async event handler ending up marked: (top-gdb) bt #0 mark_async_event_handler (async_handler_ptr=0x556bffffffff) at ../../src/gdb/async-event.c:295 riscvarchive#1 0x0000556bf71b711f in infrun_async (enable=1) at ../../src/gdb/infrun.c:119 riscvarchive#2 0x0000556bf7471387 in target_async (enable=1) at ../../src/gdb/target.c:3684 riscvarchive#3 0x0000556bf748a0bd in gdb_readline_wrapper_cleanup::~gdb_readline_wrapper_cleanup (this=0x7ffe3cf30eb0, __in_chrg=<optimized out>) at ../../src/gdb/top.c:1074 riscvarchive#4 0x0000556bf74874e2 in gdb_readline_wrapper (prompt=0x556bfa17da60 "Delete all breakpoints? (y or n) ") at ../../src/gdb/top.c:1096 riscvarchive#5 0x0000556bf75111c5 in defaulted_query(const char *, char, typedef __va_list_tag __va_list_tag *) (ctlstr=0x556bf7717f34 "Delete all breakpoints? ", defchar=0 '\000', args=0x7ffe3cf31020) at ../../src/gdb/utils.c:893 riscvarchive#6 0x0000556bf751166f in query (ctlstr=0x556bf7717f34 "Delete all breakpoints? ") at ../../src/gdb/utils.c:985 riscvarchive#7 0x0000556bf6f11404 in delete_command (arg=0x0, from_tty=1) at ../../src/gdb/breakpoint.c:13500 ... ... which then later results in a target_wait call: (top-gdb) bt #0 remote_target::wait_ns (this=0x7ffe3cf30f80, ptid=..., status=0xde530314f0802800, options=...) at ../../src/gdb/remote.c:7937 riscvarchive#1 0x0000556bf7369dcb in remote_target::wait (this=0x556bfa0b2180, ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/remote.c:8173 riscvarchive#2 0x0000556bf745e527 in target_wait (ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/target.c:2000 riscvarchive#3 0x0000556bf71be686 in do_target_wait_1 (inf=0x556bfa1573d0, ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/infrun.c:3463 riscvarchive#4 0x0000556bf71be88b in <lambda(inferior*)>::operator()(inferior *) const (__closure=0x7ffe3cf31320, inf=0x556bfa1573d0) at ../../src/gdb/infrun.c:3526 riscvarchive#5 0x0000556bf71bebcd in do_target_wait (wait_ptid=..., ecs=0x7ffe3cf31540, options=...) at ../../src/gdb/infrun.c:3539 riscvarchive#6 0x0000556bf71bf97b in fetch_inferior_event () at ../../src/gdb/infrun.c:3879 riscvarchive#7 0x0000556bf71a27f8 in inferior_event_handler (event_type=INF_REG_EVENT) at ../../src/gdb/inf-loop.c:42 riscvarchive#8 0x0000556bf71cc8b7 in infrun_async_inferior_event_handler (data=0x0) at ../../src/gdb/infrun.c:9220 riscvarchive#9 0x0000556bf6ecb80f in check_async_event_handlers () at ../../src/gdb/async-event.c:327 riscvarchive#10 0x0000556bf76b011a in gdb_do_one_event () at ../../src/gdbsupport/event-loop.cc:216 ... ... which returns TARGET_WAITKIND_IGNORE. Fix this by only enabling remote output around setting the breakpoint. gdb/testsuite/ChangeLog: * gdb.server/bkpt-other-inferior.exp: Only enable remote output around setting the breakpoint. Change-Id: I2fd152fd9c46b1c5e7fa678cc4d4054dac0b2bd4
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
May 3, 2021
While working on some changes to 'info sources' I ran into a situation where I was seeing the same source files reported twice in the output of the 'info sources' command when using either .gdb_index or the .debug_name index. I traced the problem back to some caching in dwarf2_base_index_functions::map_symbol_filenames; when called GDB caches the set of filenames, but, filesnames are not removed as the index entries are expanded into full symtabs. As a result we can end up seeing filenames reported both from a full symtab _and_ from a (stale) previously cached index entry. Now, obviously, when seeing a problem like this the "correct" fix is to remove the stale entries from the cache, however, I ran a few experiments to see why this wasn't really hitting us anywhere, and, as far as I can tell, ::map_symbol_filenames is only called from three places: 1. The mi command -file-list-exec-source-files, 2. The 'info sources' command, and 3. Filename completion However, the result of this "bug" is that we will see duplicate filenames, and readline's completion mechanism already removes duplicates, so for case riscvarchive#3 we will never see any problems. Cases riscvarchive#1 and riscvarchive#2 are basically the same, and in each case, to see a problem we need to ensure we craft the test in a particular way, start up ensuring we have some unexpected symtabs, then run one of the commands to populate the cache, then expand one of the symtabs, and list the sources again. At this point you'll see duplicate entries in the results. Hardly surprising we haven't randomly hit this situation in testing. So, considering that use cases riscvarchive#1 and riscvarchive#2 are certainly not "high performance" code (i.e. I don't think these justify the need for caching) this leaves use case riscvarchive#3. Does this use justify the need for caching? Well the psymbol_functions::map_symbol_filenames function doesn't seem to do any extra caching, and within dwarf2_base_index_functions::map_symbol_filenames, the only expensive bit appears to be the call to dw2_get_file_names, and this already does its own caching via this_cu->v.quick->file_names. The upshot of all this analysis was that I'm not convinced the need for the additional caching is justified, and so, I propose that to fix the bug in GDB, I just remove the extra caching (for now). If we later find that the caching _was_ useful, then we can reintroduce it, but add it back such that it doesn't reintroduce this bug. As I was changing dwarf2_base_index_functions::map_symbol_filenames I replaced the use of htab_up with std::unordered_set. Tested using target_boards cc-with-debug-names and dwarf4-gdb-index. gdb/ChangeLog: * dwarf2/read.c: Add 'unordered_set' include. (dwarf2_base_index_functions::map_symbol_filenames): Replace 'visited' hash table with 'qfn_cache' unordered_set. Remove use of per_Bfd->filenames_cache cache, and use function local filenames_cache instead. Reindent. * dwarf2/read.h (struct dwarf2_per_bfd) <filenames_cache>: Delete. gdb/testsuite/ChangeLog: * gdb.base/info_sources.exp: Add new tests.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Jun 11, 2021
When loading the debug info package libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug from openSUSE Leap 15.2, we run into a dwarf error: ... $ gdb -q -batch libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug Dwarf Error: Cannot not find DIE at 0x18a936e7 \ [from module libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug] ... The DIE @ 0x18a936e7 does in fact exist, and is part of a CU @ 0x18a23e52. No error message is printed when using -readnow. What happens is the following: - a dwarf2_per_cu_data P is created for the CU. - a dwarf2_cu A is created for the same CU. - another dwarf2_cu B is created for the same CU. - the dwarf2_cu B is set in per_objfile->m_dwarf2_cus, such that per_objfile->get_cu (P) returns B. - P->load_all_dies is set to 1. - all dies are read into the A->partial_dies htab - dwarf2_cu A is destroyed. - we try to find the partial_die for the DIE @ 0x18a936e7 in B->partial_dies. We can't find it, but do not try to load all dies, because P->load_all_dies is already set to 1. - an error message is generated. The question is why we're creating dwarf2_cu A and B for the same CU. The dwarf2_cu A is created here: ... (gdb) bt #0 dwarf2_cu::dwarf2_cu (this=0x79a9660, per_cu=0x23c0b30, per_objfile=0x1ad01b0) at dwarf2/cu.c:38 riscvarchive#1 0x0000000000675799 in cutu_reader::cutu_reader (this=0x7fffffffd040, this_cu=0x23c0b30, per_objfile=0x1ad01b0, abbrev_table=0x0, existing_cu=0x0, skip_partial=false) at dwarf2/read.c:6487 riscvarchive#2 0x0000000000676eb3 in process_psymtab_comp_unit (this_cu=0x23c0b30, per_objfile=0x1ad01b0, want_partial_unit=false, pretend_language=language_minimal) at dwarf2/read.c:7028 ... And the dwarf2_cu B is created here: ... (gdb) bt #0 dwarf2_cu::dwarf2_cu (this=0x885e8c0, per_cu=0x23c0b30, per_objfile=0x1ad01b0) at dwarf2/cu.c:38 riscvarchive#1 0x0000000000675799 in cutu_reader::cutu_reader (this=0x7fffffffcc50, this_cu=0x23c0b30, per_objfile=0x1ad01b0, abbrev_table=0x0, existing_cu=0x0, skip_partial=false) at dwarf2/read.c:6487 riscvarchive#2 0x0000000000678118 in load_partial_comp_unit (this_cu=0x23c0b30, per_objfile=0x1ad01b0, existing_cu=0x0) at dwarf2/read.c:7436 riscvarchive#3 0x000000000069721d in find_partial_die (sect_off=(unknown: 0x18a55054), offset_in_dwz=0, cu=0x0) at dwarf2/read.c:19391 riscvarchive#4 0x000000000069755b in partial_die_info::fixup (this=0x9096900, cu=0xa6a85f0) at dwarf2/read.c:19512 riscvarchive#5 0x0000000000697586 in partial_die_info::fixup (this=0x8629bb0, cu=0xa6a85f0) at dwarf2/read.c:19516 riscvarchive#6 0x00000000006787b1 in scan_partial_symbols (first_die=0x8629b40, lowpc=0x7fffffffcf58, highpc=0x7fffffffcf50, set_addrmap=0, cu=0x79a9660) at dwarf2/read.c:7563 riscvarchive#7 0x0000000000678878 in scan_partial_symbols (first_die=0x796ebf0, lowpc=0x7fffffffcf58, highpc=0x7fffffffcf50, set_addrmap=0, cu=0x79a9660) at dwarf2/read.c:7580 riscvarchive#8 0x0000000000676b82 in process_psymtab_comp_unit_reader (reader=0x7fffffffd040, info_ptr=0x7fffc1b3f29b, comp_unit_die=0x6ea90f0, pretend_language=language_minimal) at dwarf2/read.c:6954 riscvarchive#9 0x0000000000676ffd in process_psymtab_comp_unit (this_cu=0x23c0b30, per_objfile=0x1ad01b0, want_partial_unit=false, pretend_language=language_minimal) at dwarf2/read.c:7057 ... So in frame riscvarchive#9, a cutu_reader is created with dwarf2_cu A. Then a fixup takes us to the following CU @ 0x18aa33d6, in frame riscvarchive#5. And a similar fixup in frame riscvarchive#4 takes us back to CU @ 0x18a23e52. At that point, there's no information available that we're already trying to read that CU, and we end up creating another cutu_reader with dwarf2_cu B. It seems that there are two related problems: - creating two dwarf2_cu's is not optimal - the unoptimal case is not handled correctly This patch addresses the last problem, by moving the load_all_dies flag from dwarf2_per_cu_data to dwarf2_cu, such that it is paired with the partial_dies field, which ensures that the two can be kept in sync. Tested on x86_64-linux. gdb/ChangeLog: 2021-05-27 Tom de Vries <[email protected]> PR symtab/27898 * dwarf2/cu.c (dwarf2_cu::dwarf2_cu): Add load_all_dies init. * dwarf2/cu.h (dwarf2_cu): Add load_all_dies field. * dwarf2/read.c (load_partial_dies, find_partial_die): Update. * dwarf2/read.h (dwarf2_per_cu_data::dwarf2_per_cu_data): Remove load_all_dies init. (dwarf2_per_cu_data): Remove load_all_dies field.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Jun 15, 2021
… when attaching / handling a fork child When trying to attach to a pthread process on a Linux system with glibc 2.33, we get: $ ./gdb -q -nx --data-directory=data-directory -p 1472010 Attaching to process 1472010 [New LWP 1472013] [New LWP 1472014] [New LWP 1472015] Error while reading shared library symbols for /usr/lib/libpthread.so.0: Cannot find user-level thread for LWP 1472015: generic error 0x00007ffff6d3637f in poll () from /usr/lib/libc.so.6 (gdb) When attaching to a process (or handling a fork child, an operation very similar to attaching), GDB reads the shared library list from the process. For each shared library (if "set auto-solib-add" is on), it reads its symbols and calls the "new_objfile" observable. The libthread-db code monitors this observable, and if it sees an objfile named somewhat like "libpthread.so" go by, it tries to load libthread_db.so in the GDB process itself. libthread_db knows how to navigate libpthread's data structures to get information about the existing threads. To locate these data structures, libthread_db calls ps_pglobal_lookup (implemented in proc-service.c), passing in a symbol name and expecting an address in return. Before glibc 2.33, libthread_db always asked for symbols found in libpthread. There was no ordering problem: since we were always trying to load libthread_db in reaction to processing libpthread (and reading in its symbols) and libthread_db only asked symbols from libpthread, the requested symbols could always be found. Starting with glibc 2.33, libthread_db now asks for a symbol name that can be found in /lib/ld-linux-x86-64.so.2 (_rtld_global). And the ordering in which GDB reads the shared libraries from the inferior when attaching is unfortunate, in that libpthread is processed before ld-linux. So when loading libthread_db in reaction to processing libpthread, and libthread_db requests the symbol that is from ld-linux, GDB is not yet able to supply it. That problematic symbol lookup happens in the thread_from_lwp function, when we call td_ta_map_lwp2thr_p, and an exception is thrown at this point: #0 0x00007ffff6681012 in __cxxabiv1::__cxa_throw (obj=0x60e000006100, tinfo=0x555560033b50 <typeinfo for gdb_exception_error>, dest=0x55555d9404bc <gdb_exception_error::~gdb_exception_error()>) at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_throw.cc:78 riscvarchive#1 0x000055555e5d3734 in throw_it(return_reason, errors, const char *, typedef __va_list_tag __va_list_tag *) (reason=RETURN_ERROR, error=GENERIC_ERROR, fmt=0x55555f0c5360 "Cannot find user-level thread for LWP %ld: %s", ap=0x7fffffffaae0) at /home/simark/src/binutils-gdb/gdbsupport/common-exceptions.cc:200 riscvarchive#2 0x000055555e5d37d4 in throw_verror (error=GENERIC_ERROR, fmt=0x55555f0c5360 "Cannot find user-level thread for LWP %ld: %s", ap=0x7fffffffaae0) at /home/simark/src/binutils-gdb/gdbsupport/common-exceptions.cc:208 riscvarchive#3 0x000055555e0b0ed2 in verror (string=0x55555f0c5360 "Cannot find user-level thread for LWP %ld: %s", args=0x7fffffffaae0) at /home/simark/src/binutils-gdb/gdb/utils.c:171 riscvarchive#4 0x000055555e5e898a in error (fmt=0x55555f0c5360 "Cannot find user-level thread for LWP %ld: %s") at /home/simark/src/binutils-gdb/gdbsupport/errors.cc:43 riscvarchive#5 0x000055555d06b4bc in thread_from_lwp (stopped=0x617000035d80, ptid=...) at /home/simark/src/binutils-gdb/gdb/linux-thread-db.c:418 riscvarchive#6 0x000055555d07040d in try_thread_db_load_1 (info=0x60c000011140) at /home/simark/src/binutils-gdb/gdb/linux-thread-db.c:912 riscvarchive#7 0x000055555d071103 in try_thread_db_load (library=0x55555f0c62a0 "libthread_db.so.1", check_auto_load_safe=false) at /home/simark/src/binutils-gdb/gdb/linux-thread-db.c:1014 riscvarchive#8 0x000055555d072168 in try_thread_db_load_from_sdir () at /home/simark/src/binutils-gdb/gdb/linux-thread-db.c:1091 riscvarchive#9 0x000055555d072d1c in thread_db_load_search () at /home/simark/src/binutils-gdb/gdb/linux-thread-db.c:1146 riscvarchive#10 0x000055555d07365c in thread_db_load () at /home/simark/src/binutils-gdb/gdb/linux-thread-db.c:1203 riscvarchive#11 0x000055555d07373e in check_for_thread_db () at /home/simark/src/binutils-gdb/gdb/linux-thread-db.c:1246 riscvarchive#12 0x000055555d0738ab in thread_db_new_objfile (objfile=0x61300000c0c0) at /home/simark/src/binutils-gdb/gdb/linux-thread-db.c:1275 riscvarchive#13 0x000055555bd10740 in std::__invoke_impl<void, void (*&)(objfile*), objfile*> (__f=@0x616000068d88: 0x55555d073745 <thread_db_new_objfile(objfile*)>) at /usr/include/c++/10.2.0/bits/invoke.h:60 riscvarchive#14 0x000055555bd02096 in std::__invoke_r<void, void (*&)(objfile*), objfile*> (__fn=@0x616000068d88: 0x55555d073745 <thread_db_new_objfile(objfile*)>) at /usr/include/c++/10.2.0/bits/invoke.h:153 riscvarchive#15 0x000055555bce0392 in std::_Function_handler<void (objfile*), void (*)(objfile*)>::_M_invoke(std::_Any_data const&, objfile*&&) (__functor=..., __args#0=@0x7fffffffb4a0: 0x61300000c0c0) at /usr/include/c++/10.2.0/bits/std_function.h:291 riscvarchive#16 0x000055555d3595c0 in std::function<void (objfile*)>::operator()(objfile*) const (this=0x616000068d88, __args#0=0x61300000c0c0) at /usr/include/c++/10.2.0/bits/std_function.h:622 riscvarchive#17 0x000055555d356b7f in gdb::observers::observable<objfile*>::notify (this=0x555566727020 <gdb::observers::new_objfile>, args#0=0x61300000c0c0) at /home/simark/src/binutils-gdb/gdb/../gdbsupport/observable.h:106 riscvarchive#18 0x000055555da3f228 in symbol_file_add_with_addrs (abfd=0x61200001ccc0, name=0x6190000d9090 "/usr/lib/libpthread.so.0", add_flags=..., addrs=0x7fffffffbc10, flags=..., parent=0x0) at /home/simark/src/binutils-gdb/gdb/symfile.c:1131 riscvarchive#19 0x000055555da3f763 in symbol_file_add_from_bfd (abfd=0x61200001ccc0, name=0x6190000d9090 "/usr/lib/libpthread.so.0", add_flags=<error reading variable: Cannot access memory at address 0xffffffffffffffb0>, addrs=0x7fffffffbc10, flags=<error reading variable: Cannot access memory at address 0xffffffffffffffc0>, parent=0x0) at /home/simark/src/binutils-gdb/gdb/symfile.c:1167 riscvarchive#20 0x000055555d95f9fa in solib_read_symbols (so=0x6190000d8e80, flags=...) at /home/simark/src/binutils-gdb/gdb/solib.c:681 riscvarchive#21 0x000055555d96233d in solib_add (pattern=0x0, from_tty=0, readsyms=1) at /home/simark/src/binutils-gdb/gdb/solib.c:987 riscvarchive#22 0x000055555d93646e in enable_break (info=0x608000008f20, from_tty=0) at /home/simark/src/binutils-gdb/gdb/solib-svr4.c:2238 riscvarchive#23 0x000055555d93cfc0 in svr4_solib_create_inferior_hook (from_tty=0) at /home/simark/src/binutils-gdb/gdb/solib-svr4.c:3049 riscvarchive#24 0x000055555d96610d in solib_create_inferior_hook (from_tty=0) at /home/simark/src/binutils-gdb/gdb/solib.c:1195 riscvarchive#25 0x000055555cdee318 in post_create_inferior (from_tty=0) at /home/simark/src/binutils-gdb/gdb/infcmd.c:318 riscvarchive#26 0x000055555ce00e6e in setup_inferior (from_tty=0) at /home/simark/src/binutils-gdb/gdb/infcmd.c:2439 riscvarchive#27 0x000055555ce59c34 in handle_one (event=...) at /home/simark/src/binutils-gdb/gdb/infrun.c:4887 riscvarchive#28 0x000055555ce5cd00 in stop_all_threads () at /home/simark/src/binutils-gdb/gdb/infrun.c:5064 riscvarchive#29 0x000055555ce7f0da in stop_waiting (ecs=0x7fffffffd170) at /home/simark/src/binutils-gdb/gdb/infrun.c:8006 riscvarchive#30 0x000055555ce67f5c in handle_signal_stop (ecs=0x7fffffffd170) at /home/simark/src/binutils-gdb/gdb/infrun.c:6062 riscvarchive#31 0x000055555ce63653 in handle_inferior_event (ecs=0x7fffffffd170) at /home/simark/src/binutils-gdb/gdb/infrun.c:5727 riscvarchive#32 0x000055555ce4f297 in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:4105 riscvarchive#33 0x000055555cdbe3bf in inferior_event_handler (event_type=INF_REG_EVENT) at /home/simark/src/binutils-gdb/gdb/inf-loop.c:42 riscvarchive#34 0x000055555d018047 in handle_target_event (error=0, client_data=0x0) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:4060 riscvarchive#35 0x000055555e5ea77e in handle_file_event (file_ptr=0x60600008b1c0, ready_mask=1) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:575 riscvarchive#36 0x000055555e5eb09c in gdb_wait_for_event (block=0) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:701 riscvarchive#37 0x000055555e5e8d19 in gdb_do_one_event () at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:212 riscvarchive#38 0x000055555dd6e0d4 in wait_sync_command_done () at /home/simark/src/binutils-gdb/gdb/top.c:528 riscvarchive#39 0x000055555dd6e372 in maybe_wait_sync_command_done (was_sync=0) at /home/simark/src/binutils-gdb/gdb/top.c:545 riscvarchive#40 0x000055555d0ec7c8 in catch_command_errors (command=0x55555ce01bb8 <attach_command(char const*, int)>, arg=0x7fffffffe28d "1472010", from_tty=1, do_bp_actions=false) at /home/simark/src/binutils-gdb/gdb/main.c:452 riscvarchive#41 0x000055555d0f03ad in captured_main_1 (context=0x7fffffffdd10) at /home/simark/src/binutils-gdb/gdb/main.c:1149 riscvarchive#42 0x000055555d0f1239 in captured_main (data=0x7fffffffdd10) at /home/simark/src/binutils-gdb/gdb/main.c:1232 riscvarchive#43 0x000055555d0f1315 in gdb_main (args=0x7fffffffdd10) at /home/simark/src/binutils-gdb/gdb/main.c:1257 riscvarchive#44 0x000055555bb70cf9 in main (argc=7, argv=0x7fffffffde88) at /home/simark/src/binutils-gdb/gdb/gdb.c:32 The exception is caught here: #0 __cxxabiv1::__cxa_begin_catch (exc_obj_in=0x60e0000060e0) at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_catch.cc:84 riscvarchive#1 0x000055555d95fded in solib_read_symbols (so=0x6190000d8e80, flags=...) at /home/simark/src/binutils-gdb/gdb/solib.c:689 riscvarchive#2 0x000055555d96233d in solib_add (pattern=0x0, from_tty=0, readsyms=1) at /home/simark/src/binutils-gdb/gdb/solib.c:987 riscvarchive#3 0x000055555d93646e in enable_break (info=0x608000008f20, from_tty=0) at /home/simark/src/binutils-gdb/gdb/solib-svr4.c:2238 riscvarchive#4 0x000055555d93cfc0 in svr4_solib_create_inferior_hook (from_tty=0) at /home/simark/src/binutils-gdb/gdb/solib-svr4.c:3049 riscvarchive#5 0x000055555d96610d in solib_create_inferior_hook (from_tty=0) at /home/simark/src/binutils-gdb/gdb/solib.c:1195 riscvarchive#6 0x000055555cdee318 in post_create_inferior (from_tty=0) at /home/simark/src/binutils-gdb/gdb/infcmd.c:318 riscvarchive#7 0x000055555ce00e6e in setup_inferior (from_tty=0) at /home/simark/src/binutils-gdb/gdb/infcmd.c:2439 riscvarchive#8 0x000055555ce59c34 in handle_one (event=...) at /home/simark/src/binutils-gdb/gdb/infrun.c:4887 riscvarchive#9 0x000055555ce5cd00 in stop_all_threads () at /home/simark/src/binutils-gdb/gdb/infrun.c:5064 riscvarchive#10 0x000055555ce7f0da in stop_waiting (ecs=0x7fffffffd170) at /home/simark/src/binutils-gdb/gdb/infrun.c:8006 riscvarchive#11 0x000055555ce67f5c in handle_signal_stop (ecs=0x7fffffffd170) at /home/simark/src/binutils-gdb/gdb/infrun.c:6062 riscvarchive#12 0x000055555ce63653 in handle_inferior_event (ecs=0x7fffffffd170) at /home/simark/src/binutils-gdb/gdb/infrun.c:5727 riscvarchive#13 0x000055555ce4f297 in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:4105 riscvarchive#14 0x000055555cdbe3bf in inferior_event_handler (event_type=INF_REG_EVENT) at /home/simark/src/binutils-gdb/gdb/inf-loop.c:42 riscvarchive#15 0x000055555d018047 in handle_target_event (error=0, client_data=0x0) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:4060 riscvarchive#16 0x000055555e5ea77e in handle_file_event (file_ptr=0x60600008b1c0, ready_mask=1) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:575 riscvarchive#17 0x000055555e5eb09c in gdb_wait_for_event (block=0) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:701 riscvarchive#18 0x000055555e5e8d19 in gdb_do_one_event () at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:212 riscvarchive#19 0x000055555dd6e0d4 in wait_sync_command_done () at /home/simark/src/binutils-gdb/gdb/top.c:528 riscvarchive#20 0x000055555dd6e372 in maybe_wait_sync_command_done (was_sync=0) at /home/simark/src/binutils-gdb/gdb/top.c:545 riscvarchive#21 0x000055555d0ec7c8 in catch_command_errors (command=0x55555ce01bb8 <attach_command(char const*, int)>, arg=0x7fffffffe28d "1472010", from_tty=1, do_bp_actions=false) at /home/simark/src/binutils-gdb/gdb/main.c:452 riscvarchive#22 0x000055555d0f03ad in captured_main_1 (context=0x7fffffffdd10) at /home/simark/src/binutils-gdb/gdb/main.c:1149 riscvarchive#23 0x000055555d0f1239 in captured_main (data=0x7fffffffdd10) at /home/simark/src/binutils-gdb/gdb/main.c:1232 riscvarchive#24 0x000055555d0f1315 in gdb_main (args=0x7fffffffdd10) at /home/simark/src/binutils-gdb/gdb/main.c:1257 riscvarchive#25 0x000055555bb70cf9 in main (argc=7, argv=0x7fffffffde88) at /home/simark/src/binutils-gdb/gdb/gdb.c:32 Catching the exception at this point means that the thread_db_info object for this inferior will be left in place, despite the failure to load libthread_db. This means that there won't be further attempts at loading libthread_db, because thread_db_load will think that libthread_db is already loaded for this inferior and will always exit early. To fix this, add a try/catch around calling try_thread_db_load_1 in try_thread_db_load, such that if some exception is thrown while trying to load libthread_db, we reset / delete the thread_db_info for that inferior. That alone makes attach work fine again, because check_for_thread_db is called again in the thread_db_inferior_created observer (that happens after we learned about all shared libraries and their symbols), and libthread_db is successfully loaded then. When attaching, I think that the inferior_created observer is a good place to try to load libthread_db: it is called once everything has stabilized, when we learned about all shared libraries. The only problem then is that when we first try (and fail) to load libthread_db, in reaction to learning about libpthread, we show this warning: warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. This is misleading, because we do succeed in loading it later. So when attaching, I think we shouldn't try to load libthread_db in reaction to the new_objfile events, we should wait until we have learned about all shared libraries (using the inferior_created observable). To do so, add an `in_initial_library_scan` flag to struct inferior. This flag is used to postpone loading libthread_db if we are attaching or handling a fork child. When debugging remotely with GDBserver, the same problem happens, except that the qSymbol mechanism (allowing the remote side to ask GDB for symbols values) is involved. The fix there is the same idea, we make GDB wait until all shared libraries and their symbols are known before sending out a qSymbol packet. This way, we never present the remote side a state where libpthread.so's symbols are known but ld-linux's symbols aren't. gdb/ChangeLog: * inferior.h (class inferior) <in_initial_library_scan>: New. * infcmd.c (post_create_inferior): Set in_initial_library_scan. * infrun.c (follow_fork_inferior): Likewise. * linux-thread-db.c (try_thread_db_load): Catch exception thrown by try_thread_db_load_1 (thread_db_load): Return early if in_initial_library_scan is set. * remote.c (remote_new_objfile): Return early if in_initial_library_scan is set. Change-Id: I7a279836cfbb2b362b4fde11b196b4aab82f5efb
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Jul 8, 2021
When loading a mach-o (macOS) executable and trying to set a breakpoint, a GDB built with ASan or -D_GLIBCXX_DEBUG will crash with an out-of-bound vector access. This can be reproduced on Linux using the repro files in bug 28017 [1]: $ ./gdb -nx --data-directory=data-directory -q repro/test -ex "b main" -batch /usr/include/c++/11.1.0/debug/vector:445: In function: std::__debug::vector<_Tp, _Allocator>::const_reference std::__debug::vector<_Tp, _Allocator>::operator[](std::__debug::vector<_Tp, _Allocator>::size_type) const [with _Tp = long unsigned int; _Allocator = std::allocator<long unsigned int>; std::__debug::vector<_Tp, _Allocator>::const_reference = const long unsigned int&; std::__debug::vector<_Tp, _Allocator>::size_type = long unsigned int] Error: attempt to subscript container with out-of-bounds index 13, but container only holds 13 elements. Objects involved in the operation: sequence "this" @ 0x0x61300000a590 { type = std::__debug::vector<unsigned long, std::allocator<unsigned long> >; } The out-of-bound access happens here: #0 0x00007ffff6405d22 in raise () from /usr/lib/libc.so.6 riscvarchive#1 0x00007ffff63ef862 in abort () from /usr/lib/libc.so.6 riscvarchive#2 0x00007ffff664e21e in __gnu_debug::_Error_formatter::_M_error() const [clone .cold] from /usr/lib/libstdc++.so.6 riscvarchive#3 0x000055555699e5ff in std::__debug::vector<unsigned long, std::allocator<unsigned long> >::operator[] (this=0x61300000a590, __n=13) at /usr/include/c++/11.1.0/debug/vector:445 riscvarchive#4 0x0000555556a58c17 in objfile::section_offset (this=0x61300000a4c0, section=0x55555bbe4ac0 <_bfd_std_section>) at /home/simark/src/binutils-gdb/gdb/objfiles.h:644 riscvarchive#5 0x0000555556a58cac in obj_section::offset (this=0x62100016d2a8) at /home/simark/src/binutils-gdb/gdb/objfiles.h:838 riscvarchive#6 0x0000555556a58cfa in obj_section::addr (this=0x62100016d2a8) at /home/simark/src/binutils-gdb/gdb/objfiles.h:850 riscvarchive#7 0x000055555779f5f7 in sort_cmp (sect1=0x62100016d2a8, sect2=0x62100016d170) at /home/simark/src/binutils-gdb/gdb/objfiles.c:902 riscvarchive#8 0x00005555577aae35 in __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(obj_section const*, obj_section const*)>::operator()<obj_section**, obj_section**> (this=0x7fffffffa9e0, __it1=0x60c000015970, __it2=0x60c000015940) at /usr/include/c++/11.1.0/bits/predefined_ops.h:158 riscvarchive#9 0x00005555577aa2b8 in std::__insertion_sort<obj_section**, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(obj_section const*, obj_section const*)> > (__first=0x60c000015940, __last=0x60c0000159c0, __comp=...) at /usr/include/c++/11.1.0/bits/stl_algo.h:1826 riscvarchive#10 0x00005555577a8e26 in std::__final_insertion_sort<obj_section**, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(obj_section const*, obj_section const*)> > (__first=0x60c000015940, __last=0x60c0000159c0, __comp=...) at /usr/include/c++/11.1.0/bits/stl_algo.h:1871 riscvarchive#11 0x00005555577a723c in std::__sort<obj_section**, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(obj_section const*, obj_section const*)> > (__first=0x60c000015940, __last=0x60c0000159c0, __comp=...) at /usr/include/c++/11.1.0/bits/stl_algo.h:1957 riscvarchive#12 0x00005555577a50f4 in std::sort<obj_section**, bool (*)(obj_section const*, obj_section const*)> (__first=0x60c000015940, __last=0x60c0000159c0, __comp=0x55555779f4e7 <sort_cmp(obj_section const*, obj_section const*)>) at /usr/include/c++/11.1.0/bits/stl_algo.h:4875 riscvarchive#13 0x00005555577a147e in update_section_map (pspace=0x61200001d2c0, pmap=0x6030000d40b0, pmap_size=0x6030000d40b8) at /home/simark/src/binutils-gdb/gdb/objfiles.c:1165 riscvarchive#14 0x00005555577a19a0 in find_pc_section (pc=0x100003fa0) at /home/simark/src/binutils-gdb/gdb/objfiles.c:1212 riscvarchive#15 0x00005555576dd39e in lookup_minimal_symbol_by_pc_section (pc_in=0x100003fa0, section=0x0, prefer=lookup_msym_prefer::TEXT, previous=0x0) at /home/simark/src/binutils-gdb/gdb/minsyms.c:750 riscvarchive#16 0x00005555576de552 in lookup_minimal_symbol_by_pc (pc=0x100003fa0) at /home/simark/src/binutils-gdb/gdb/minsyms.c:986 riscvarchive#17 0x0000555557d44b54 in find_pc_sect_line (pc=0x100003fa0, section=0x62100016d170, notcurrent=0) at /home/simark/src/binutils-gdb/gdb/symtab.c:3163 riscvarchive#18 0x0000555557d489fa in find_function_start_sal_1 (func_addr=0x100003fa0, section=0x62100016d170, funfirstline=true) at /home/simark/src/binutils-gdb/gdb/symtab.c:3650 riscvarchive#19 0x0000555557d49015 in find_function_start_sal (sym=0x621000191670, funfirstline=true) at /home/simark/src/binutils-gdb/gdb/symtab.c:3706 riscvarchive#20 0x0000555557485283 in symbol_to_sal (result=0x7fffffffbb30, funfirstline=1, sym=0x621000191670) at /home/simark/src/binutils-gdb/gdb/linespec.c:4460 riscvarchive#21 0x00005555574728c2 in convert_linespec_to_sals (state=0x7fffffffc390, ls=0x7fffffffc3e0) at /home/simark/src/binutils-gdb/gdb/linespec.c:2335 riscvarchive#22 0x0000555557475a8e in parse_linespec (parser=0x7fffffffc360, arg=0x60200007a550 "main", match_type=symbol_name_match_type::WILD) at /home/simark/src/binutils-gdb/gdb/linespec.c:2716 riscvarchive#23 0x0000555557479027 in event_location_to_sals (parser=0x7fffffffc360, location=0x606000097be0) at /home/simark/src/binutils-gdb/gdb/linespec.c:3173 riscvarchive#24 0x00005555574798f7 in decode_line_full (location=0x606000097be0, flags=1, search_pspace=0x0, default_symtab=0x0, default_line=0, canonical=0x7fffffffcca0, select_mode=0x0, filter=0x0) at /home/simark/src/binutils-gdb/gdb/linespec.c:3253 riscvarchive#25 0x0000555556b4949f in parse_breakpoint_sals (location=0x606000097be0, canonical=0x7fffffffcca0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:9134 riscvarchive#26 0x0000555556b6ce95 in create_sals_from_location_default (location=0x606000097be0, canonical=0x7fffffffcca0, type_wanted=bp_breakpoint) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:13819 riscvarchive#27 0x0000555556b645a6 in bkpt_create_sals_from_location (location=0x606000097be0, canonical=0x7fffffffcca0, type_wanted=bp_breakpoint) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:12631 riscvarchive#28 0x0000555556b4badf in create_breakpoint (gdbarch=0x621000152d10, location=0x606000097be0, cond_string=0x0, thread=0, extra_string=0x0, force_condition=false, parse_extra=1, tempflag=0, type_wanted=bp_breakpoint, ignore_count=0, pending_break_support=AUTO_BOOLEAN_AUTO, ops=0x55555bd728a0 <bkpt_breakpoint_ops>, from_tty=0, enabled=1, internal=0, flags=0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:9410 riscvarchive#29 0x0000555556b4d3b1 in break_command_1 (arg=0x7fffffffe291 "", flag=0, from_tty=0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:9590 riscvarchive#30 0x0000555556b4dc1b in break_command (arg=0x7fffffffe28d "main", from_tty=0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:9660 riscvarchive#31 0x0000555556d24ca9 in do_const_cfunc (c=0x61100003a240, args=0x7fffffffe28d "main", from_tty=0) at /home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:102 riscvarchive#32 0x0000555556d2fcd3 in cmd_func (cmd=0x61100003a240, args=0x7fffffffe28d "main", from_tty=0) at /home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:2160 riscvarchive#33 0x0000555557e84e93 in execute_command (p=0x7fffffffe290 "n", from_tty=0) at /home/simark/src/binutils-gdb/gdb/top.c:674 riscvarchive#34 0x00005555575a9933 in catch_command_errors (command=0x555557e84043 <execute_command(char const*, int)>, arg=0x7fffffffe28b "b main", from_tty=0, do_bp_actions=true) at /home/simark/src/binutils-gdb/gdb/main.c:523 riscvarchive#35 0x00005555575a9fdb in execute_cmdargs (cmdarg_vec=0x7fffffffd910, file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND, ret=0x7fffffffd5b0) at /home/simark/src/binutils-gdb/gdb/main.c:618 riscvarchive#36 0x00005555575ad48a in captured_main_1 (context=0x7fffffffdd00) at /home/simark/src/binutils-gdb/gdb/main.c:1322 riscvarchive#37 0x00005555575ada9c in captured_main (data=0x7fffffffdd00) at /home/simark/src/binutils-gdb/gdb/main.c:1343 riscvarchive#38 0x00005555575adb31 in gdb_main (args=0x7fffffffdd00) at /home/simark/src/binutils-gdb/gdb/main.c:1368 riscvarchive#39 0x000055555681e179 in main (argc=8, argv=0x7fffffffde78) at /home/simark/src/binutils-gdb/gdb/gdb.c:32 The section being dealt with at that moment is the special *COM* section: (top-gdb) p section.name $1 = 0x55555a1bbe60 "*COM*" (top-gdb) p section $2 = (bfd_section *) 0x55555bbe4ac0 <_bfd_std_section> I'm not too sure what this section is for, but this is one of four special BFD sections that GDB puts after the regular sections in the objfile::sections and objfile::section_offsets lists. You can check gdb_bfd_section_index to see how they are handled. gdb_bfd_count_sections returns "+ 4" to account for those sections. The problem is that macho_symfile_offsets uses bfd_count_sections instead of gdb_bfd_count_sections when allocating the objfile::section_offsets vector. The vector will therefore contain, say, 13 elements instead of 17. When trying to access the section offset of the *COM* section, the first after the regular sections, we access section_offsets[13], which is out of bounds. Fix that by using gdb_bfd_count_sections instead of bfd_count_sections. I'm fairly confident that this is correct, as this is what default_symfile_offsets does. With this patch, the command shown above terminates normally: $ ./gdb -nx --data-directory=data-directory -q repro/test -ex "b main" -batch Breakpoint 1 at 0x100003fad: file test.c, line 2. [1] https://sourceware.org/bugzilla/show_bug.cgi?id=28017 gdb/ChangeLog: PR gdb/28017 * machoread.c (macho_symfile_offsets): Use gdb_bfd_count_sections to allocate objfile::section_offsets. Change-Id: Ic3a56f46f7232e9f24581f8255fc1ab981935450
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Jul 8, 2021
When loading a file using the file command on macOS, we get: $ ./gdb -nx --data-directory=data-directory -q -ex "file ./test" Reading symbols from ./test... Reading symbols from /Users/smarchi/build/binutils-gdb/gdb/test.dSYM/Contents/Resources/DWARF/test... /Users/smarchi/src/binutils-gdb/gdb/thread.c:72: internal-error: struct thread_info *inferior_thread(): Assertion `current_thread_ != nullptr' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) The backtrace is: * frame #0: 0x0000000101fcb826 gdb`internal_error(file="/Users/smarchi/src/binutils-gdb/gdb/thread.c", line=72, fmt="%s: Assertion `%s' failed.") at errors.cc:52:3 frame riscvarchive#1: 0x00000001018a2584 gdb`inferior_thread() at thread.c:72:3 frame riscvarchive#2: 0x0000000101469c09 gdb`get_current_regcache() at regcache.c:421:31 frame riscvarchive#3: 0x00000001015f9812 gdb`darwin_solib_get_all_image_info_addr_at_init(info=0x0000603000006d00) at solib-darwin.c:464:34 frame riscvarchive#4: 0x00000001015f7a04 gdb`darwin_solib_create_inferior_hook(from_tty=1) at solib-darwin.c:515:5 frame riscvarchive#5: 0x000000010161205e gdb`solib_create_inferior_hook(from_tty=1) at solib.c:1200:3 frame riscvarchive#6: 0x00000001016d8f76 gdb`symbol_file_command(args="./test", from_tty=1) at symfile.c:1650:7 frame riscvarchive#7: 0x0000000100abab17 gdb`file_command(arg="./test", from_tty=1) at exec.c:555:3 frame riscvarchive#8: 0x00000001004dc799 gdb`do_const_cfunc(c=0x000061100000c340, args="./test", from_tty=1) at cli-decode.c:102:3 frame riscvarchive#9: 0x00000001004ea042 gdb`cmd_func(cmd=0x000061100000c340, args="./test", from_tty=1) at cli-decode.c:2160:7 frame riscvarchive#10: 0x00000001018d4f59 gdb`execute_command(p="t", from_tty=1) at top.c:674:2 frame riscvarchive#11: 0x0000000100eee430 gdb`catch_command_errors(command=(gdb`execute_command(char const*, int) at top.c:561), arg="file ./test", from_tty=1, do_bp_actions=true)(char const*, int), char const*, int, bool) at main.c:523:7 frame riscvarchive#12: 0x0000000100eee902 gdb`execute_cmdargs(cmdarg_vec=0x00007ffeefbfeba0 size=1, file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND, ret=0x00007ffeefbfec20) at main.c:618:9 frame riscvarchive#13: 0x0000000100eed3a4 gdb`captured_main_1(context=0x00007ffeefbff780) at main.c:1322:3 frame riscvarchive#14: 0x0000000100ee810d gdb`captured_main(data=0x00007ffeefbff780) at main.c:1343:3 frame riscvarchive#15: 0x0000000100ee8025 gdb`gdb_main(args=0x00007ffeefbff780) at main.c:1368:7 frame riscvarchive#16: 0x00000001000044f1 gdb`main(argc=6, argv=0x00007ffeefbff8a0) at gdb.c:32:10 frame riscvarchive#17: 0x00007fff20558f5d libdyld.dylib`start + 1 The solib_create_inferior_hook call in symbol_file_command was added by commit ea142fb ("Fix breakpoints on file reloads for PIE binaries"). It causes solib_create_inferior_hook to be called while the inferior is not running, which darwin_solib_create_inferior_hook does not expect. darwin_solib_get_all_image_info_addr_at_init, in particular, assumes that there is a current thread, as it tries to get the current thread's regcache. Fix it by adding a target_has_execution check and returning early. Note that there is a similar check in svr4_solib_create_inferior_hook. gdb/ChangeLog: * solib-darwin.c (darwin_solib_create_inferior_hook): Return early if no execution. Change-Id: Ia11dd983a1e29786e5ce663d0fcaa6846dc611bb
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Jul 22, 2021
Commit 408f668 ("detach in all-stop with threads running") regressed "detach" with "target remote": (gdb) detach Detaching from program: target:/any/program, process 3671843 Detaching from process 3671843 Ending remote debugging. [Inferior 1 (process 3671843) detached] In main terminate called after throwing an instance of 'gdb_exception_error' Aborted (core dumped) Here's the exception above being thrown: (top-gdb) bt #0 throw_error (error=TARGET_CLOSE_ERROR, fmt=0x555556035588 "Remote connection closed") at src/gdbsupport/common-exceptions.cc:222 riscvarchive#1 0x0000555555bbaa46 in remote_target::readchar (this=0x555556a11040, timeout=10000) at src/gdb/remote.c:9440 riscvarchive#2 0x0000555555bbb9e5 in remote_target::getpkt_or_notif_sane_1 (this=0x555556a11040, buf=0x555556a11058, forever=0, expecting_notif=0, is_notif=0x0) at src/gdb/remote.c:9928 riscvarchive#3 0x0000555555bbbda9 in remote_target::getpkt_sane (this=0x555556a11040, buf=0x555556a11058, forever=0) at src/gdb/remote.c:10030 riscvarchive#4 0x0000555555bc0e75 in remote_target::remote_hostio_send_command (this=0x555556a11040, command_bytes=13, which_packet=14, remote_errno=0x7fffffffcfd0, attachment=0x0, attachment_len=0x0) at src/gdb/remote.c:12137 riscvarchive#5 0x0000555555bc1b6c in remote_target::remote_hostio_close (this=0x555556a11040, fd=8, remote_errno=0x7fffffffcfd0) at src/gdb/remote.c:12455 riscvarchive#6 0x0000555555bc1bb4 in remote_target::fileio_close (During symbol reading: .debug_line address at offset 0x64f417 is 0 [in module build/gdb/gdb] this=0x555556a11040, fd=8, remote_errno=0x7fffffffcfd0) at src/gdb/remote.c:12462 riscvarchive#7 0x0000555555c9274c in target_fileio_close (fd=3, target_errno=0x7fffffffcfd0) at src/gdb/target.c:3365 riscvarchive#8 0x000055555595a19d in gdb_bfd_iovec_fileio_close (abfd=0x555556b9f8a0, stream=0x555556b11530) at src/gdb/gdb_bfd.c:439 riscvarchive#9 0x0000555555e09e3f in opncls_bclose (abfd=0x555556b9f8a0) at src/bfd/opncls.c:599 riscvarchive#10 0x0000555555e0a2c7 in bfd_close_all_done (abfd=0x555556b9f8a0) at src/bfd/opncls.c:847 riscvarchive#11 0x0000555555e0a27a in bfd_close (abfd=0x555556b9f8a0) at src/bfd/opncls.c:814 riscvarchive#12 0x000055555595a9d3 in gdb_bfd_close_or_warn (abfd=0x555556b9f8a0) at src/gdb/gdb_bfd.c:626 riscvarchive#13 0x000055555595ad29 in gdb_bfd_unref (abfd=0x555556b9f8a0) at src/gdb/gdb_bfd.c:715 riscvarchive#14 0x0000555555ae4730 in objfile::~objfile (this=0x555556515540, __in_chrg=<optimized out>) at src/gdb/objfiles.c:573 riscvarchive#15 0x0000555555ae955a in std::_Sp_counted_ptr<objfile*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x555556c20db0) at /usr/include/c++/9/bits/shared_ptr_base.h:377 riscvarchive#16 0x000055555572b7c8 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x555556c20db0) at /usr/include/c++/9/bits/shared_ptr_base.h:155 riscvarchive#17 0x00005555557263c3 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x555556bf0588, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:730 riscvarchive#18 0x0000555555ae745e in std::__shared_ptr<objfile, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x555556bf0580, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:1169 riscvarchive#19 0x0000555555ae747e in std::shared_ptr<objfile>::~shared_ptr (this=0x555556bf0580, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr.h:103 riscvarchive#20 0x0000555555b1c1dc in __gnu_cxx::new_allocator<std::_List_node<std::shared_ptr<objfile> > >::destroy<std::shared_ptr<objfile> > (this=0x5555564cdd60, __p=0x555556bf0580) at /usr/include/c++/9/ext/new_allocator.h:153 riscvarchive#21 0x0000555555b1bb1d in std::allocator_traits<std::allocator<std::_List_node<std::shared_ptr<objfile> > > >::destroy<std::shared_ptr<objfile> > (__a=..., __p=0x555556bf0580) at /usr/include/c++/9/bits/alloc_traits.h:497 riscvarchive#22 0x0000555555b1b73e in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::_M_erase (this=0x5555564cdd60, __position=std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x555556515540}) at /usr/include/c++/9/bits/stl_list.h:1921 riscvarchive#23 0x0000555555b1afeb in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::erase (this=0x5555564cdd60, __position=std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x555556515540}) at /usr/include/c++/9/bits/list.tcc:158 riscvarchive#24 0x0000555555b19576 in program_space::remove_objfile (this=0x5555564cdd20, objfile=0x555556515540) at src/gdb/progspace.c:210 riscvarchive#25 0x0000555555ae4502 in objfile::unlink (this=0x555556515540) at src/gdb/objfiles.c:487 riscvarchive#26 0x0000555555ae5a12 in objfile_purge_solibs () at src/gdb/objfiles.c:875 riscvarchive#27 0x0000555555c09686 in no_shared_libraries (ignored=0x0, from_tty=1) at src/gdb/solib.c:1236 riscvarchive#28 0x00005555559e3f5f in detach_command (args=0x0, from_tty=1) at src/gdb/infcmd.c:2769 So frame riscvarchive#28 already detached the remote process, and then we're purging the shared libraries. GDB had opened remote shared libraries via the target: sysroot, so it tries closing them. GDBserver is tearing down already, so remote communication breaks down and we close the remote target and throw TARGET_CLOSE_ERROR. Note frame riscvarchive#14: riscvarchive#14 0x0000555555ae4730 in objfile::~objfile (this=0x555556515540, __in_chrg=<optimized out>) at src/gdb/objfiles.c:573 That's a dtor, thus noexcept. That's the reason for the std::terminate. Stepping back a bit, why do we still have open remote files if we've managed to detach already, and, we're debugging with "target remote"? The reason is that commit 408f668 makes detach_command hold a reference to the target, so the remote target won't be finally closed until frame riscvarchive#28 returns. It's closing the target that invalidates target file I/O handles. This commit fixes the issue by not relying on target_close to invalidate the target file I/O handles, instead invalidate them immediately in remote_unpush_target. So when GDB purges the solibs, and we end up in target_fileio_close (frame riscvarchive#7 above), there's nothing to do, and we don't try to talk with the remote target anymore. The regression isn't seen when testing with --target_board=native-gdbserver, because that does "set sysroot" to disable the "target:" sysroot, for test run speed reasons. So this commit adds a testcase that explicitly tests detach with "set sysroot target:". gdb/ChangeLog: yyyy-mm-dd Pedro Alves <[email protected]> PR gdb/28080 * remote.c (remote_unpush_target): Invalidate file I/O target handles. * target.c (fileio_handles_invalidate_target): Make extern. * target.h (fileio_handles_invalidate_target): Declare. gdb/testsuite/ChangeLog: yyyy-mm-dd Pedro Alves <[email protected]> PR gdb/28080 * gdb.base/detach-sysroot-target.exp: New. * gdb.base/detach-sysroot-target.c: New. Reported-By: Jonah Graham <[email protected]> Change-Id: I851234910172f42a1b30e731161376c344d2727d
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Jul 22, 2021
…080) Before PR gdb/28080 was fixed by the previous patch, GDB was crashing like this: (gdb) detach Detaching from program: target:/any/program, process 3671843 Detaching from process 3671843 Ending remote debugging. [Inferior 1 (process 3671843) detached] In main terminate called after throwing an instance of 'gdb_exception_error' Aborted (core dumped) Here's the exception above being thrown: (top-gdb) bt #0 throw_error (error=TARGET_CLOSE_ERROR, fmt=0x555556035588 "Remote connection closed") at src/gdbsupport/common-exceptions.cc:222 riscvarchive#1 0x0000555555bbaa46 in remote_target::readchar (this=0x555556a11040, timeout=10000) at src/gdb/remote.c:9440 riscvarchive#2 0x0000555555bbb9e5 in remote_target::getpkt_or_notif_sane_1 (this=0x555556a11040, buf=0x555556a11058, forever=0, expecting_notif=0, is_notif=0x0) at src/gdb/remote.c:9928 riscvarchive#3 0x0000555555bbbda9 in remote_target::getpkt_sane (this=0x555556a11040, buf=0x555556a11058, forever=0) at src/gdb/remote.c:10030 riscvarchive#4 0x0000555555bc0e75 in remote_target::remote_hostio_send_command (this=0x555556a11040, command_bytes=13, which_packet=14, remote_errno=0x7fffffffcfd0, attachment=0x0, attachment_len=0x0) at src/gdb/remote.c:12137 riscvarchive#5 0x0000555555bc1b6c in remote_target::remote_hostio_close (this=0x555556a11040, fd=8, remote_errno=0x7fffffffcfd0) at src/gdb/remote.c:12455 riscvarchive#6 0x0000555555bc1bb4 in remote_target::fileio_close (During symbol reading: .debug_line address at offset 0x64f417 is 0 [in module build/gdb/gdb] this=0x555556a11040, fd=8, remote_errno=0x7fffffffcfd0) at src/gdb/remote.c:12462 riscvarchive#7 0x0000555555c9274c in target_fileio_close (fd=3, target_errno=0x7fffffffcfd0) at src/gdb/target.c:3365 riscvarchive#8 0x000055555595a19d in gdb_bfd_iovec_fileio_close (abfd=0x555556b9f8a0, stream=0x555556b11530) at src/gdb/gdb_bfd.c:439 riscvarchive#9 0x0000555555e09e3f in opncls_bclose (abfd=0x555556b9f8a0) at src/bfd/opncls.c:599 riscvarchive#10 0x0000555555e0a2c7 in bfd_close_all_done (abfd=0x555556b9f8a0) at src/bfd/opncls.c:847 riscvarchive#11 0x0000555555e0a27a in bfd_close (abfd=0x555556b9f8a0) at src/bfd/opncls.c:814 riscvarchive#12 0x000055555595a9d3 in gdb_bfd_close_or_warn (abfd=0x555556b9f8a0) at src/gdb/gdb_bfd.c:626 riscvarchive#13 0x000055555595ad29 in gdb_bfd_unref (abfd=0x555556b9f8a0) at src/gdb/gdb_bfd.c:715 riscvarchive#14 0x0000555555ae4730 in objfile::~objfile (this=0x555556515540, __in_chrg=<optimized out>) at src/gdb/objfiles.c:573 riscvarchive#15 0x0000555555ae955a in std::_Sp_counted_ptr<objfile*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x555556c20db0) at /usr/include/c++/9/bits/shared_ptr_base.h:377 riscvarchive#16 0x000055555572b7c8 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x555556c20db0) at /usr/include/c++/9/bits/shared_ptr_base.h:155 riscvarchive#17 0x00005555557263c3 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x555556bf0588, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:730 riscvarchive#18 0x0000555555ae745e in std::__shared_ptr<objfile, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x555556bf0580, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:1169 riscvarchive#19 0x0000555555ae747e in std::shared_ptr<objfile>::~shared_ptr (this=0x555556bf0580, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr.h:103 riscvarchive#20 0x0000555555b1c1dc in __gnu_cxx::new_allocator<std::_List_node<std::shared_ptr<objfile> > >::destroy<std::shared_ptr<objfile> > (this=0x5555564cdd60, __p=0x555556bf0580) at /usr/include/c++/9/ext/new_allocator.h:153 riscvarchive#21 0x0000555555b1bb1d in std::allocator_traits<std::allocator<std::_List_node<std::shared_ptr<objfile> > > >::destroy<std::shared_ptr<objfile> > (__a=..., __p=0x555556bf0580) at /usr/include/c++/9/bits/alloc_traits.h:497 riscvarchive#22 0x0000555555b1b73e in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::_M_erase (this=0x5555564cdd60, __position=std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x555556515540}) at /usr/include/c++/9/bits/stl_list.h:1921 riscvarchive#23 0x0000555555b1afeb in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::erase (this=0x5555564cdd60, __position=std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x555556515540}) at /usr/include/c++/9/bits/list.tcc:158 riscvarchive#24 0x0000555555b19576 in program_space::remove_objfile (this=0x5555564cdd20, objfile=0x555556515540) at src/gdb/progspace.c:210 riscvarchive#25 0x0000555555ae4502 in objfile::unlink (this=0x555556515540) at src/gdb/objfiles.c:487 riscvarchive#26 0x0000555555ae5a12 in objfile_purge_solibs () at src/gdb/objfiles.c:875 riscvarchive#27 0x0000555555c09686 in no_shared_libraries (ignored=0x0, from_tty=1) at src/gdb/solib.c:1236 riscvarchive#28 0x00005555559e3f5f in detach_command (args=0x0, from_tty=1) at src/gdb/infcmd.c:2769 Note frame riscvarchive#14: riscvarchive#14 0x0000555555ae4730 in objfile::~objfile (this=0x555556515540, __in_chrg=<optimized out>) at src/gdb/objfiles.c:573 That's a dtor, thus noexcept. That's the reason for the std::terminate. The previous patch fixed things such that the exception above isn't thrown anymore. However, it's possible that e.g., the remote connection drops just while a user types "nosharedlibrary", or some other reason that leads to objfile::~objfile, and then we end up the same std::terminate problem. Also notice that frames riscvarchive#9-riscvarchive#11 are BFD frames: riscvarchive#9 0x0000555555e09e3f in opncls_bclose (abfd=0x555556bc27e0) at src/bfd/opncls.c:599 riscvarchive#10 0x0000555555e0a2c7 in bfd_close_all_done (abfd=0x555556bc27e0) at src/bfd/opncls.c:847 riscvarchive#11 0x0000555555e0a27a in bfd_close (abfd=0x555556bc27e0) at src/bfd/opncls.c:814 BFD is written in C and thus throwing exceptions over such frames may either not clean up properly, or, may abort if bfd is not compiled with -fasynchronous-unwind-tables (x86-64 defaults that on, but not all GCC ports do). Thus frame riscvarchive#8 seems like a good place to swallow exceptions. More so since in this spot we already ignore target_fileio_close return errors. That's what this commit does. Without the previous fix, we'd see: (gdb) detach Detaching from program: target:/any/program, process 2197701 Ending remote debugging. [Inferior 1 (process 2197701) detached] warning: cannot close "target:/lib64/ld-linux-x86-64.so.2": Remote connection closed Note it prints a warning, which would still be a regression compared to GDB 10, if it weren't for the previous fix. gdb/ChangeLog: yyyy-mm-dd Pedro Alves <[email protected]> PR gdb/28080 * gdb_bfd.c (gdb_bfd_close_warning): New. (gdb_bfd_iovec_fileio_close): Wrap target_fileio_close in try/catch and print warning on exception. (gdb_bfd_close_or_warn): Use gdb_bfd_close_warning. Change-Id: Ic7a26ddba0a4444e3377b0e7c1c89934a84545d7
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Sep 27, 2021
Simon Marchi tried gdb on OpenBSD, and it immediately segfaults when running a program. Simon tracked down the problem to x86_dr_low.get_status being nullptr at this point: (lldb) print x86_dr_low.get_status (unsigned long (*)()) $0 = 0x0000000000000000 (lldb) bt * thread riscvarchive#1, stop reason = step over * frame #0: 0x0000033b64b764aa gdb`x86_dr_stopped_data_address(state=0x0000033d7162a310, addr_p=0x00007f7ffffc5688) at x86-dregs.c:645:12 frame riscvarchive#1: 0x0000033b64b766de gdb`x86_dr_stopped_by_watchpoint(state=0x0000033d7162a310) at x86-dregs.c:687:10 frame riscvarchive#2: 0x0000033b64ea5f72 gdb`x86_stopped_by_watchpoint() at x86-nat.c:206:10 frame riscvarchive#3: 0x0000033b64637fbb gdb`x86_nat_target<obsd_nat_target>::stopped_by_watchpoint(this=0x0000033b65252820) at x86-nat.h:100:12 frame riscvarchive#4: 0x0000033b64d3ff11 gdb`target_stopped_by_watchpoint() at target.c:468:46 frame riscvarchive#5: 0x0000033b6469b001 gdb`watchpoints_triggered(ws=0x00007f7ffffc61c8) at breakpoint.c:4790:32 frame riscvarchive#6: 0x0000033b64a8bb8b gdb`handle_signal_stop(ecs=0x00007f7ffffc61a0) at infrun.c:6072:29 frame riscvarchive#7: 0x0000033b64a7e3a7 gdb`handle_inferior_event(ecs=0x00007f7ffffc61a0) at infrun.c:5694:7 frame riscvarchive#8: 0x0000033b64a7c1a0 gdb`fetch_inferior_event() at infrun.c:4090:5 frame riscvarchive#9: 0x0000033b64a51921 gdb`inferior_event_handler(event_type=INF_REG_EVENT) at inf-loop.c:41:7 frame riscvarchive#10: 0x0000033b64a827c9 gdb`infrun_async_inferior_event_handler(data=0x0000000000000000) at infrun.c:9384:3 frame riscvarchive#11: 0x0000033b6465bd4f gdb`check_async_event_handlers() at async-event.c:335:4 frame riscvarchive#12: 0x0000033b65070917 gdb`gdb_do_one_event() at event-loop.cc:216:10 frame riscvarchive#13: 0x0000033b64af0db1 gdb`start_event_loop() at main.c:421:13 frame riscvarchive#14: 0x0000033b64aefe9a gdb`captured_command_loop() at main.c:481:3 frame riscvarchive#15: 0x0000033b64aed5c2 gdb`captured_main(data=0x00007f7ffffc6470) at main.c:1353:4 frame riscvarchive#16: 0x0000033b64aed4f2 gdb`gdb_main(args=0x00007f7ffffc6470) at main.c:1368:7 frame riscvarchive#17: 0x0000033b6459d787 gdb`main(argc=5, argv=0x00007f7ffffc6518) at gdb.c:32:10 frame riscvarchive#18: 0x0000033b6459d521 gdb`___start + 321 On BSDs, get_status is set in _initialize_x86_bsd_nat, but only if HAVE_PT_GETDBREGS is defined. PT_GETDBREGS doesn't exist on OpenBSD, so get_status (and the other fields of x86_dr_low) are left as nullptr. OpenBSD doesn't support getting or setting the x86 debug registers, so fix by omitting debug register support entirely on OpenBSD: - Change x86bsd_nat_target to only inherit from x86_nat_target if PT_GETDBREGS is supported. - Don't include x86-nat.o and nat/x86-dregs.o for OpenBSD/amd64. They were already omitted for OpenBSD/i386.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Sep 27, 2021
While working on the testsuite, I ended up noticing that GDB fails to produce a full backtrace from a thread waiting in pthread_join. When selecting the waiting thread and using the 'bt' command, the following result can be observed: (gdb) bt #0 0x0000003ff7fccd20 in __futex_abstimed_wait_common64 () from /lib/riscv64-linux-gnu/libpthread.so.0 riscvarchive#1 0x0000003ff7fc43da in __pthread_clockjoin_ex () from /lib/riscv64-linux-gnu/libpthread.so.0 Backtrace stopped: frame did not save the PC On my platform, I do not have debug symbols for glibc, so I need to rely on prologue analysis in order to unwind stack. Here is what the function prologue looks like: (gdb) disassemble __pthread_clockjoin_ex Dump of assembler code for function __pthread_clockjoin_ex: 0x0000003ff7fc42de <+0>: addi sp,sp,-144 0x0000003ff7fc42e0 <+2>: sd s5,88(sp) 0x0000003ff7fc42e2 <+4>: auipc s5,0xd 0x0000003ff7fc42e6 <+8>: ld s5,-2(s5) # 0x3ff7fd12e0 0x0000003ff7fc42ea <+12>: ld a5,0(s5) 0x0000003ff7fc42ee <+16>: sd ra,136(sp) 0x0000003ff7fc42f0 <+18>: sd s0,128(sp) 0x0000003ff7fc42f2 <+20>: sd s1,120(sp) 0x0000003ff7fc42f4 <+22>: sd s2,112(sp) 0x0000003ff7fc42f6 <+24>: sd s3,104(sp) 0x0000003ff7fc42f8 <+26>: sd s4,96(sp) 0x0000003ff7fc42fa <+28>: sd s6,80(sp) 0x0000003ff7fc42fc <+30>: sd s7,72(sp) 0x0000003ff7fc42fe <+32>: sd s8,64(sp) 0x0000003ff7fc4300 <+34>: sd s9,56(sp) 0x0000003ff7fc4302 <+36>: sd a5,40(sp) As far as prologue analysis is concerned, the most interesting part is done at address 0x0000003ff7fc42ee (<+16>): 'sd ra,136(sp)'. This stores the RA (return address) register on the stack, which is the information we are looking for in order to identify the caller. In the current implementation of the prologue scanner, GDB stops when hitting 0x0000003ff7fc42e6 (<+8>) because it does not know what to do with the 'ld' instruction. GDB thinks it reached the end of the prologue but have not yet reached the important part, which explain GDB's inability to unwind past this point. The section of the prologue starting at <+4> until <+12> is used to load the stack canary[1], which will then be placed on the stack at <+36> at the end of the prologue. In order to have the prologue properly handled, this commit proposes to add support for the ld instruction in the RISC-V prologue scanner. I guess riscv32 would use lw in such situation so this patch also adds support for this instruction. With this patch applied, gdb is now able to unwind past pthread_join: (gdb) bt #0 0x0000003ff7fccd20 in __futex_abstimed_wait_common64 () from /lib/riscv64-linux-gnu/libpthread.so.0 riscvarchive#1 0x0000003ff7fc43da in __pthread_clockjoin_ex () from /lib/riscv64-linux-gnu/libpthread.so.0 riscvarchive#2 0x0000002aaaaaa88e in bar() () riscvarchive#3 0x0000002aaaaaa8c4 in foo() () riscvarchive#4 0x0000002aaaaaa8da in main () I have had a look to see if I could reproduce this easily, but in my simple testcases using '-fstack-protector-all', the canary is loaded after the RA register is saved. I do not have a reliable way of generating a prologue similar to the problematic one so I forged one instead. The testsuite have been run on riscv64 ubuntu 21.01 with no regression observed. [1] https://en.wikipedia.org/wiki/Buffer_overflow_protection#Canaries
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Sep 27, 2021
The original reproducer for PR28030 required use of a specific compiler version - gcc-c++-11.1.1-3.fc34 is mentioned in the PR, though it seems probable that other gcc versions might also be able to reproduce the bug as well. This commit introduces a test case which, using the DWARF assembler, provides a reproducer which is independent of the compiler version. (Well, it'll work with whatever compilers the DWARF assembler works with.) To the best of my knowledge, it's also the first test case which uses the DWARF assembler to provide debug info for a shared object. That being the case, I provided more than the usual commentary which should allow this case to be used as a template when a combo shared library / DWARF assembler test case is required in the future. I provide some details regarding the bug in a comment near the beginning of locexpr-dml.exp. This problem was difficult to reproduce; I found myself constantly referring to the backtrace while trying to figure out what (else) I might be missing while trying to create a reproducer. Below is a partial backtrace which I include for posterity. #0 internal_error ( file=0xc50110 "/ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c", line=5575, fmt=0xc520c0 "Unexpected type field location kind: %d") at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdbsupport/errors.cc:51 riscvarchive#1 0x00000000006ef0c5 in copy_type_recursive (objfile=0x1635930, type=0x274c260, copied_types=0x30bb290) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c:5575 riscvarchive#2 0x00000000006ef382 in copy_type_recursive (objfile=0x1635930, type=0x274ca10, copied_types=0x30bb290) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c:5602 riscvarchive#3 0x0000000000a7409a in preserve_one_value (value=0x24269f0, objfile=0x1635930, copied_types=0x30bb290) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/value.c:2529 riscvarchive#4 0x000000000072012a in gdbscm_preserve_values ( extlang=0xc55720 <extension_language_guile>, objfile=0x1635930, copied_types=0x30bb290) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/guile/scm-value.c:94 riscvarchive#5 0x00000000006a3f82 in preserve_ext_lang_values (objfile=0x1635930, copied_types=0x30bb290) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/extension.c:568 riscvarchive#6 0x0000000000a7428d in preserve_values (objfile=0x1635930) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/value.c:2579 riscvarchive#7 0x000000000082d514 in objfile::~objfile (this=0x1635930, __in_chrg=<optimized out>) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:549 riscvarchive#8 0x0000000000831cc8 in std::_Sp_counted_ptr<objfile*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x1654580) at /usr/include/c++/11/bits/shared_ptr_base.h:348 riscvarchive#9 0x00000000004e6617 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x1654580) at /usr/include/c++/11/bits/shared_ptr_base.h:168 riscvarchive#10 0x00000000004e1d2f in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x190bb88, __in_chrg=<optimized out>) at /usr/include/c++/11/bits/shared_ptr_base.h:705 riscvarchive#11 0x000000000082feee in std::__shared_ptr<objfile, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x190bb80, __in_chrg=<optimized out>) at /usr/include/c++/11/bits/shared_ptr_base.h:1154 riscvarchive#12 0x000000000082ff0a in std::shared_ptr<objfile>::~shared_ptr ( this=0x190bb80, __in_chrg=<optimized out>) at /usr/include/c++/11/bits/shared_ptr.h:122 riscvarchive#13 0x000000000085ed7e in __gnu_cxx::new_allocator<std::_List_node<std::shared_ptr<objfile> > >::destroy<std::shared_ptr<objfile> > (this=0x114bc00, __p=0x190bb80) at /usr/include/c++/11/ext/new_allocator.h:168 riscvarchive#14 0x000000000085e88d in std::allocator_traits<std::allocator<std::_List_node<std::shared_ptr<objfile> > > >::destroy<std::shared_ptr<objfile> > (__a=..., __p=0x190bb80) at /usr/include/c++/11/bits/alloc_traits.h:531 riscvarchive#15 0x000000000085e50c in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::_M_erase (this=0x114bc00, __position= std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x1635930}) at /usr/include/c++/11/bits/stl_list.h:1925 riscvarchive#16 0x000000000085df0e in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::erase (this=0x114bc00, __position= std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x1635930}) at /usr/include/c++/11/bits/list.tcc:158 riscvarchive#17 0x000000000085c748 in program_space::remove_objfile (this=0x114bbc0, objfile=0x1635930) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/progspace.c:210 riscvarchive#18 0x000000000082d3ae in objfile::unlink (this=0x1635930) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:487 riscvarchive#19 0x000000000082e68c in objfile_purge_solibs () at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:875 riscvarchive#20 0x000000000092dd37 in no_shared_libraries (ignored=0x0, from_tty=1) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/solib.c:1236 riscvarchive#21 0x00000000009a37fe in target_pre_inferior (from_tty=1) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/target.c:2496 riscvarchive#22 0x00000000007454d6 in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/infcmd.c:437 I'll note a few points regarding this backtrace: Frame riscvarchive#1 is where the internal error occurs. It's caused by an unhandled case for FIELD_LOC_KIND_DWARF_BLOCK. The fix for this bug adds support for this case. Frame riscvarchive#22 - it's a partial backtrace - shows that GDB is attempting to (re)run the program. You can see the exact command sequence that was used for reproducing this problem in the PR (at https://sourceware.org/bugzilla/show_bug.cgi?id=28030), but in a nutshell, after starting the program and advancing to the appropriate source line, GDB was asked to step into libstdc++; a "finish" command was issued, returning a value. The fact that a value was returned is very important. GDB was then used to step back into libstdc++. A breakpoint was set on a source line in the library after which a "run" command was issued. Frame riscvarchive#19 shows a call to objfile_purge_solibs. It's aptly named. Frame riscvarchive#7 is a call to the destructor for one of the objfile solibs; it turned out to be the one for libstdc++. Frames riscvarchive#6 thru riscvarchive#3 show various value preservation frames. If you look at preserve_values() in gdb/value.c, the value history is preserved first, followed by internal variables, followed by values for the extension languages (python and guile).
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Sep 27, 2021
…es.exp When running test-case gdb.base/break-probes.exp on ubuntu 18.04.5, we have: ... (gdb) bt^M #0 0x00007ffff7dd6e12 in ?? () from /lib64/ld-linux-x86-64.so.2^M riscvarchive#1 0x00007ffff7dedf50 in ?? () from /lib64/ld-linux-x86-64.so.2^M riscvarchive#2 0x00007ffff7dd5128 in ?? () from /lib64/ld-linux-x86-64.so.2^M riscvarchive#3 0x00007ffff7dd4098 in ?? () from /lib64/ld-linux-x86-64.so.2^M riscvarchive#4 0x0000000000000001 in ?? ()^M riscvarchive#5 0x00007fffffffdaac in ?? ()^M riscvarchive#6 0x0000000000000000 in ?? ()^M (gdb) FAIL: gdb.base/break-probes.exp: ensure using probes ... The test-case intends to emit an UNTESTED in this case, but fails to do so because it tries to do it in a regexp clause in a gdb_test_multiple, which doesn't trigger. Instead, a default clause triggers which produces the FAIL. Also the use of UNTESTED is not appropriate, and we should use UNSUPPORTED instead. Fix this by silencing the FAIL, and emitting an UNSUPPORTED after the gdb_test_multiple: ... if { ! $using_probes } { + unsupported "probes not present on this system" return -1 } ... Tested on x86_64-linux.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Sep 27, 2021
When running test-case gdb.base/break-probes.exp on ubuntu 18.04.5, we have: ... (gdb) run^M Starting program: break-probes^M Stopped due to shared library event (no libraries added or removed)^M (gdb) bt^M #0 0x00007ffff7dd6e12 in ?? () from /lib64/ld-linux-x86-64.so.2^M riscvarchive#1 0x00007ffff7dedf50 in ?? () from /lib64/ld-linux-x86-64.so.2^M riscvarchive#2 0x00007ffff7dd5128 in ?? () from /lib64/ld-linux-x86-64.so.2^M riscvarchive#3 0x00007ffff7dd4098 in ?? () from /lib64/ld-linux-x86-64.so.2^M riscvarchive#4 0x0000000000000001 in ?? ()^M riscvarchive#5 0x00007fffffffdaac in ?? ()^M riscvarchive#6 0x0000000000000000 in ?? ()^M (gdb) UNSUPPORTED: gdb.base/break-probes.exp: probes not present on this system ... Using the backtrace, the test-case tries to establish that we're stopped in dl_main, which is used as proof that we're using probes. However, the backtrace only shows an address, because: - the dynamic linker contains no minimal symbols and no debug info, and - gdb is build without --with-separate-debug-dir so it can't find the corresponding .debug file, which does contain the mimimal symbols and debug info. Fix this by instead printing the pc and grepping for the value in the info probes output: ... (gdb) p /x $pc^M $1 = 0x7ffff7dd6e12^M (gdb) info probes^M Type Provider Name Where Object ^M ... stap rtld init_start 0x00007ffff7dd6e12 /lib64/ld-linux-x86-64.so.2 ^M ... (gdb) ... Tested on x86_64-linux.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
Sep 27, 2021
When running test-case gdb.base/break-interp.exp on ubuntu 18.04.5, we have: ... (gdb) bt^M #0 0x00007eff7ad5ae12 in ?? () from break-interp-LDprelinkNOdebugNO^M riscvarchive#1 0x00007eff7ad71f50 in ?? () from break-interp-LDprelinkNOdebugNO^M riscvarchive#2 0x00007eff7ad59128 in ?? () from break-interp-LDprelinkNOdebugNO^M riscvarchive#3 0x00007eff7ad58098 in ?? () from break-interp-LDprelinkNOdebugNO^M riscvarchive#4 0x0000000000000002 in ?? ()^M riscvarchive#5 0x00007fff505d7a32 in ?? ()^M riscvarchive#6 0x00007fff505d7a94 in ?? ()^M riscvarchive#7 0x0000000000000000 in ?? ()^M (gdb) FAIL: gdb.base/break-interp.exp: ldprelink=NO: ldsepdebug=NO: \ first backtrace: dl bt ... Using the backtrace, the test-case tries to establish that we're stopped in dl_main. However, the backtrace only shows an address, because: - the dynamic linker contains no minimal symbols and no debug info, and - gdb is build without --with-separate-debug-dir so it can't find the corresponding .debug file, which does contain the mimimal symbols and debug info. As in "[gdb/testsuite] Improve probe detection in gdb.base/break-probes.exp", fix this by doing info probes and grepping for the address. Tested on x86_64-linux.
kito-cheng
pushed a commit
that referenced
this pull request
Nov 23, 2021
On openSUSE Tumbleweed with glibc-debuginfo installed I get: ... (gdb) PASS: gdb.threads/linux-dp.exp: continue to breakpoint: thread 5's print where^M #0 print_philosopher (n=3, left=33 '!', right=33 '!') at linux-dp.c:105^M #1 0x0000000000401628 in philosopher (data=0x40537c) at linux-dp.c:148^M #2 0x00007ffff7d56b37 in start_thread (arg=<optimized out>) \ at pthread_create.c:435^M #3 0x00007ffff7ddb640 in clone3 () \ at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81^M (gdb) PASS: gdb.threads/linux-dp.exp: first thread-specific breakpoint hit ... while without debuginfo installed I get instead: ... (gdb) PASS: gdb.threads/linux-dp.exp: continue to breakpoint: thread 5's print where^M #0 print_philosopher (n=3, left=33 '!', right=33 '!') at linux-dp.c:105^M #1 0x0000000000401628 in philosopher (data=0x40537c) at linux-dp.c:148^M #2 0x00007ffff7d56b37 in start_thread () from /lib64/libc.so.6^M #3 0x00007ffff7ddb640 in clone3 () from /lib64/libc.so.6^M (gdb) FAIL: gdb.threads/linux-dp.exp: first thread-specific breakpoint hit ... The problem is that the regexp used: ... "\(from .*libpthread\|at pthread_create\|in pthread_create\)" ... expects the 'from' part to match libpthread, but in glibc 2.34 libpthread has been merged into libc. Fix this by updating the regexp. Tested on x86_64-linux.
kito-cheng
pushed a commit
that referenced
this pull request
Nov 23, 2021
This commit fixes Bug 28308, titled "Strange interactions with dprintf and break/commands": Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28308 Since creating that bug report, I've found a somewhat simpler way of reproducing the problem. I've encapsulated it into the GDB test case which I've created along with this bug fix. The name of the new test is gdb.base/dprintf-execution-x-script.exp, I'll demonstrate the problem using this test case, though for brevity, I've placed all relevant files in the same directory and have renamed the files to all start with 'dp-bug' instead of 'dprintf-execution-x-script'. The script file, named dp-bug.gdb, consists of the following commands: dprintf increment, "dprintf in increment(), vi=%d\n", vi break inc_vi commands continue end run Note that the final command in this script is 'run'. When 'run' is instead issued interactively, the bug does not occur. So, let's look at the interactive case first in order to see the correct/expected output: $ gdb -q -x dp-bug.gdb dp-bug ... eliding buggy output which I'll discuss later ... (gdb) run Starting program: /mesquite2/sourceware-git/f34-master/bld/gdb/tmp/dp-bug vi=0 dprintf in increment(), vi=0 Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 26 in dprintf-execution-x-script.c vi=1 dprintf in increment(), vi=1 Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 26 in dprintf-execution-x-script.c vi=2 dprintf in increment(), vi=2 Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 26 in dprintf-execution-x-script.c vi=3 [Inferior 1 (process 1539210) exited normally] In this run, in which 'run' was issued from the gdb prompt (instead of at the end of the script), there are three dprintf messages along with three 'Breakpoint 2' messages. This is the correct output. Now let's look at the output that I snipped above; this is the output when 'run' is issued from the script loaded via GDB's -x switch: $ gdb -q -x dp-bug.gdb dp-bug Reading symbols from dp-bug... Dprintf 1 at 0x40116e: file dprintf-execution-x-script.c, line 38. Breakpoint 2 at 0x40113a: file dprintf-execution-x-script.c, line 26. vi=0 dprintf in increment(), vi=0 Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 26 dprintf-execution-x-script.c: No such file or directory. vi=1 Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 26 in dprintf-execution-x-script.c vi=2 Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26 26 in dprintf-execution-x-script.c vi=3 [Inferior 1 (process 1539175) exited normally] In the output shown above, only the first dprintf message is printed. The 2nd and 3rd dprintf messages are missing! However, all three 'Breakpoint 2...' messages are still printed. Why does this happen? bpstat_do_actions_1() in gdb/breakpoint.c contains the following comment and code near the start of the function: /* Avoid endless recursion if a `source' command is contained in bs->commands. */ if (executing_breakpoint_commands) return 0; scoped_restore save_executing = make_scoped_restore (&executing_breakpoint_commands, 1); Also, as described by this comment prior to the 'async' field in 'struct ui' in top.h, the main UI starts off in sync mode when processing command line arguments: /* True if the UI is in async mode, false if in sync mode. If in sync mode, a synchronous execution command (e.g, "next") does not return until the command is finished. If in async mode, then running a synchronous command returns right after resuming the target. Waiting for the command's completion is later done on the top event loop. For the main UI, this starts out disabled, until all the explicit command line arguments (e.g., `gdb -ex "start" -ex "next"') are processed. */ This combination of things, the state of the static global 'executing_breakpoint_commands' plus the state of the async field in the main UI causes this behavior. This is a backtrace after hitting the dprintf breakpoint for the second time when doing 'run' from the script file, i.e. non-interactively: Thread 1 "gdb" hit Breakpoint 3, bpstat_do_actions_1 (bsp=0x7fffffffc2b8) at /ironwood1/sourceware-git/f34-master/bld/../../worktree-master/gdb/breakpoint.c:4431 4431 if (executing_breakpoint_commands) #0 bpstat_do_actions_1 (bsp=0x7fffffffc2b8) at gdb/breakpoint.c:4431 #1 0x00000000004d8bc6 in dprintf_after_condition_true (bs=0x1538090) at gdb/breakpoint.c:13048 #2 0x00000000004c5caa in bpstat_stop_status (aspace=0x116dbc0, bp_addr=0x40116e, thread=0x137f450, ws=0x7fffffffc718, stop_chain=0x1538090) at gdb/breakpoint.c:5498 #3 0x0000000000768d98 in handle_signal_stop (ecs=0x7fffffffc6f0) at gdb/infrun.c:6172 #4 0x00000000007678d3 in handle_inferior_event (ecs=0x7fffffffc6f0) at gdb/infrun.c:5662 #5 0x0000000000763cd5 in fetch_inferior_event () at gdb/infrun.c:4060 #6 0x0000000000746d7d in inferior_event_handler (event_type=INF_REG_EVENT) at gdb/inf-loop.c:41 #7 0x00000000007a702f in handle_target_event (error=0, client_data=0x0) at gdb/linux-nat.c:4207 #8 0x0000000000b8cd6e in gdb_wait_for_event (block=block@entry=0) at gdbsupport/event-loop.cc:701 #9 0x0000000000b8d032 in gdb_wait_for_event (block=0) at gdbsupport/event-loop.cc:597 #10 gdb_do_one_event () at gdbsupport/event-loop.cc:212 #11 0x00000000009d19b6 in wait_sync_command_done () at gdb/top.c:528 #12 0x00000000009d1a3f in maybe_wait_sync_command_done (was_sync=0) at gdb/top.c:545 #13 0x00000000009d2033 in execute_command (p=0x7fffffffcb18 "", from_tty=0) at gdb/top.c:676 #14 0x0000000000560d5b in execute_control_command_1 (cmd=0x13b9bb0, from_tty=0) at gdb/cli/cli-script.c:547 #15 0x000000000056134a in execute_control_command (cmd=0x13b9bb0, from_tty=0) at gdb/cli/cli-script.c:717 #16 0x00000000004c3bbe in bpstat_do_actions_1 (bsp=0x137f530) at gdb/breakpoint.c:4469 #17 0x00000000004c3d40 in bpstat_do_actions () at gdb/breakpoint.c:4533 #18 0x00000000006a473a in command_handler (command=0x1399ad0 "run") at gdb/event-top.c:624 #19 0x00000000009d182e in read_command_file (stream=0x113e540) at gdb/top.c:443 #20 0x0000000000563697 in script_from_file (stream=0x113e540, file=0x13bb0b0 "dp-bug.gdb") at gdb/cli/cli-script.c:1642 #21 0x00000000006abd63 in source_gdb_script (extlang=0xc44e80 <extension_language_gdb>, stream=0x113e540, file=0x13bb0b0 "dp-bug.gdb") at gdb/extension.c:188 #22 0x0000000000544400 in source_script_from_stream (stream=0x113e540, file=0x7fffffffd91a "dp-bug.gdb", file_to_open=0x13bb0b0 "dp-bug.gdb") at gdb/cli/cli-cmds.c:692 #23 0x0000000000544557 in source_script_with_search (file=0x7fffffffd91a "dp-bug.gdb", from_tty=1, search_path=0) at gdb/cli/cli-cmds.c:750 #24 0x00000000005445cf in source_script (file=0x7fffffffd91a "dp-bug.gdb", from_tty=1) at gdb/cli/cli-cmds.c:759 #25 0x00000000007cf6d9 in catch_command_errors (command=0x5445aa <source_script(char const*, int)>, arg=0x7fffffffd91a "dp-bug.gdb", from_tty=1, do_bp_actions=false) at gdb/main.c:523 #26 0x00000000007cf85d in execute_cmdargs (cmdarg_vec=0x7fffffffd1b0, file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND, ret=0x7fffffffd18c) at gdb/main.c:615 #27 0x00000000007d0c8e in captured_main_1 (context=0x7fffffffd3f0) at gdb/main.c:1322 #28 0x00000000007d0eba in captured_main (data=0x7fffffffd3f0) at gdb/main.c:1343 #29 0x00000000007d0f25 in gdb_main (args=0x7fffffffd3f0) at gdb/main.c:1368 #30 0x00000000004186dd in main (argc=5, argv=0x7fffffffd508) at gdb/gdb.c:32 There are two frames for bpstat_do_actions_1(), one at frame #16 and the other at frame #0. The one at frame #16 is processing the actions for Breakpoint 2, which is a 'continue'. The one at frame #0 is attempting to process the dprintf breakpoint action. However, at this point, the value of 'executing_breakpoint_commands' is 1, forcing an early return, i.e. prior to executing the command(s) associated with the dprintf breakpoint. For the sake of comparison, this is what the stack looks like when hitting the dprintf breakpoint for the second time when issuing the 'run' command from the GDB prompt. Thread 1 "gdb" hit Breakpoint 3, bpstat_do_actions_1 (bsp=0x7fffffffccd8) at /ironwood1/sourceware-git/f34-master/bld/../../worktree-master/gdb/breakpoint.c:4431 4431 if (executing_breakpoint_commands) #0 bpstat_do_actions_1 (bsp=0x7fffffffccd8) at gdb/breakpoint.c:4431 #1 0x00000000004d8bc6 in dprintf_after_condition_true (bs=0x16b0290) at gdb/breakpoint.c:13048 #2 0x00000000004c5caa in bpstat_stop_status (aspace=0x116dbc0, bp_addr=0x40116e, thread=0x13f0e60, ws=0x7fffffffd138, stop_chain=0x16b0290) at gdb/breakpoint.c:5498 #3 0x0000000000768d98 in handle_signal_stop (ecs=0x7fffffffd110) at gdb/infrun.c:6172 #4 0x00000000007678d3 in handle_inferior_event (ecs=0x7fffffffd110) at gdb/infrun.c:5662 #5 0x0000000000763cd5 in fetch_inferior_event () at gdb/infrun.c:4060 #6 0x0000000000746d7d in inferior_event_handler (event_type=INF_REG_EVENT) at gdb/inf-loop.c:41 #7 0x00000000007a702f in handle_target_event (error=0, client_data=0x0) at gdb/linux-nat.c:4207 #8 0x0000000000b8cd6e in gdb_wait_for_event (block=block@entry=0) at gdbsupport/event-loop.cc:701 #9 0x0000000000b8d032 in gdb_wait_for_event (block=0) at gdbsupport/event-loop.cc:597 #10 gdb_do_one_event () at gdbsupport/event-loop.cc:212 #11 0x00000000007cf512 in start_event_loop () at gdb/main.c:421 #12 0x00000000007cf631 in captured_command_loop () at gdb/main.c:481 #13 0x00000000007d0ebf in captured_main (data=0x7fffffffd3f0) at gdb/main.c:1353 #14 0x00000000007d0f25 in gdb_main (args=0x7fffffffd3f0) at gdb/main.c:1368 #15 0x00000000004186dd in main (argc=5, argv=0x7fffffffd508) at gdb/gdb.c:32 This relatively short backtrace is due to the current UI's async field being set to 1. Yet another thing to be aware of regarding this problem is the difference in the way that commands associated to dprintf breakpoints versus regular breakpoints are handled. While they both use a command list associated with the breakpoint, regular breakpoints will place the commands to be run on the bpstat chain constructed in bp_stop_status(). These commands are run later on. For dprintf breakpoints, commands are run via the 'after_condition_true' function pointer directly from bpstat_stop_status(). (The 'commands' field in the bpstat is cleared in dprintf_after_condition_true(). This prevents the dprintf commands from being run again later on when other commands on the bpstat chain are processed.) Another thing that I noticed is that dprintf breakpoints are the only type of breakpoint which use 'after_condition_true'. This suggests that one possible way of fixing this problem, that of making dprintf breakpoints work more like regular breakpoints, probably won't work. (I must admit, however, that my understanding of this code isn't complete enough to say why. I'll trust that whoever implemented it had a good reason for doing it this way.) The comment referenced earlier regarding 'executing_breakpoint_commands' states that the reason for checking this variable is to avoid potential endless recursion when a 'source' command appears in bs->commands. We know that a dprintf command is constrained to either 1) execution of a GDB printf command, 2) an inferior function call of a printf-like function, or 3) execution of an agent-printf command. Therefore, infinite recursion due to a 'source' command cannot happen when executing commands upon hitting a dprintf breakpoint. I chose to fix this problem by having dprintf_after_condition_true() directly call execute_control_commands(). This means that it no longer attempts to go through bpstat_do_actions_1() avoiding the infinite recursion check for potential 'source' commands on the command chain. I think it simplifies this code a little bit too, a definite bonus. Summary: * breakpoint.c (dprintf_after_condition_true): Don't call bpstat_do_actions_1(). Call execute_control_commands() instead.
Nelson1225
pushed a commit
that referenced
this pull request
Feb 10, 2022
Fedora Rawhide is now using gcc-12.0. As part of updating to the gcc-12.0 package set, Rawhide is also now using a version of libgcc_s which lacks a .data section. This causes gdb to fail in the following fashion while debugging a program (such as gdb) which uses libgcc_s: (top-gdb) run Starting program: rawhide-master/bld/gdb/gdb ... objfiles.h:467: internal-error: sect_index_data not initialized A problem internal to GDB has been detected, further debugging may prove unreliable. ... I snipped the backtrace from the above output. Instead, here's a portion of a backtrace obtained using GDB's backtrace command. (Obviously, in order to obtain it, I used a GDB which has been patched with this commit.) #0 internal_error ( file=0xc6a508 "gdb/objfiles.h", line=467, fmt=0xc6a4e8 "sect_index_data not initialized") at gdbsupport/errors.cc:51 #1 0x00000000005f9651 in objfile::data_section_offset (this=0x4fa48f0) at gdb/objfiles.h:467 #2 0x000000000097c5f8 in relocate_address (address=0x17244, objfile=0x4fa48f0) at gdb/stap-probe.c:1333 #3 0x000000000097c630 in stap_probe::get_relocated_address (this=0xa1a17a0, objfile=0x4fa48f0) at gdb/stap-probe.c:1341 #4 0x00000000004d7025 in create_exception_master_breakpoint_probe ( objfile=0x4fa48f0) at gdb/breakpoint.c:3505 #5 0x00000000004d7426 in create_exception_master_breakpoint () at gdb/breakpoint.c:3575 #6 0x00000000004efcc1 in breakpoint_re_set () at gdb/breakpoint.c:13407 #7 0x0000000000956998 in solib_add (pattern=0x0, from_tty=0, readsyms=1) at gdb/solib.c:1001 #8 0x00000000009576a8 in handle_solib_event () at gdb/solib.c:1269 ... The function 'relocate_address' in gdb/stap-probe.c attempts to do its "relocation" by using objfile->data_section_offset(). That method, data_section_offset() is defined as follows in objfiles.h: CORE_ADDR data_section_offset () const { return section_offsets[SECT_OFF_DATA (this)]; } The internal error occurs when the SECT_OFF_DATA macro finds that the 'sect_index_data' field is -1: #define SECT_OFF_DATA(objfile) \ ((objfile->sect_index_data == -1) \ ? (internal_error (__FILE__, __LINE__, \ _("sect_index_data not initialized")), -1) \ : objfile->sect_index_data) relocate_address() is obtaining the section offset in order to compute a relocated address. For some ABIs, such as the System V ABI, the section offsets will all be the same. So for those ABIs, it doesn't matter which offset is used. However, other ABIs, such as the FDPIC ABI, will have different offsets for the various sections. Thus, for those ABIs, it is vital that this and other relocation code use the correct offset. In stap_probe::get_relocated_address, the address to which to add the offset (thus forming the relocated address) is obtained via this->get_address (); get_address is a getter for m_address in probe.h. It's documented/defined as follows (also in probe.h): /* The address where the probe is inserted, relative to SECT_OFF_TEXT. */ CORE_ADDR m_address; (Thanks to Tom Tromey for this observation.) So, based on this, the current use of data_section_offset / SECT_OFF_DATA is wrong. This relocation code should have been using text_section_offset / SECT_OFF_TEXT all along. That being the case, I've adjusted the stap-probe.c relocation code accordingly. Searching the sources turned up one other use of data_section_offset, in gdb/dtrace-probe.c, so I've updated that code as well. The same reasoning presented above applies to this case too. Summary: * gdb/dtrace-probe.c (dtrace_probe::get_relocated_address): Use method text_section_offset instead of data_section_offset. * gdb/stap-probe.c (relocate_address): Likewise.
Nelson1225
pushed a commit
that referenced
this pull request
Feb 10, 2022
g++ 11.1.0 has a bug where it will emit a negative DW_AT_data_member_location in some cases: $ cat test.cpp #include <memory> int main() { std::unique_ptr<int> ptr; } $ g++ -g test.cpp $ llvm-dwarfdump -F a.out ... 0x00000964: DW_TAG_member DW_AT_name [DW_FORM_strp] ("_M_head_impl") DW_AT_decl_file [DW_FORM_data1] ("/usr/include/c++/11.1.0/tuple") DW_AT_decl_line [DW_FORM_data1] (125) DW_AT_decl_column [DW_FORM_data1] (0x27) DW_AT_type [DW_FORM_ref4] (0x0000067a "default_delete<int>") DW_AT_data_member_location [DW_FORM_sdata] (-1) ... This leads to a GDB crash (when built with ASan, otherwise probably garbage results), since it tries to read just before (to the left, in ASan speak) of the value's buffer: ==888645==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000c52af at pc 0x7f711b239f4b bp 0x7fff356bd470 sp 0x7fff356bcc18 READ of size 1 at 0x6020000c52af thread T0 #0 0x7f711b239f4a in __interceptor_memcpy /build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 #1 0x555c4977efa1 in value_contents_copy_raw /home/simark/src/binutils-gdb/gdb/value.c:1347 #2 0x555c497909cd in value_primitive_field(value*, long, int, type*) /home/simark/src/binutils-gdb/gdb/value.c:3126 #3 0x555c478f2eaa in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:333 #4 0x555c478f63b2 in cp_print_value /home/simark/src/binutils-gdb/gdb/cp-valprint.c:513 #5 0x555c478f02ca in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:161 #6 0x555c478f63b2 in cp_print_value /home/simark/src/binutils-gdb/gdb/cp-valprint.c:513 #7 0x555c478f02ca in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:161 #8 0x555c478f63b2 in cp_print_value /home/simark/src/binutils-gdb/gdb/cp-valprint.c:513 #9 0x555c478f02ca in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:161 #10 0x555c4760d45f in c_value_print_struct /home/simark/src/binutils-gdb/gdb/c-valprint.c:383 #11 0x555c4760df4c in c_value_print_inner(value*, ui_file*, int, value_print_options const*) /home/simark/src/binutils-gdb/gdb/c-valprint.c:438 #12 0x555c483ff9a7 in language_defn::value_print_inner(value*, ui_file*, int, value_print_options const*) const /home/simark/src/binutils-gdb/gdb/language.c:632 #13 0x555c49758b68 in do_val_print /home/simark/src/binutils-gdb/gdb/valprint.c:1048 #14 0x555c49759b17 in common_val_print(value*, ui_file*, int, value_print_options const*, language_defn const*) /home/simark/src/binutils-gdb/gdb/valprint.c:1151 #15 0x555c478f2fcb in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:335 #16 0x555c478f63b2 in cp_print_value /home/simark/src/binutils-gdb/gdb/cp-valprint.c:513 #17 0x555c478f02ca in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:161 #18 0x555c4760d45f in c_value_print_struct /home/simark/src/binutils-gdb/gdb/c-valprint.c:383 #19 0x555c4760df4c in c_value_print_inner(value*, ui_file*, int, value_print_options const*) /home/simark/src/binutils-gdb/gdb/c-valprint.c:438 #20 0x555c483ff9a7 in language_defn::value_print_inner(value*, ui_file*, int, value_print_options const*) const /home/simark/src/binutils-gdb/gdb/language.c:632 #21 0x555c49758b68 in do_val_print /home/simark/src/binutils-gdb/gdb/valprint.c:1048 #22 0x555c49759b17 in common_val_print(value*, ui_file*, int, value_print_options const*, language_defn const*) /home/simark/src/binutils-gdb/gdb/valprint.c:1151 #23 0x555c478f2fcb in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:335 #24 0x555c4760d45f in c_value_print_struct /home/simark/src/binutils-gdb/gdb/c-valprint.c:383 #25 0x555c4760df4c in c_value_print_inner(value*, ui_file*, int, value_print_options const*) /home/simark/src/binutils-gdb/gdb/c-valprint.c:438 #26 0x555c483ff9a7 in language_defn::value_print_inner(value*, ui_file*, int, value_print_options const*) const /home/simark/src/binutils-gdb/gdb/language.c:632 #27 0x555c49758b68 in do_val_print /home/simark/src/binutils-gdb/gdb/valprint.c:1048 #28 0x555c49759b17 in common_val_print(value*, ui_file*, int, value_print_options const*, language_defn const*) /home/simark/src/binutils-gdb/gdb/valprint.c:1151 #29 0x555c4760f04c in c_value_print(value*, ui_file*, value_print_options const*) /home/simark/src/binutils-gdb/gdb/c-valprint.c:587 #30 0x555c483ff954 in language_defn::value_print(value*, ui_file*, value_print_options const*) const /home/simark/src/binutils-gdb/gdb/language.c:614 #31 0x555c49759f61 in value_print(value*, ui_file*, value_print_options const*) /home/simark/src/binutils-gdb/gdb/valprint.c:1189 #32 0x555c48950f70 in print_formatted /home/simark/src/binutils-gdb/gdb/printcmd.c:337 #33 0x555c48958eda in print_value(value*, value_print_options const&) /home/simark/src/binutils-gdb/gdb/printcmd.c:1258 #34 0x555c48959891 in print_command_1 /home/simark/src/binutils-gdb/gdb/printcmd.c:1367 #35 0x555c4895a3df in print_command /home/simark/src/binutils-gdb/gdb/printcmd.c:1458 #36 0x555c4767f974 in do_simple_func /home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:97 #37 0x555c47692e25 in cmd_func(cmd_list_element*, char const*, int) /home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:2475 #38 0x555c4936107e in execute_command(char const*, int) /home/simark/src/binutils-gdb/gdb/top.c:670 #39 0x555c485f1bff in catch_command_errors /home/simark/src/binutils-gdb/gdb/main.c:523 #40 0x555c485f249c in execute_cmdargs /home/simark/src/binutils-gdb/gdb/main.c:618 #41 0x555c485f6677 in captured_main_1 /home/simark/src/binutils-gdb/gdb/main.c:1317 #42 0x555c485f6c83 in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1338 #43 0x555c485f6d65 in gdb_main(captured_main_args*) /home/simark/src/binutils-gdb/gdb/main.c:1363 #44 0x555c46e41ba8 in main /home/simark/src/binutils-gdb/gdb/gdb.c:32 #45 0x7f71198bcb24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24) #46 0x555c46e4197d in _start (/home/simark/build/binutils-gdb-one-target/gdb/gdb+0x77f197d) 0x6020000c52af is located 1 bytes to the left of 8-byte region [0x6020000c52b0,0x6020000c52b8) allocated by thread T0 here: #0 0x7f711b2b7459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154 #1 0x555c470acdc9 in xcalloc /home/simark/src/binutils-gdb/gdb/alloc.c:100 #2 0x555c49b775cd in xzalloc(unsigned long) /home/simark/src/binutils-gdb/gdbsupport/common-utils.cc:29 #3 0x555c4977bdeb in allocate_value_contents /home/simark/src/binutils-gdb/gdb/value.c:1029 #4 0x555c4977be25 in allocate_value(type*) /home/simark/src/binutils-gdb/gdb/value.c:1040 #5 0x555c4979030d in value_primitive_field(value*, long, int, type*) /home/simark/src/binutils-gdb/gdb/value.c:3092 #6 0x555c478f6280 in cp_print_value /home/simark/src/binutils-gdb/gdb/cp-valprint.c:501 #7 0x555c478f02ca in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:161 #8 0x555c478f63b2 in cp_print_value /home/simark/src/binutils-gdb/gdb/cp-valprint.c:513 #9 0x555c478f02ca in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:161 #10 0x555c478f63b2 in cp_print_value /home/simark/src/binutils-gdb/gdb/cp-valprint.c:513 #11 0x555c478f02ca in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:161 #12 0x555c4760d45f in c_value_print_struct /home/simark/src/binutils-gdb/gdb/c-valprint.c:383 #13 0x555c4760df4c in c_value_print_inner(value*, ui_file*, int, value_print_options const*) /home/simark/src/binutils-gdb/gdb/c-valprint.c:438 #14 0x555c483ff9a7 in language_defn::value_print_inner(value*, ui_file*, int, value_print_options const*) const /home/simark/src/binutils-gdb/gdb/language.c:632 #15 0x555c49758b68 in do_val_print /home/simark/src/binutils-gdb/gdb/valprint.c:1048 #16 0x555c49759b17 in common_val_print(value*, ui_file*, int, value_print_options const*, language_defn const*) /home/simark/src/binutils-gdb/gdb/valprint.c:1151 #17 0x555c478f2fcb in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:335 #18 0x555c478f63b2 in cp_print_value /home/simark/src/binutils-gdb/gdb/cp-valprint.c:513 #19 0x555c478f02ca in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:161 #20 0x555c4760d45f in c_value_print_struct /home/simark/src/binutils-gdb/gdb/c-valprint.c:383 #21 0x555c4760df4c in c_value_print_inner(value*, ui_file*, int, value_print_options const*) /home/simark/src/binutils-gdb/gdb/c-valprint.c:438 #22 0x555c483ff9a7 in language_defn::value_print_inner(value*, ui_file*, int, value_print_options const*) const /home/simark/src/binutils-gdb/gdb/language.c:632 #23 0x555c49758b68 in do_val_print /home/simark/src/binutils-gdb/gdb/valprint.c:1048 #24 0x555c49759b17 in common_val_print(value*, ui_file*, int, value_print_options const*, language_defn const*) /home/simark/src/binutils-gdb/gdb/valprint.c:1151 #25 0x555c478f2fcb in cp_print_value_fields(value*, ui_file*, int, value_print_options const*, type**, int) /home/simark/src/binutils-gdb/gdb/cp-valprint.c:335 #26 0x555c4760d45f in c_value_print_struct /home/simark/src/binutils-gdb/gdb/c-valprint.c:383 #27 0x555c4760df4c in c_value_print_inner(value*, ui_file*, int, value_print_options const*) /home/simark/src/binutils-gdb/gdb/c-valprint.c:438 #28 0x555c483ff9a7 in language_defn::value_print_inner(value*, ui_file*, int, value_print_options const*) const /home/simark/src/binutils-gdb/gdb/language.c:632 #29 0x555c49758b68 in do_val_print /home/simark/src/binutils-gdb/gdb/valprint.c:1048 Since there are some binaries with this in the wild, I think it would be useful for GDB to work around this. I did the obvious simple thing, if the DW_AT_data_member_location's value is -1, replace it with 0. I added a producer check to only apply this fixup for GCC 11. The idea is that if some other compiler ever uses a DW_AT_data_member_location value of -1 by mistake, we don't know (before analyzing the bug at least) if they did mean 0 or some other value. So I wouldn't want to apply the fixup in that case. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28063 Change-Id: Ieef3459b0b9bbce8bdad838ba83b4b64e7269d42
Nelson1225
pushed a commit
that referenced
this pull request
Feb 10, 2022
Starting with commit commit 1da5d0e Date: Tue Jan 4 08:02:24 2022 -0700 Change how Python architecture and language are handled we see a failure in gdb.threads/killed-outside.exp: ... Executing on target: kill -9 16622 (timeout = 300) builtin_spawn -ignore SIGHUP kill -9 16622 continue Continuing. Couldn't get registers: No such process. (gdb) [Thread 0x7ffff77c2700 (LWP 16626) exited] Program terminated with signal SIGKILL, Killed. The program no longer exists. FAIL: gdb.threads/killed-outside.exp: prompt after first continue (timeout) This is not a regression but a failure due to a change in GDB's output. Prior to the aforementioned commit, GDB has been printing the "Couldn't get registers: No such process." message twice. The second one came from (top-gdb) bt #0 amd64_linux_nat_target::fetch_registers (this=0x555557f31440 <the_amd64_linux_nat_target>, regcache=0x555558805ce0, regnum=16) at /gdb-up/gdb/amd64-linux-nat.c:225 #1 0x000055555640ac5f in target_ops::fetch_registers (this=0x555557d636d0 <the_thread_db_target>, arg0=0x555558805ce0, arg1=16) at /gdb-up/gdb/target-delegates.c:502 #2 0x000055555641a647 in target_fetch_registers (regcache=0x555558805ce0, regno=16) at /gdb-up/gdb/target.c:3945 #3 0x0000555556278e68 in regcache::raw_update (this=0x555558805ce0, regnum=16) at /gdb-up/gdb/regcache.c:587 #4 0x0000555556278f14 in readable_regcache::raw_read (this=0x555558805ce0, regnum=16, buf=0x555558881950 "") at /gdb-up/gdb/regcache.c:601 #5 0x00005555562792aa in readable_regcache::cooked_read (this=0x555558805ce0, regnum=16, buf=0x555558881950 "") at /gdb-up/gdb/regcache.c:690 #6 0x000055555627965e in readable_regcache::cooked_read_value (this=0x555558805ce0, regnum=16) at /gdb-up/gdb/regcache.c:748 #7 0x0000555556352a37 in sentinel_frame_prev_register (this_frame=0x555558181090, this_prologue_cache=0x5555581810a8, regnum=16) at /gdb-up/gdb/sentinel-frame.c:53 #8 0x0000555555fa4773 in frame_unwind_register_value (next_frame=0x555558181090, regnum=16) at /gdb-up/gdb/frame.c:1235 #9 0x0000555555fa420d in frame_register_unwind (next_frame=0x555558181090, regnum=16, optimizedp=0x7fffffffd570, unavailablep=0x7fffffffd574, lvalp=0x7fffffffd57c, addrp=0x7fffffffd580, realnump=0x7fffffffd578, bufferp=0x7fffffffd5b0 "") at /gdb-up/gdb/frame.c:1143 #10 0x0000555555fa455f in frame_unwind_register (next_frame=0x555558181090, regnum=16, buf=0x7fffffffd5b0 "") at /gdb-up/gdb/frame.c:1199 #11 0x00005555560178e2 in i386_unwind_pc (gdbarch=0x5555587c4a70, next_frame=0x555558181090) at /gdb-up/gdb/i386-tdep.c:1972 #12 0x0000555555cd2b9d in gdbarch_unwind_pc (gdbarch=0x5555587c4a70, next_frame=0x555558181090) at /gdb-up/gdb/gdbarch.c:3007 #13 0x0000555555fa3a5b in frame_unwind_pc (this_frame=0x555558181090) at /gdb-up/gdb/frame.c:948 #14 0x0000555555fa7621 in get_frame_pc (frame=0x555558181160) at /gdb-up/gdb/frame.c:2572 #15 0x0000555555fa7706 in get_frame_address_in_block (this_frame=0x555558181160) at /gdb-up/gdb/frame.c:2602 #16 0x0000555555fa77d0 in get_frame_address_in_block_if_available (this_frame=0x555558181160, pc=0x7fffffffd708) at /gdb-up/gdb/frame.c:2665 #17 0x0000555555fa5f8d in select_frame (fi=0x555558181160) at /gdb-up/gdb/frame.c:1890 #18 0x0000555555fa5bab in lookup_selected_frame (a_frame_id=..., frame_level=-1) at /gdb-up/gdb/frame.c:1720 #19 0x0000555555fa5e47 in get_selected_frame (message=0x0) at /gdb-up/gdb/frame.c:1810 #20 0x0000555555cc9c6e in get_current_arch () at /gdb-up/gdb/arch-utils.c:848 #21 0x000055555625b239 in gdbpy_before_prompt_hook (extlang=0x555557451f20 <extension_language_python>, current_gdb_prompt=0x555557f4d890 <top_prompt+16> "(gdb) ") at /gdb-up/gdb/python/python.c:1063 #22 0x0000555555f7cfbb in ext_lang_before_prompt (current_gdb_prompt=0x555557f4d890 <top_prompt+16> "(gdb) ") at /gdb-up/gdb/extension.c:922 #23 0x0000555555f7d442 in std::_Function_handler<void (char const*), void (*)(char const*)>::_M_invoke(std::_Any_data const&, char const*&&) (__functor=..., __args#0=@0x7fffffffd900: 0x555557f4d890 <top_prompt+16> "(gdb) ") at /usr/include/c++/7/bits/std_function.h:316 #24 0x0000555555f752dd in std::function<void (char const*)>::operator()(char const*) const (this=0x55555817d838, __args#0=0x555557f4d890 <top_prompt+16> "(gdb) ") at /usr/include/c++/7/bits/std_function.h:706 #25 0x0000555555f75100 in gdb::observers::observable<char const*>::notify (this=0x555557f49060 <gdb::observers::before_prompt>, args#0=0x555557f4d890 <top_prompt+16> "(gdb) ") at /gdb-up/gdb/../gdbsupport/observable.h:150 #26 0x0000555555f736dc in top_level_prompt () at /gdb-up/gdb/event-top.c:444 #27 0x0000555555f735ba in display_gdb_prompt (new_prompt=0x0) at /gdb-up/gdb/event-top.c:411 #28 0x00005555564611a7 in tui_on_command_error () at /gdb-up/gdb/tui/tui-interp.c:205 #29 0x0000555555c2173f in std::_Function_handler<void (), void (*)()>::_M_invoke(std::_Any_data const&) (__functor=...) at /usr/include/c++/7/bits/std_function.h:316 #30 0x0000555555e10c20 in std::function<void ()>::operator()() const (this=0x5555580f9028) at /usr/include/c++/7/bits/std_function.h:706 #31 0x0000555555e10973 in gdb::observers::observable<>::notify() const (this=0x555557f48d20 <gdb::observers::command_error>) at /gdb-up/gdb/../gdbsupport/observable.h:150 #32 0x00005555560e9b3f in start_event_loop () at /gdb-up/gdb/main.c:438 #33 0x00005555560e9bcc in captured_command_loop () at /gdb-up/gdb/main.c:481 #34 0x00005555560eb616 in captured_main (data=0x7fffffffddd0) at /gdb-up/gdb/main.c:1348 #35 0x00005555560eb67c in gdb_main (args=0x7fffffffddd0) at /gdb-up/gdb/main.c:1363 #36 0x0000555555c1b6b3 in main (argc=12, argv=0x7fffffffded8) at /gdb-up/gdb/gdb.c:32 Commit 1da5d0e eliminated the call to 'get_current_arch' in 'gdbpy_before_prompt_hook'. Hence, the second instance of "Couldn't get registers: No such process." does not appear anymore. Fix the failure by updating the regular expression in the test.
pz9115
pushed a commit
to plctlab/riscv-binutils-gdb
that referenced
this pull request
Mar 7, 2022
…ync." Commit 14b3360 ("do_target_wait_1: Clear TARGET_WNOHANG if the target isn't async.") broke some multi-target tests, such as gdb.multi/multi-target-info-inferiors.exp. The symptom is that execution just hangs at some point. What happens is: 1. One remote inferior is started, and now sits stopped at a breakpoint. It is not "async" at this point (but it "can async"). 2. We run a native inferior, the event loop gets woken up by the native target's fd. 3. In do_target_wait, we randomly choose an inferior to call target_wait on first, it happens to be the remote inferior. 4. Because the target is currently not "async", we clear TARGET_WNOHANG, resulting in synchronous wait. We therefore block here: #0 0x00007fe9540dbb4d in select () from /usr/lib/libc.so.6 #1 0x000055fc7e821da7 in gdb_select (n=15, readfds=0x7ffdb77c1fb0, writefds=0x0, exceptfds=0x7ffdb77c2050, timeout=0x7ffdb77c1f90) at /home/simark/src/binutils-gdb/gdb/posix-hdep.c:31 #2 0x000055fc7ddef905 in interruptible_select (n=15, readfds=0x7ffdb77c1fb0, writefds=0x0, exceptfds=0x7ffdb77c2050, timeout=0x7ffdb77c1f90) at /home/simark/src/binutils-gdb/gdb/event-top.c:1134 riscvarchive#3 0x000055fc7eda58e4 in ser_base_wait_for (scb=0x6250002e4100, timeout=1) at /home/simark/src/binutils-gdb/gdb/ser-base.c:240 riscvarchive#4 0x000055fc7eda66ba in do_ser_base_readchar (scb=0x6250002e4100, timeout=-1) at /home/simark/src/binutils-gdb/gdb/ser-base.c:365 riscvarchive#5 0x000055fc7eda6ff6 in generic_readchar (scb=0x6250002e4100, timeout=-1, do_readchar=0x55fc7eda663c <do_ser_base_readchar(serial*, int)>) at /home/simark/src/binutils-gdb/gdb/ser-base.c:444 riscvarchive#6 0x000055fc7eda718a in ser_base_readchar (scb=0x6250002e4100, timeout=-1) at /home/simark/src/binutils-gdb/gdb/ser-base.c:471 riscvarchive#7 0x000055fc7edb1ecd in serial_readchar (scb=0x6250002e4100, timeout=-1) at /home/simark/src/binutils-gdb/gdb/serial.c:393 riscvarchive#8 0x000055fc7ec48b8f in remote_target::readchar (this=0x617000038780, timeout=-1) at /home/simark/src/binutils-gdb/gdb/remote.c:9446 riscvarchive#9 0x000055fc7ec4da82 in remote_target::getpkt_or_notif_sane_1 (this=0x617000038780, buf=0x6170000387a8, forever=1, expecting_notif=1, is_notif=0x7ffdb77c24f0) at /home/simark/src/binutils-gdb/gdb/remote.c:9928 riscvarchive#10 0x000055fc7ec4f045 in remote_target::getpkt_or_notif_sane (this=0x617000038780, buf=0x6170000387a8, forever=1, is_notif=0x7ffdb77c24f0) at /home/simark/src/binutils-gdb/gdb/remote.c:10037 riscvarchive#11 0x000055fc7ec354d4 in remote_target::wait_ns (this=0x617000038780, ptid=..., status=0x7ffdb77c33c8, options=...) at /home/simark/src/binutils-gdb/gdb/remote.c:8147 riscvarchive#12 0x000055fc7ec38aa1 in remote_target::wait (this=0x617000038780, ptid=..., status=0x7ffdb77c33c8, options=...) at /home/simark/src/binutils-gdb/gdb/remote.c:8337 riscvarchive#13 0x000055fc7f1409ce in target_wait (ptid=..., status=0x7ffdb77c33c8, options=...) at /home/simark/src/binutils-gdb/gdb/target.c:2612 riscvarchive#14 0x000055fc7e19da98 in do_target_wait_1 (inf=0x617000038080, ptid=..., status=0x7ffdb77c33c8, options=...) at /home/simark/src/binutils-gdb/gdb/infrun.c:3636 riscvarchive#15 0x000055fc7e19e26b in operator() (__closure=0x7ffdb77c2f90, inf=0x617000038080) at /home/simark/src/binutils-gdb/gdb/infrun.c:3697 riscvarchive#16 0x000055fc7e19f0c4 in do_target_wait (ecs=0x7ffdb77c33a0, options=...) at /home/simark/src/binutils-gdb/gdb/infrun.c:3716 riscvarchive#17 0x000055fc7e1a31f7 in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:4061 Before the aforementioned commit, we would not have cleared TARGET_WNOHANG, the remote target's wait would have returned nothing, and we would have consumed the native target's event. After applying this revert, the testsuite state looks as good as before for me on Ubuntu 20.04 amd64. Change-Id: Ic17a1642935cabcc16c25cb6899d52e12c2f5c3f
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
May 19, 2022
The current zombie leader detection code in linux-nat.c has a race -- if a multi-threaded inferior exits just before check_zombie_leaders finds that the leader is now zombie via checking /proc/PID/status, check_zombie_leaders deletes the leader, assuming we won't get an event for that exit (which we won't in some scenarios, but not in this one). That might seem mostly harmless, but it has some downsides: - later when we continue pulling events out of the kernel, we will collect the exit event of the non-leader threads, and once we see the last lwp in our list exit, we return _that_ lwp's exit code as whole-process exit code to infrun, instead of the leader's exit code. - this can cause a hang in stop_all_threads in infrun.c. Say there are 2 threads in the process. stop_all_threads stops each of those threads, and then waits for two stop or exit events, one for each thread. If the whole process exits, and check_zombie_leaders hits the false-positive case, linux-nat.c will only return one event to GDB (the whole-process exit returned when we see the last thread, the non-leader thread, exit), making stop_all_threads hang forever waiting for a second event that will never come. However, in this false-positive scenario, where the whole process is exiting, as opposed to just the leader (with pthread_exit(), for example), we _will_ get an exit event shortly for the leader, after we collect the exit event of all the other non-leader threads. Or put another way, we _always_ get an event for the leader after we see it become zombie. I tried a number of approaches to fix this: riscvarchive#1 - My first thought to address the race was to make GDB always report the whole-process exit status for the leader thread, not for whatever is the last lwp in the list. We _always_ get a final exit (or exec) event for the leader, and when the race triggers, we're not collecting it. riscvarchive#2 - My second thought was to try to plug the race in the first place. I thought of making GDB call waitpid/WNOHANG for all non-leader threads immediately when the zombie leader is detected, assuming there would be an exit event pending for each of them waiting to be collected. Turns out that that doesn't work -- you can see the leader become zombie _before_ the kernel kills all other threads. Waitpid in that small time window returns 0, indicating no-event. Thankfully we hit that race window all the time, which avoided trading one race for another. Looking at the non-leader thread's status in /proc doesn't help either, the threads are still in running state for a bit, for the same reason. riscvarchive#3 - My next attempt, which seemed promising, was to synchronously stop and wait for the stop for each of the non-leader threads. For the scenario in question, this will collect all the exit statuses of the non-leader threads. Then, if we are left with only the zombie leader in the lwp list, it means we either have a normal while-process exit or an exec, in which case we should not delete the leader. If _only_ the leader exited, like in gdb.threads/leader-exit.exp, then after pausing threads, we will still have at least one live non-leader thread in the list, and so we delete the leader lwp. I got this working and polished, and it was only after staring at the kernel code to convince myself that this would really work (and it would, for the scenario I considered), that I realized I had failed to account for one scenario -- if any non-leader thread is _already_ stopped when some thread triggers a group exit, like e.g., if you have some threads stopped and then resume just one thread with scheduler-locking or non-stop, and that thread exits the process. I also played with PTRACE_EVENT_EXIT, see if it would help in any way to plug the race, and I couldn't find a way that it would result in any practical difference compared to looking at /proc/PID/status, with respect to having a race. So I concluded that there's no way to plug the race, we just have to deal with it. Which means, going back to approach riscvarchive#1. That is the approach taken by this patch. Change-Id: I6309fd4727da8c67951f9cea557724b77e8ee979
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
May 19, 2022
While working on a different patch, I triggered an assertion from the initialize_current_architecture code, specifically from one of the *_gdbarch_init functions in a *-tdep.c file. This exposes a couple of issues with GDB. This is easy enough to reproduce by adding 'gdb_assert (false)' into a suitable function. For example, I added a line into i386_gdbarch_init and can see the following issue. I start GDB and immediately hit the assert, the output is as you'd expect, except for the very last line: $ ./gdb/gdb --data-directory ./gdb/data-directory/ ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ----- Backtrace ----- ... snip ... --------------------- ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) ../../src.dev-1/gdb/ser-event.c:212:16: runtime error: member access within null pointer of type 'struct serial' Something goes wrong when we try to query the user. Note, I configured GDB with --enable-ubsan, I suspect that without this the above "error" would actually just be a crash. The backtrace from ser-event.c:212 looks like this: (gdb) bt 10 #0 serial_event_clear (event=0x675c020) at ../../src/gdb/ser-event.c:212 riscvarchive#1 0x0000000000769456 in invoke_async_signal_handlers () at ../../src/gdb/async-event.c:211 riscvarchive#2 0x000000000295049b in gdb_do_one_event () at ../../src/gdbsupport/event-loop.cc:194 riscvarchive#3 0x0000000001f015f8 in gdb_readline_wrapper ( prompt=0x67135c0 "../../src/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugg"...) at ../../src/gdb/top.c:1141 riscvarchive#4 0x0000000002118b64 in defaulted_query(const char *, char, typedef __va_list_tag __va_list_tag *) ( ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ", defchar=0 '\000', args=0x7fffffffa6e0) at ../../src/gdb/utils.c:934 riscvarchive#5 0x0000000002118f72 in query (ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ") at ../../src/gdb/utils.c:1026 riscvarchive#6 0x00000000021170f6 in internal_vproblem(internal_problem *, const char *, int, const char *, typedef __va_list_tag __va_list_tag *) (problem=0x6107bc0 <internal_error_problem>, file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:417 riscvarchive#7 0x00000000021175a0 in internal_verror (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:485 riscvarchive#8 0x00000000029503b3 in internal_error (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.") at ../../src/gdbsupport/errors.cc:55 riscvarchive#9 0x000000000122d5b6 in i386_gdbarch_init (info=..., arches=0x0) at ../../src/gdb/i386-tdep.c:8455 (More stack frames follow...) It turns out that the problem is that the async event handler mechanism has been invoked, but this has not yet been initialized. If we look at gdb_init (in gdb/top.c) we can indeed see the call to gdb_init_signals is after the call to initialize_current_architecture. If I reorder the calls, moving gdb_init_signals earlier, then the initial error is resolved, however, things are still broken. I now see the same "Quit this debugging session? (y or n)" prompt, but when I provide an answer and press return GDB immediately crashes. So what's going on now? The next problem is that the call_readline field within the current_ui structure is not initialized, and this callback is invoked to process the reply I entered. The problem is that call_readline is setup as a result of calling set_top_level_interpreter, which is called from captured_main_1. Unfortunately, set_top_level_interpreter is called after gdb_init is called. I wondered how to solve this problem for a while, however, I don't know if there's an easy "just reorder some lines" solution here. Looking through captured_main_1 there seems to be a bunch of dependencies between printing various things, parsing config files, and setting up the interpreter. I'm sure there is a solution hiding in there somewhere.... I'm just not sure I want to spend any longer looking for it. So. I propose a simpler solution, more of a hack/work-around. In utils.c we already have a function filtered_printing_initialized, this is checked in a few places within internal_vproblem. In some of these cases the call gates whether or not GDB will query the user. My proposal is to add a new readline_initialized function, which checks if the current_ui has had readline initialized yet. If this is not the case then we should not attempt to query the user. After this change GDB prints the error message, the backtrace, and then aborts (including dumping core). This actually seems pretty sane as, if GDB has not yet made it through the initialization then it doesn't make much sense to allow the user to say "no, I don't want to quit the debug session" (I think).
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
May 19, 2022
The variable right_lib_flags is not being set correctly to define RIGHT. The value RIGHT is needed to force the address of the library functions lib1_func3 and lib2_func4 to occur at different address in the wrong and right libraries. With RIGHT defined correctly, functions lib1_func3 and lib2_func4 occur at different addresses the test runs correctly on Powerpc. The test needs the lib2 addresses to be different in the right and wrong cases. That is the point of introducing function lib2_spacer with the ifdef RIGHT compiler directive. On Intel, the ARRAY_SIZE of 1 versus 8192 is sufficient to get the dynamic linker to move the addresses of the library. You can also get the same effect on PowerPC but you must use a value much larger than 8192. The key thing is that the test was not properly setting RIGHT to defined to get the lib2_spacer function on Intel and Powerpc. Without the patch, we have the Intel backtrace for the bad libraries: backtrace #0 break_here () at /home/ ... /gdb/testsuite/gdb.base/solib-search.c:30 riscvarchive#1 0x00007ffff7fae156 in ?? () riscvarchive#2 0x00007fffffffc150 in ?? () riscvarchive#3 0x00007ffff7fbb156 in ?? () riscvarchive#4 0x00007fffffffc160 in ?? () riscvarchive#5 0x00007ffff7fae146 in ?? () riscvarchive#6 0x00007fffffffc170 in ?? () riscvarchive#7 0x00007ffff7fbb146 in ?? () riscvarchive#8 0x00007fffffffc180 in ?? () riscvarchive#9 0x0000555555555156 in main () at /home/ ... /binutils-gdb/gdb/testsuite/gdb.base/solib-search.c:23 Backtrace stopped: previous frame inner to this frame (corrupt stack?) (gdb) PASS: gdb.base/solib-search.exp: backtrace (with wrong libs) (data collection) The backtrace on Intel with the good libraries is: backtrace #0 break_here () at /.../binutils-gdb/gdb/testsuite/gdb.base/solib-search.c:30 riscvarchive#1 0x00007ffff7fae156 in lib2_func4 () at /.../binutils-gdb/gdb/testsuite/gdb.base/solib-search-lib2.c:49 riscvarchive#2 0x00007ffff7fbb156 in lib1_func3 () at /.../gdb.base/solib-search-lib1.c:49 riscvarchive#3 0x00007ffff7fae146 in lib2_func2 () at /.../testsuite/gdb.base/solib-search-lib2.c:30 riscvarchive#4 0x00007ffff7fbb146 in lib1_func1 () at /.../gdb.base/solib-search-lib1.c:30 riscvarchive#5 0x0000555555555156 in main () at /...solib-search.c:23 (gdb) PASS: gdb.base/solib-search.exp: backtrace (with right libs) (data collection) PASS: gdb.base/solib-search.exp: backtrace (with right libs) In one case the backtrace is correct and the other it is wrong on Intel. This is due to the fact that the ARRAY_SIZE caused the dynamic linker to move the library function addresses around. I believe it has to do with the default size of the data and code sections used by the dynamic linker. So without the patch the backtrace on PowerPC looks like: backtrace #0 break_here () at /.../solib-search.c:30 riscvarchive#1 0x00007ffff7f007f4 in lib2_func4 () at /.../solib-search-lib2.c:49 riscvarchive#2 0x00007ffff7f307f4 in lib1_func3 () at /.../solib-search-lib1.c:49 riscvarchive#3 0x00007ffff7f007ac in lib2_func2 () at /.../solib-search-lib2.c:30 riscvarchive#4 0x00007ffff7f307ac in lib1_func1 () at /.../solib-search-lib1.c:30 riscvarchive#5 0x000000001000074c in main () at /.../solib-search.c:23 for both the good and bad libraries. The patch fixes defining RIGHT in solib-search-lib1.c and solib-search- lib2.c. Note, without the patch the lib1_spacer and lib2_spacer functions do not show up in the object dump of the Intel or Powerpc libraries as it should. The patch fixes that by making sure RIGHT gets defined. Now with the patch the backtrace for the bad library on PowerPC looks like: backtrace #0 break_here () at /.../solib-search.c:30 riscvarchive#1 0x00007ffff7f0083c in __glink_PLTresolve () from /.../solib-search-lib2.so Backtrace stopped: frame did not save the PC And the backtrace for the good libraries on PowerPC looks like: backtrace #0 break_here () at /.../solib-search.c:30 riscvarchive#1 0x00007ffff7f0083c in lib2_func4 () at /.../solib-search-lib2.c:49 riscvarchive#2 0x00007ffff7f3083c in lib1_func3 () at /.../solib-search-lib1.c:49 riscvarchive#3 0x00007ffff7f007cc in lib2_func2 () at /.../solib-search-lib2.c:30 riscvarchive#4 0x00007ffff7f307cc in lib1_func1 () at /.../solib-search-lib1.c:30 riscvarchive#5 0x000000001000074c in main () at /.../solib-search.c:23 (gdb) PASS: gdb.base/solib-search.exp: backtrace (with right libs) (data collection) PASS: gdb.base/solib-search.exp: backtrace (with right libs) The issue then is on Power where the ARRAY_SIZE of 1 versus 8192 is not sufficient to cause the dymanic linker to allocate the libraries at different addresses. I don't claim to understand the specifics of how the dynamic linker works and what the default size is for the data and code sections are. My guess is by default PowerPC allocates a larger data size by default, which is large enough to hold array[8192]. The default size of the data section allocated by the dynamic linker on Intel is not large enough to hold array[8192] thus causing the code section on Intel to have to move when the large array is defined. Note on PowerPC, if you make ARRAY_SIZE big enough, then you will cause the library addresses to occur at different addresses as the larger data section forces the code section to a different address. That was actually my original fix for the program until I spoke with Doug Evans who originally wrote the test. Doug noticed that RIGHT was not getting defined as he originally intended in the test. With the patch to fix the definition of RIGHT, PowerPC has a bad and a good backtrace because the address of lib1_func3 and lib2_func4 both move because lib1_spacer and lib2_spacer are now defined before lib1_func3 and lib2_func4. Without the patch, the lib1_spacer and lib2_spacer function doesn't show up in the binary for the correct or incorrect library on Intel or PowerPC. With the patch, RIGHT gets defined as originally intended for the test on both architectures and lib1_spacer and lib2_spacer function show up in the binaries on both architectures changing the other function addresses as intended thus causing the test work as intended on PowerPC.
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
May 19, 2022
… failing to attach Running $ ../gdbserver/gdbserver --once --attach :1234 539436 with ASan while /proc/sys/kernel/yama/ptrace_scope is set to 1 (prevents attaching) shows that we fail to free some platform-specific objects tied to the process_info (process_info_private and arch_process_info): Direct leak of 32 byte(s) in 1 object(s) allocated from: #0 0x7f6b558b3fb9 in __interceptor_calloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154 riscvarchive#1 0x562eaf15d04a in xcalloc /home/simark/src/binutils-gdb/gdbserver/../gdb/alloc.c:100 riscvarchive#2 0x562eaf251548 in xcnew<process_info_private> /home/simark/src/binutils-gdb/gdbserver/../gdbsupport/poison.h:122 riscvarchive#3 0x562eaf22810c in linux_process_target::add_linux_process_no_mem_file(int, int) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:426 riscvarchive#4 0x562eaf22d33f in linux_process_target::attach(unsigned long) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:1132 riscvarchive#5 0x562eaf1a7222 in attach_inferior /home/simark/src/binutils-gdb/gdbserver/server.cc:308 riscvarchive#6 0x562eaf1c1016 in captured_main /home/simark/src/binutils-gdb/gdbserver/server.cc:3949 riscvarchive#7 0x562eaf1c1d60 in main /home/simark/src/binutils-gdb/gdbserver/server.cc:4084 riscvarchive#8 0x7f6b552f630f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f) Indirect leak of 56 byte(s) in 1 object(s) allocated from: #0 0x7f6b558b3fb9 in __interceptor_calloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154 riscvarchive#1 0x562eaf15d04a in xcalloc /home/simark/src/binutils-gdb/gdbserver/../gdb/alloc.c:100 riscvarchive#2 0x562eaf2a0d79 in xcnew<arch_process_info> /home/simark/src/binutils-gdb/gdbserver/../gdbsupport/poison.h:122 riscvarchive#3 0x562eaf295e2c in x86_target::low_new_process() /home/simark/src/binutils-gdb/gdbserver/linux-x86-low.cc:723 riscvarchive#4 0x562eaf22819b in linux_process_target::add_linux_process_no_mem_file(int, int) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:428 riscvarchive#5 0x562eaf22d33f in linux_process_target::attach(unsigned long) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:1132 riscvarchive#6 0x562eaf1a7222 in attach_inferior /home/simark/src/binutils-gdb/gdbserver/server.cc:308 riscvarchive#7 0x562eaf1c1016 in captured_main /home/simark/src/binutils-gdb/gdbserver/server.cc:3949 riscvarchive#8 0x562eaf1c1d60 in main /home/simark/src/binutils-gdb/gdbserver/server.cc:4084 riscvarchive#9 0x7f6b552f630f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f) Those objects are deleted by linux_process_target::mourn, but that is not called if we fail to attach, we only call remove_process. I initially fixed this by making linux_process_target::attach call linux_process_target::mourn on failure (before calling error). But this isn't done anywhere else (including in GDB) so it would just be confusing to do things differently here. Instead, add a linux_process_target::remove_linux_process helper method (which calls remove_process), and call that instead of remove_process in the Linux target. Move the free-ing of the extra data from the mourn method to that new method. Change-Id: I277059a69d5f08087a7f3ef0b8f1792a1fcf7a85
Nelson1225
pushed a commit
to Nelson1225/riscv-binutils-gdb
that referenced
this pull request
May 19, 2022
Luis noticed that the recent changes to gdbserver to make it track process and threads independently regressed a few gdb.multi/*.exp tests for aarch64-linux. We started seeing the following internal error for gdb.multi/multi-target-continue.exp for example: Starting program: binutils-gdb/gdb/testsuite/outputs/gdb.multi/multi-target-continue/multi-target-continue ^M Error in re-setting breakpoint 2: Remote connection closed^M ../../../repos/binutils-gdb/gdb/thread.c:85: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed.^M A problem internal to GDB has been detected,^M further debugging may prove unreliable. A backtrace looks like: #0 thread_regcache_data (thread=thread@entry=0x0) at ../../../repos/binutils-gdb/gdbserver/inferiors.cc:120 riscvarchive#1 0x0000aaaaaaabf0e8 in get_thread_regcache (thread=0x0, fetch=fetch@entry=0) at ../../../repos/binutils-gdb/gdbserver/regcache.cc:31 riscvarchive#2 0x0000aaaaaaad785c in is_64bit_tdesc () at ../../../repos/binutils-gdb/gdbserver/linux-aarch64-low.cc:194 riscvarchive#3 0x0000aaaaaaad8a48 in aarch64_target::sw_breakpoint_from_kind (this=<optimized out>, kind=4, size=0xffffffffef04) at ../../../repos/binutils-gdb/gdbserver/linux-aarch64-low.cc:3226 riscvarchive#4 0x0000aaaaaaabe220 in bp_size (bp=0xaaaaaab6f3d0) at ../../../repos/binutils-gdb/gdbserver/mem-break.cc:226 riscvarchive#5 check_mem_read (mem_addr=187649984471104, buf=buf@entry=0xaaaaaab625d0 "\006", mem_len=mem_len@entry=56) at ../../../repos/binutils-gdb/gdbserver/mem-break.cc:1862 riscvarchive#6 0x0000aaaaaaacc660 in read_inferior_memory (memaddr=<optimized out>, myaddr=0xaaaaaab625d0 "\006", len=56) at ../../../repos/binutils-gdb/gdbserver/target.cc:93 riscvarchive#7 0x0000aaaaaaac3d9c in gdb_read_memory (len=56, myaddr=0xaaaaaab625d0 "\006", memaddr=187649984471104) at ../../../repos/binutils-gdb/gdbserver/server.cc:1071 riscvarchive#8 gdb_read_memory (memaddr=187649984471104, myaddr=0xaaaaaab625d0 "\006", len=56) at ../../../repos/binutils-gdb/gdbserver/server.cc:1048 riscvarchive#9 0x0000aaaaaaac82a4 in process_serial_event () at ../../../repos/binutils-gdb/gdbserver/server.cc:4307 riscvarchive#10 handle_serial_event (err=<optimized out>, client_data=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:4520 riscvarchive#11 0x0000aaaaaaafbcd0 in gdb_wait_for_event (block=block@entry=1) at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:700 riscvarchive#12 0x0000aaaaaaafc0b0 in gdb_wait_for_event (block=1) at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:596 riscvarchive#13 gdb_do_one_event () at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:237 riscvarchive#14 0x0000aaaaaaacacb0 in start_event_loop () at ../../../repos/binutils-gdb/gdbserver/server.cc:3518 riscvarchive#15 captured_main (argc=4, argv=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:3998 riscvarchive#16 0x0000aaaaaaab66dc in main (argc=<optimized out>, argv=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:4084 This sequence of functions is invoked due to a series of conditions: 1 - The probe-based breakpoint mechanism failed (for some reason) so ... 2 - ... gdbserver has to know what type of architecture it is dealing with so it can pick the right breakpoint kind, so it wants to check if we have a 64-bit target. 3 - To determine the size of a register, we currently fetch the current thread's register cache, and the current thread pointer is now nullptr. In riscvarchive#3, the current thread is nullptr because gdb_read_memory clears it on purpose, via set_desired_process, exactly to expose code relying on the current thread when it shouldn't. It was always possible to end up in this situation (when the current thread exits), but it was harder to reproduce before. This commit fixes it by tweaking is_64bit_tdesc to look at the current process's tdesc instead of the current thread's tdesc. Note that the thread's tdesc is itself filled from the process's tdesc, so this should be equivalent: struct regcache * get_thread_regcache (struct thread_info *thread, int fetch) { struct regcache *regcache; regcache = thread_regcache_data (thread); ... if (regcache == NULL) { struct process_info *proc = get_thread_process (thread); gdb_assert (proc->tdesc != NULL); regcache = new_register_cache (proc->tdesc); set_thread_regcache_data (thread, regcache); } ... Change-Id: Ibc809d7345e70a2f058b522bdc5cdbdca97e2cdc
kito-cheng
pushed a commit
that referenced
this pull request
Jul 7, 2022
Simon reported that the recent change to make GDB and GDBserver avoid reading shell registers caused a GDBserver regression, caught with ASan while running gdb.server/non-existing-program.exp: $ /home/smarchi/build/binutils-gdb/gdb/testsuite/../../gdb/../gdbserver/gdbserver stdio non-existing-program ================================================================= ==127719==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f0000000e9 at pc 0x55bcbfa301f4 bp 0x7ffd238a7320 sp 0x7ffd238a7310 WRITE of size 1 at 0x60f0000000e9 thread T0 #0 0x55bcbfa301f3 in scoped_restore_tmpl<bool>::~scoped_restore_tmpl() /home/smarchi/src/binutils-gdb/gdbserver/../gdbsupport/scoped_restore.h:86 #1 0x55bcbfa2ffe9 in post_fork_inferior(int, char const*) /home/smarchi/src/binutils-gdb/gdbserver/fork-child.cc:120 #2 0x55bcbf9c9199 in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:991 #3 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941 #4 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084 #5 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2) #6 0x55bcbf8ef2bd in _start (/home/smarchi/build/binutils-gdb/gdbserver/gdbserver+0x1352bd) 0x60f0000000e9 is located 169 bytes inside of 176-byte region [0x60f000000040,0x60f0000000f0) freed by thread T0 here: #0 0x7ff9d6c6f0c7 in operator delete(void*) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:160 #1 0x55bcbf910d00 in remove_process(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/inferiors.cc:164 #2 0x55bcbf9c4ac7 in linux_process_target::remove_linux_process(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:454 #3 0x55bcbf9cdaa6 in linux_process_target::mourn(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:1599 #4 0x55bcbf988dc4 in target_mourn_inferior(ptid_t) /home/smarchi/src/binutils-gdb/gdbserver/target.cc:205 #5 0x55bcbfa32020 in startup_inferior(process_stratum_target*, int, int, target_waitstatus*, ptid_t*) /home/smarchi/src/binutils-gdb/gdbserver/../gdb/nat/fork-inferior.c:515 #6 0x55bcbfa2fdeb in post_fork_inferior(int, char const*) /home/smarchi/src/binutils-gdb/gdbserver/fork-child.cc:111 #7 0x55bcbf9c9199 in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:991 #8 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941 #9 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084 #10 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2) previously allocated by thread T0 here: #0 0x7ff9d6c6e5a7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99 #1 0x55bcbf910ad0 in add_process(int, int) /home/smarchi/src/binutils-gdb/gdbserver/inferiors.cc:144 #2 0x55bcbf9c477d in linux_process_target::add_linux_process_no_mem_file(int, int) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:425 #3 0x55bcbf9c8f4c in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:985 #4 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941 #5 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084 #6 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2) Above we see that in the non-existing-program case, the process gets deleted before the starting_up flag gets restored to false. This happens because startup_inferior calls target_mourn_inferior before throwing an error, and in GDBserver, unlike in GDB, mourning deletes the process. Fix this by not using a scoped_restore to manage the starting_up flag, since we should only clear it when startup_inferior doesn't throw. Change-Id: I67325d6f81c64de4e89e20e4ec4556f57eac7f6c
kito-cheng
pushed a commit
that referenced
this pull request
Jul 7, 2022
When building gdb with -fsanitize=thread and gcc 12, and running test-case gdb.dwarf2/dwz.exp, we run into a data race between thread T2 and the main thread in the same write: ... Write of size 1 at 0x7b200000300c:^M #0 cutu_reader::cutu_reader(dwarf2_per_cu_data*, dwarf2_per_objfile*, \ abbrev_table*, dwarf2_cu*, bool, abbrev_cache*) gdb/dwarf2/read.c:6252 \ (gdb+0x82f3b3)^M ... which is here: ... this_cu->dwarf_version = cu->header.version; ... Both writes are called from the parallel for in dwarf2_build_psymtabs_hard, this one directly: ... #1 process_psymtab_comp_unit gdb/dwarf2/read.c:6774 (gdb+0x8304d7)^M #2 operator() gdb/dwarf2/read.c:7098 (gdb+0x8317be)^M #3 operator() gdbsupport/parallel-for.h:163 (gdb+0x872380)^M ... and this via the PU import: ... #1 cooked_indexer::ensure_cu_exists(cutu_reader*, dwarf2_per_objfile*, \ sect_offset, bool, bool) gdb/dwarf2/read.c:17964 (gdb+0x85c43b)^M #2 cooked_indexer::index_imported_unit(cutu_reader*, unsigned char const*, \ abbrev_info const*) gdb/dwarf2/read.c:18248 (gdb+0x85d8ff)^M #3 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, \ cooked_index_entry const*, bool) gdb/dwarf2/read.c:18302 (gdb+0x85dcdb)^M #4 cooked_indexer::make_index(cutu_reader*) gdb/dwarf2/read.c:18443 \ (gdb+0x85e68a)^M #5 process_psymtab_comp_unit gdb/dwarf2/read.c:6812 (gdb+0x830879)^M #6 operator() gdb/dwarf2/read.c:7098 (gdb+0x8317be)^M #7 operator() gdbsupport/parallel-for.h:171 (gdb+0x8723e2)^M ... Fix this by setting the field earlier, in read_comp_units_from_section. The write in cutu_reader::cutu_reader() is still needed, in case read_comp_units_from_section is not used (run the test-case with say, target board cc-with-gdb-index). Make the write conditional, such that it doesn't trigger if the field is already set by read_comp_units_from_section. Instead, verify that the field already has the value that we're trying to set it to. Move this logic into into a member function set_version (in analogy to the already present member function version) to make sure it's used consistenly, and make the field private in order to enforce access through the member functions, and rename it to m_dwarf_version. While we're at it, make sure that the version is set before read, to avoid say returning true for "per_cu.version () < 5" if "per_cu.version () == 0". Tested on x86_64-linux.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.