Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnulib, sim: don't use strsignal and errno on WinCE #1

Open
wants to merge 1 commit into
base: ce-2.28
Choose a base branch
from

Conversation

balintf
Copy link

@balintf balintf commented Nov 11, 2017

Fix build errors that occur when building binutils using MSYS2 64-bit gcc 7.2 on Windows.

MaxKellermann pushed a commit that referenced this pull request Oct 23, 2018
One test in gdb.compile/compile.exp passes on one fedora builder,

 bt
 #0  0x00007ffff7ff43f6 in _gdb_expr (__regs=0x7ffff7ff2000) at gdb
 command line:1^M
 #1  <function called from gdb>^M
 #2  main () at /home/gdb-buildbot/fedora-x86-64-1/fedora-x86-64/build/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.compile/compile.c:106^M
 (gdb) PASS: gdb.compile/compile.exp: bt

but fails on my machine with gcc trunk,

 bt^M
 #0  _gdb_expr (__regs=0x7ffff7ff3000) at gdb command line:1^M
 #1  <function called from gdb>^M
 #2  main () at gdb/testsuite/gdb.compile/compile.c:106^M
 (gdb) FAIL: gdb.compile/compile.exp: bt

The test should be tweaked to match both cases (pc in the start of line
vs pc in the middle of line).  Note that I am not clear that why libcc1
emits debug info this way so that the address is in the middle of line.

gdb/testsuite:

2018-01-17  Yao Qi  <[email protected]>

	* gdb.compile/compile.exp: Match the address printed for
	frame in the output of command "bt".
MaxKellermann pushed a commit that referenced this pull request Oct 23, 2018
I got some crashes while doing some work with dwarf2_per_objfile.  It
turns out that dwarf2_per_objfile_free is using the dwarf2_per_objfile
objects after their destructor has ran.

The easiest way to reproduce this is to run the inferior twice (do
"start" twice).  Currently, it goes unnoticed, but when I tried to
change all_comp_units and all_type_units to std::vectors, things started
crashing.

The dwarf2_per_objfile objects get destroyed here:

 #0  dwarf2_per_objfile::~dwarf2_per_objfile (this=0x35afe70, __in_chrg=<optimized out>) at /home/emaisin/src/binutils-gdb/gdb/dwarf2read.c:2422
 #1  0x0000000000833282 in dwarf2_free_objfile (objfile=0x356cff0) at /home/emaisin/src/binutils-gdb/gdb/dwarf2read.c:25363
 #2  0x0000000000699255 in elf_symfile_finish (objfile=0x356cff0) at /home/emaisin/src/binutils-gdb/gdb/elfread.c:1309
 bminor#3  0x0000000000911ed3 in objfile::~objfile (this=0x356cff0, __in_chrg=<optimized out>) at /home/emaisin/src/binutils-gdb/gdb/objfiles.c:674

and just after that the dwarf2read per-objfile registry cleanup function
gets called:

 #0  dwarf2_per_objfile_free (objfile=0x356cff0, d=0x35afe70) at /home/emaisin/src/binutils-gdb/gdb/dwarf2read.c:25667
 ... registry boilerplate ...
 bminor#4  0x00000000009103ea in objfile_free_data (container=0x356cff0) at /home/emaisin/src/binutils-gdb/gdb/objfiles.c:61
 bminor#5  0x0000000000911ee2 in objfile::~objfile (this=0x356cff0, __in_chrg=<optimized out>) at /home/emaisin/src/binutils-gdb/gdb/objfiles.c:678

In dwarf2_per_objfile_free, we access fields of the dwarf2_per_objfile
object, which is invalid since its destructor has been executed.

This patch moves the content of dwarf2_per_objfile_free to the
destructor of dwarf2_per_objfile.  The call to
register_objfile_data_with_cleanup in _initialize_dwarf2_read can be
changed to the simpler register_objfile_data.

gdb/ChangeLog:

	* dwarf2read.c (free_dwo_files): Add forward-declaration.
	(dwarf2_per_objfile::~dwarf2_per_objfile): Move content from
	dwarf2_per_objfile_free here.
	(dwarf2_per_objfile_free): Remove.
	(_initialize_dwarf2_read): Don't register
	dwarf2_per_objfile_free as a registry cleanup.
MaxKellermann pushed a commit that referenced this pull request Oct 23, 2018
When running the test gdb.dwarf2/dw2-bad-parameter-type.exp under
valgrind, I see the following issue reported (on x86-64 Fedora):

  (gdb) ptype f
  ==5203== Invalid read of size 1
  ==5203==    at 0x6931FE: process_die_scope::~process_die_scope() (dwarf2read.c:10642)
  ==5203==    by 0x66818F: process_die(die_info*, dwarf2_cu*) (dwarf2read.c:10664)
  ==5203==    by 0x66A01F: read_file_scope(die_info*, dwarf2_cu*) (dwarf2read.c:11650)
  ==5203==    by 0x667F2D: process_die(die_info*, dwarf2_cu*) (dwarf2read.c:10672)
  ==5203==    by 0x6677B6: process_full_comp_unit(dwarf2_per_cu_data*, language) (dwarf2read.c:10445)
  ==5203==    by 0x66657A: process_queue(dwarf2_per_objfile*) (dwarf2read.c:9945)
  ==5203==    by 0x6559B4: dw2_do_instantiate_symtab(dwarf2_per_cu_data*) (dwarf2read.c:3163)
  ==5203==    by 0x66683D: psymtab_to_symtab_1(partial_symtab*) (dwarf2read.c:10034)
  ==5203==    by 0x66622A: dwarf2_read_symtab(partial_symtab*, objfile*) (dwarf2read.c:9811)
  ==5203==    by 0x787984: psymtab_to_symtab(objfile*, partial_symtab*) (psymtab.c:792)
  ==5203==    by 0x786E3E: psym_lookup_symbol(objfile*, int, char const*, domain_enum_tag) (psymtab.c:522)
  ==5203==    by 0x804BD0: lookup_symbol_via_quick_fns(objfile*, int, char const*, domain_enum_tag) (symtab.c:2383)
  ==5203==  Address 0x147ed063 is 291 bytes inside a block of size 4,064 free'd
  ==5203==    at 0x4C2CD5A: free (vg_replace_malloc.c:530)
  ==5203==    by 0x444415: void xfree<void>(void*) (common-utils.h:60)
  ==5203==    by 0x9DA8C2: call_freefun (obstack.c:103)
  ==5203==    by 0x9DAD35: _obstack_free (obstack.c:280)
  ==5203==    by 0x44464C: auto_obstack::~auto_obstack() (gdb_obstack.h:73)
  ==5203==    by 0x68AFB0: dwarf2_cu::~dwarf2_cu() (dwarf2read.c:25080)
  ==5203==    by 0x68B204: free_one_cached_comp_unit(dwarf2_per_cu_data*) (dwarf2read.c:25174)
  ==5203==    by 0x66668C: dwarf2_release_queue(void*) (dwarf2read.c:9982)
  ==5203==    by 0x563A4C: do_my_cleanups(cleanup**, cleanup*) (cleanups.c:154)
  ==5203==    by 0x563AA7: do_cleanups(cleanup*) (cleanups.c:176)
  ==5203==    by 0x5646CE: throw_exception_cxx(gdb_exception) (common-exceptions.c:289)
  ==5203==    by 0x5647B7: throw_exception(gdb_exception) (common-exceptions.c:317)
  ==5203==  Block was alloc'd at
  ==5203==    at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
  ==5203==    by 0x564BE8: xmalloc (common-utils.c:44)
  ==5203==    by 0x9DA872: call_chunkfun (obstack.c:94)
  ==5203==    by 0x9DA935: _obstack_begin_worker (obstack.c:141)
  ==5203==    by 0x9DAA3C: _obstack_begin (obstack.c:164)
  ==5203==    by 0x4445E0: auto_obstack::auto_obstack() (gdb_obstack.h:70)
  ==5203==    by 0x68AE07: dwarf2_cu::dwarf2_cu(dwarf2_per_cu_data*) (dwarf2read.c:25073)
  ==5203==    by 0x661A8A: init_cutu_and_read_dies(dwarf2_per_cu_data*, abbrev_table*, int, int, void (*)(die_reader_specs const*, unsigned char const*, die_info*, int, void*), void*) (dwarf2read.c:7869)
  ==5203==    by 0x666A29: load_full_comp_unit(dwarf2_per_cu_data*, language) (dwarf2read.c:10108)
  ==5203==    by 0x655847: load_cu(dwarf2_per_cu_data*) (dwarf2read.c:3120)
  ==5203==    by 0x655928: dw2_do_instantiate_symtab(dwarf2_per_cu_data*) (dwarf2read.c:3148)
  ==5203==    by 0x66683D: psymtab_to_symtab_1(partial_symtab*) (dwarf2read.c:10034)

There's actually a series of three issues reported, but it turns out
they're all related, so we can consider on the first one.

The invalid read is triggered from a destructor which is being invoked
as part of a stack unwind after throwing an error.  At the time the
error is thrown, the stack looks like this:

    #0  0x00000000009f4ecd in __cxa_throw ()
    #1  0x0000000000564761 in throw_exception_cxx (exception=...) at ../../src/gdb/common/common-exceptions.c:303
    #2  0x00000000005647b8 in throw_exception (exception=...) at ../../src/gdb/common/common-exceptions.c:317
    bminor#3  0x00000000005648ff in throw_it(return_reason, errors, const char *, typedef __va_list_tag __va_list_tag *) (reason=RETURN_ERROR,
        error=GENERIC_ERROR, fmt=0xb33020 "Dwarf Error: Cannot find DIE at 0x%x referenced from DIE at 0x%x [in module %s]",
        ap=0x7fff387f2d68) at ../../src/gdb/common/common-exceptions.c:373
    bminor#4  0x0000000000564929 in throw_verror (error=GENERIC_ERROR,
        fmt=0xb33020 "Dwarf Error: Cannot find DIE at 0x%x referenced from DIE at 0x%x [in module %s]", ap=0x7fff387f2d68)
        at ../../src/gdb/common/common-exceptions.c:379
    bminor#5  0x0000000000867be4 in verror (string=0xb33020 "Dwarf Error: Cannot find DIE at 0x%x referenced from DIE at 0x%x [in module %s]",
        args=0x7fff387f2d68) at ../../src/gdb/utils.c:251
    bminor#6  0x000000000056879d in error (fmt=0xb33020 "Dwarf Error: Cannot find DIE at 0x%x referenced from DIE at 0x%x [in module %s]")
        at ../../src/gdb/common/errors.c:43
    bminor#7  0x0000000000686875 in follow_die_ref (src_die=0x30bc8a0, attr=0x30bc8c8, ref_cu=0x7fff387f2ed0) at ../../src/gdb/dwarf2read.c:22969
    bminor#8  0x00000000006844cd in lookup_die_type (die=0x30bc8a0, attr=0x30bc8c8, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:21976
    bminor#9  0x0000000000683f27 in die_type (die=0x30bc8a0, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:21832
    bminor#10 0x0000000000679b39 in read_subroutine_type (die=0x30bc830, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:17343
    bminor#11 0x00000000006845fb in read_type_die_1 (die=0x30bc830, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:22035
    bminor#12 0x0000000000684576 in read_type_die (die=0x30bc830, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:22010
    #13 0x000000000067003f in read_func_scope (die=0x30bc830, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:13822
    #14 0x0000000000667f5e in process_die (die=0x30bc830, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:10679
    #15 0x000000000066a020 in read_file_scope (die=0x30bc720, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:11650
    #16 0x0000000000667f2e in process_die (die=0x30bc720, cu=0x30bc5d0) at ../../src/gdb/dwarf2read.c:10672
    #17 0x00000000006677b7 in process_full_comp_unit (per_cu=0x3089b80, pretend_language=language_minimal)
        at ../../src/gdb/dwarf2read.c:10445
    #18 0x000000000066657b in process_queue (dwarf2_per_objfile=0x30897d0) at ../../src/gdb/dwarf2read.c:9945
    #19 0x00000000006559b5 in dw2_do_instantiate_symtab (per_cu=0x3089b80) at ../../src/gdb/dwarf2read.c:3163
    #20 0x000000000066683e in psymtab_to_symtab_1 (pst=0x3089bd0) at ../../src/gdb/dwarf2read.c:10034
    #21 0x000000000066622b in dwarf2_read_symtab (self=0x3089bd0, objfile=0x3073f40) at ../../src/gdb/dwarf2read.c:9811
    #22 0x0000000000787985 in psymtab_to_symtab (objfile=0x3073f40, pst=0x3089bd0) at ../../src/gdb/psymtab.c:792
    #23 0x0000000000786e3f in psym_lookup_symbol (objfile=0x3073f40, block_index=1, name=0x30b2e30 "f", domain=VAR_DOMAIN)
        at ../../src/gdb/psymtab.c:522
    #24 0x0000000000804bd1 in lookup_symbol_via_quick_fns (objfile=0x3073f40, block_index=1, name=0x30b2e30 "f", domain=VAR_DOMAIN)
        at ../../src/gdb/symtab.c:2383
    #25 0x0000000000804fe4 in lookup_symbol_in_objfile (objfile=0x3073f40, block_index=1, name=0x30b2e30 "f", domain=VAR_DOMAIN)
        at ../../src/gdb/symtab.c:2558
    #26 0x0000000000805125 in lookup_static_symbol (name=0x30b2e30 "f", domain=VAR_DOMAIN) at ../../src/gdb/symtab.c:2595
    #27 0x0000000000804357 in lookup_symbol_aux (name=0x30b2e30 "f", match_type=symbol_name_match_type::FULL, block=0x0,
        domain=VAR_DOMAIN, language=language_c, is_a_field_of_this=0x0) at ../../src/gdb/symtab.c:2105
    #28 0x0000000000803ad9 in lookup_symbol_in_language (name=0x30b2e30 "f", block=0x0, domain=VAR_DOMAIN, lang=language_c,
        is_a_field_of_this=0x0) at ../../src/gdb/symtab.c:1887
    #29 0x0000000000803b53 in lookup_symbol (name=0x30b2e30 "f", block=0x0, domain=VAR_DOMAIN, is_a_field_of_this=0x0)
        at ../../src/gdb/symtab.c:1899
    #30 0x000000000053b246 in classify_name (par_state=0x7fff387f6090, block=0x0, is_quoted_name=false, is_after_structop=false)
        at ../../src/gdb/c-exp.y:2879
    #31 0x000000000053b7e9 in c_yylex () at ../../src/gdb/c-exp.y:3083
    #32 0x000000000053414a in c_yyparse () at c-exp.c:1903
    #33 0x000000000053c2e7 in c_parse (par_state=0x7fff387f6090) at ../../src/gdb/c-exp.y:3255
    #34 0x0000000000774a02 in parse_exp_in_context_1 (stringptr=0x7fff387f61c0, pc=0, block=0x0, comma=0, void_context_p=0, out_subexp=0x0)
        at ../../src/gdb/parse.c:1213
    #35 0x000000000077476a in parse_exp_in_context (stringptr=0x7fff387f61c0, pc=0, block=0x0, comma=0, void_context_p=0, out_subexp=0x0)
        at ../../src/gdb/parse.c:1115
    #36 0x0000000000774714 in parse_exp_1 (stringptr=0x7fff387f61c0, pc=0, block=0x0, comma=0) at ../../src/gdb/parse.c:1106
    #37 0x0000000000774c53 in parse_expression (string=0x27ff996 "f") at ../../src/gdb/parse.c:1253
    #38 0x0000000000861dc4 in whatis_exp (exp=0x27ff996 "f", show=1) at ../../src/gdb/typeprint.c:472
    #39 0x00000000008620d8 in ptype_command (type_name=0x27ff996 "f", from_tty=1) at ../../src/gdb/typeprint.c:561
    #40 0x000000000047430b in do_const_cfunc (c=0x3012010, args=0x27ff996 "f", from_tty=1) at ../../src/gdb/cli/cli-decode.c:106
    #41 0x000000000047715e in cmd_func (cmd=0x3012010, args=0x27ff996 "f", from_tty=1) at ../../src/gdb/cli/cli-decode.c:1886
    #42 0x00000000008431bb in execute_command (p=0x27ff996 "f", from_tty=1) at ../../src/gdb/top.c:630
    #43 0x00000000006bf946 in command_handler (command=0x27ff990 "ptype f") at ../../src/gdb/event-top.c:583
    #44 0x00000000006bfd12 in command_line_handler (rl=0x30bb3a0 "\240\305\v\003") at ../../src/gdb/event-top.c:774

The problem is that in `process_die` (frames 14 and 16) we create a
`process_die_scope` object, that takes a copy of the `struct
dwarf2_cu *` passed into the frame.  The destructor of the
`process_die_scope` dereferences the stored pointer.  This wouldn't be
an issue, except...

... in dw2_do_instantiate_symtab (frame 19) a clean up was registered that
clears the dwarf2_queue in case of an error.  Part of this clean up
involves deleting the `struct dwarf2_cu`s referenced from the queue..

The problem then, is that cleanups are processed at the site of the
throw, while, class destructors are invoked as we unwind their frame.
The result is that we process the frame 19 cleanup (and delete the
struct dwarf2_cu) before we process the destructors in frames 14 and 16.
When we do get back to frames 14 and 16 the objects being references
have already been deleted.

The solution is to remove the cleanup from dw2_do_instantiate_symtab, and
instead use a destructor to release the dwarf2_queue instead.  With this
patch in place, the valgrind errors are now resolved.

gdb/ChangeLog:

	* dwarf2read.c (dwarf2_release_queue): Delete function, move body
	into...
	(class dwarf2_queue_guard): ...the destructor of this new class.
	(dw2_do_instantiate_symtab): Create instance of the new class
	dwarf2_queue_guard, remove cleanup.
MaxKellermann pushed a commit that referenced this pull request Oct 23, 2018
In https://sourceware.org/ml/gdb-patches/2017-06/msg00741.html,
Pedro asks:

> Doesn't the "info verbose on" bit affect frame filters too?

The answer is that yes, it could.  However, it's not completely
effective, because the C code can't guess how many frames might need
to be unwound to satisfy the request -- a frame filter will request as
many frames as it needs.

Also, I tried removing this code from backtrace, and I think the
result is better without it.  In particular, now the expansion line
occurs just before the frame that caused the expansion, like:

    (gdb) bt no-filters
    #0  0x00007ffff576cecd in poll () from /lib64/libc.so.6
    Reading in symbols for ../../binutils-gdb/gdb/event-loop.c...done.
    #1  0x00000000007ecc33 in gdb_wait_for_event (block=1)
	at ../../binutils-gdb/gdb/event-loop.c:772
    #2  0x00000000007ec006 in gdb_do_one_event ()
	at ../../binutils-gdb/gdb/event-loop.c:347
    bminor#3  0x00000000007ec03e in start_event_loop ()
	at ../../binutils-gdb/gdb/event-loop.c:371
    Reading in symbols for ../../binutils-gdb/gdb/main.c...done.
    bminor#4  0x000000000086693d in captured_command_loop (
	Reading in symbols for ../../binutils-gdb/gdb/exceptions.c...done.
    data=0x0) at ../../binutils-gdb/gdb/main.c:325

So, I am proposing this patch to simply remove this code.

gdb/ChangeLog
2018-03-26  Tom Tromey  <[email protected]>

	* stack.c (backtrace_command_1): Remove verbose code.
MaxKellermann pushed a commit that referenced this pull request Oct 23, 2018
A future patch will propose making the remote target's target_ops be
heap-allocated (to make it possible to have multiple instances of
remote targets, for multiple simultaneous connections), and will
delete/destroy the remote target at target_close time.

That change trips on a latent problem, though.  File I/O handles
remain open even after the target is gone, with a dangling pointer to
a target that no longer exists.  This results in GDB crashing when it
calls the target_ops backend associated with the file handle:

 (gdb) Disconnect
 Ending remote debugging.
 * GDB crashes deferencing a dangling pointer

Backtrace:

   #0  0x00007f79338570a0 in main_arena () at /lib64/libc.so.6
   #1  0x0000000000858bfe in target_fileio_close(int, int*) (fd=1, target_errno=0x7ffe0499a4c8)
       at src/gdb/target.c:2980
   #2  0x00000000007088bd in gdb_bfd_iovec_fileio_close(bfd*, void*) (abfd=0x1a631b0, stream=0x223c9d0)
       at src/gdb/gdb_bfd.c:353
   bminor#3  0x0000000000930906 in opncls_bclose (abfd=0x1a631b0) at src/bfd/opncls.c:528
   bminor#4  0x0000000000930cf9 in bfd_close_all_done (abfd=0x1a631b0) at src/bfd/opncls.c:768
   bminor#5  0x0000000000930cb3 in bfd_close (abfd=0x1a631b0) at src/bfd/opncls.c:735
   bminor#6  0x0000000000708dc5 in gdb_bfd_close_or_warn(bfd*) (abfd=0x1a631b0) at src/gdb/gdb_bfd.c:511
   bminor#7  0x00000000007091a2 in gdb_bfd_unref(bfd*) (abfd=0x1a631b0) at src/gdb/gdb_bfd.c:615
   bminor#8  0x000000000079ed8e in objfile::~objfile() (this=0x2154730, __in_chrg=<optimized out>)
       at src/gdb/objfiles.c:682
   bminor#9  0x000000000079fd1a in objfile_purge_solibs() () at src/gdb/objfiles.c:1065
   bminor#10 0x00000000008162ca in no_shared_libraries(char const*, int) (ignored=0x0, from_tty=1)
       at src/gdb/solib.c:1251
   bminor#11 0x000000000073b89b in disconnect_command(char const*, int) (args=0x0, from_tty=1)
       at src/gdb/infcmd.c:3035

This goes unnoticed in current master, because the current remote
target's target_ops is never destroyed nowadays, so we end up calling:

  remote_hostio_close -> remote_hostio_send_command

which gracefully fails with FILEIO_ENOSYS if remote_desc is NULL
(because the target is closed).

Fix this by invalidating a target's file I/O handles when the target
is closed.

With this change, remote_hostio_send_command no longer needs to handle the
case of being called with a closed remote target, originally added here:
<https://sourceware.org/ml/gdb-patches/2008-08/msg00359.html>.

gdb/ChangeLog:
2018-04-11  Pedro Alves  <[email protected]>

	* target.c (fileio_fh_t::t): Add comment.
	(target_fileio_pwrite, target_fileio_pread, target_fileio_fstat)
	(target_fileio_close): Handle a NULL target.
	(invalidate_fileio_fh): New.
	(target_close): Call it.
	* remote.c (remote_hostio_send_command): No longer check whether
	remote_desc is open.
MaxKellermann pushed a commit that referenced this pull request Oct 23, 2018
Since we use obstacks with objects that are not default constructible,
we sometimes need to manually call the constructor by hand using
placement new:

  foo *f = obstack_alloc (obstack, sizeof (foo));
  f = new (f) foo;

It's possible to use allocate_on_obstack instead, but there are types
that we sometimes want to allocate on an obstack, and sometimes on the
regular heap.  This patch introduces a utility to make this pattern
simpler if allocate_on_obstack is not an option:

  foo *f = obstack_new<foo> (obstack);

Right now there's only one usage (in tdesc_data_init).

To help catch places where we would forget to call new when allocating
such an object on an obstack, this patch also poisons some other methods
of allocating an instance of a type on an obstack:

  - OBSTACK_ZALLOC/OBSTACK_CALLOC
  - XOBNEW/XOBNEW
  - GDBARCH_OBSTACK_ZALLOC/GDBARCH_OBSTACK_CALLOC

Unfortunately, there's no way to catch wrong usages of obstack_alloc.

By pulling on that string though, it tripped on allocating struct
template_symbol using OBSTACK_ZALLOC.  The criterion currently used to
know whether it's safe to "malloc" an instance of a struct is whether it
is a POD.  Because it inherits from struct symbol, template_symbol is
not a POD.  This criterion is a bit too strict however, it should still
safe to allocate memory for a template_symbol and memset it to 0.  We
didn't use is_trivially_constructible as the criterion in the first
place only because it is not available in gcc < 5.  So here I considered
two alternatives:

1. Relax that criterion to use std::is_trivially_constructible and add a
   bit more glue code to make it work with gcc < 5
2. Continue pulling on the string and change how the symbol structures
   are allocated and initialized

I managed to do both, but I decided to go with #1 to keep this patch
simpler and more focused.  When building with a compiler that does not
have is_trivially_constructible, the check will just not be enforced.

gdb/ChangeLog:

	* common/traits.h (HAVE_IS_TRIVIALLY_COPYABLE): Define if
	compiler supports std::is_trivially_constructible.
	* common/poison.h: Include obstack.h.
	(IsMallocable): Define to is_trivially_constructible if the
	compiler supports it, define to true_type otherwise.
	(xobnew): New.
	(XOBNEW): Redefine.
	(xobnewvec): New.
	(XOBNEWVEC): Redefine.
	* gdb_obstack.h (obstack_zalloc): New.
	(OBSTACK_ZALLOC): Redefine.
	(obstack_calloc): New.
	(OBSTACK_CALLOC): Redefine.
	(obstack_new): New.
	* gdbarch.sh: Include gdb_obstack in gdbarch.h.
	(gdbarch_obstack): New declaration in gdbarch.h, definition in
	gdbarch.c.
	(GDBARCH_OBSTACK_CALLOC, GDBARCH_OBSTACK_ZALLOC): Use
	obstack_calloc/obstack_zalloc.
	(gdbarch_obstack_zalloc): Remove.
	* target-descriptions.c (tdesc_data_init): Use obstack_new.
MaxKellermann pushed a commit that referenced this pull request Oct 23, 2018
Currently, gdb.gdb/selftest.exp fails if you build GDB with
optimization (-O2, etc.).

The reason is that after setting a breakpoint in captured_main, we
stop at:
 ...
 Breakpoint 1, captured_main_1 (context=<optimized out>) at src/gdb/main.c:492
 ...
while selftest_setup expects a stop at captured_main.

Here, captured_main_1 has been inlined into captured_main, and
captured_main has been inlined into gdb_main:

 ...
 $ nm ./build/gdb/gdb | egrep ' [tT] .*captured_main|gdb_main' | c++filt
 000000000061b950 T gdb_main(captured_main_args*)
 ...

Indeed, the two inlined functions show up in the backtrace:

 ...
 (gdb) bt
 #0  captured_main_1 (context=<optimized out>) at main.c:492
 #1  captured_main (data=<optimized out>) at main.c:1147
 #2  gdb_main (args=args@entry=0x7fffffffdb80) at main.c:1173
 bminor#3  0x000000000040fea5 in main (argc=<optimized out>, argv=<optimized out>)
     at gdb.c:32
 ...

We're now stopping at captured_main_1 because commit ddfe970
("Don't elide all inlined frames") makes GDB present a stop at the
innermost inlined frame if the program stopped by a user breakpoint.

Now, the selftest.exp testcase explicitly asks to stop at
"captured_main", not "captured_main_1", so I'm thinking that it's
GDB'S behavior that should be improved.  That is what this commit
does, by only showing a stop at an inline frame if the user breakpoint
was set in that frame's block.

Before this commit:

 (top-gdb) b captured_main
 Breakpoint 1 at 0x792f99: file src/gdb/main.c, line 492.
 (top-gdb) r
 Starting program: build/gdb/gdb

 Breakpoint 1, captured_main_1 (context=<optimized out>) at src/gdb/main.c:492
 492       lim_at_start = (char *) sbrk (0);
 (top-gdb)

After this commit, we now instead get:

 (top-gdb) b captured_main
 Breakpoint 1 at 0x791339: file src/gdb/main.c, line 492.
 (top-gdb) r
 Starting program: build/gdb/gdb

 Breakpoint 1, captured_main (data=<optimized out>) at src/gdb/main.c:1147
 1147      captured_main_1 (context);
 (top-gdb)

and:

 (top-gdb) b captured_main_1
 Breakpoint 2 at 0x791339: file src/gdb/main.c, line 492.
 (top-gdb) r
 Starting program: build/gdb/gdb
 Breakpoint 2, captured_main_1 (context=<optimized out>) at src/gdb/main.c:492
 492       lim_at_start = (char *) sbrk (0);
 (top-gdb)

Note that both captured_main and captured_main_1 resolved to the same
address, 0x791339.  That is necessary to trigger the issue in
question.  The gdb.base/inline-break.exp testcase currently does not
exercise that, but the new test added by this commit does.  That new
test fails without the GDB fix and passes with the fix.  No
regressions on x86-64 GNU/Linux.

While at it, the THIS_PC comparison in stopped_by_user_bp_inline_frame
is basically a nop, so just remove it -- if a software or hardware
breakpoint explains the stop, then it must be that it was installed at
the current PC.

gdb/ChangeLog:
2018-06-19  Pedro Alves  <[email protected]>

	* inline-frame.c (stopped_by_user_bp_inline_frame): Replace PC
	parameter with a block parameter.  Compare location's block symbol
	with the frame's block instead of addresses.
	(skip_inline_frames): Pass the current block instead of the
	frame's address.  Break out as soon as we determine the frame
	should not be skipped.

gdb/testsuite/ChangeLog:
2018-06-19  Pedro Alves  <[email protected]>

	* gdb.opt/inline-break.c (func_inline_callee, func_inline_caller)
	(func_extern_caller): New.
	(main): Call func_extern_caller.
	* gdb.opt/inline-break.exp: Add tests for inline frame skipping
	logic change.
MaxKellermann pushed a commit that referenced this pull request Mar 23, 2020
Following the int -> bool conversion of boolean options (commit
491144b ("Change boolean options to bool instead of int")), I see
this ASAN error:

  ==357543==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55555b25d440 at pc 0x5555583ce9e1 bp 0x7fffffffd390 sp 0x7fffffffd380
  READ of size 4 at 0x55555b25d440 thread T0
      #0 0x5555583ce9e0 in term_cli_styling /home/simark/src/binutils-gdb/gdb/ui-file.c:111
      #1 0x5555583cf8b0 in stdio_file::can_emit_style_escape() /home/simark/src/binutils-gdb/gdb/ui-file.c:308
      #2 0x5555584450d2 in set_output_style /home/simark/src/binutils-gdb/gdb/utils.c:1442
      bminor#3 0x5555584491af in fprintf_styled(ui_file*, ui_file_style const&, char const*, ...) /home/simark/src/binutils-gdb/gdb/utils.c:2143
      bminor#4 0x5555582fa13c in print_gdb_version(ui_file*, bool) /home/simark/src/binutils-gdb/gdb/top.c:1339
      bminor#5 0x555557b723ab in captured_main_1 /home/simark/src/binutils-gdb/gdb/main.c:981
      bminor#6 0x555557b7353b in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1172
      bminor#7 0x555557b735d0 in gdb_main(captured_main_args*) /home/simark/src/binutils-gdb/gdb/main.c:1197
      bminor#8 0x55555700a53d in main /home/simark/src/binutils-gdb/gdb/gdb.c:32
      bminor#9 0x7ffff64c9ee2 in __libc_start_main (/usr/lib/libc.so.6+0x26ee2)
      bminor#10 0x55555700a30d in _start (/home/simark/build/binutils-gdb/gdb/gdb+0x1ab630d)

  0x55555b25d441 is located 0 bytes to the right of global variable 'cli_styling' defined in '/home/simark/src/binutils-gdb/gdb/cli/cli-style.c:31:6' (0x55555b25d440) of size 1

The reason of this is that we have this declaration of cli_styling in cli/cli-style.h:

  extern bool cli_styling;

but ui-file.c uses its  own local declaration:

  extern int cli_styling;

Because of that, the code in ui-file.c thinks the variable is 4 bytes
long, when it is actually 1 byte long, so the generated code reads past
the variable.

Fix it by removing the declaration and making ui-file.c include
cli/cli-style.h.

gdb/ChangeLog:

	* ui-file.c: Include cli/cli-style.h.
	(term_cli_styling): Remove cli_styling declaration.
MaxKellermann pushed a commit that referenced this pull request Mar 23, 2020
Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1765117

A segfault can happen in a specific scenario when using TUI + a
corefile, as explained in the bug mentioned above.  The problem
happens when opening a corefile on GDB:

  $ gdb ./core program

entering TUI (C-x a), and then issuing a "run" command.  GDB segfaults
with the following stack trace:

  (top-gdb) bt
  #0  0x00000000004cd5da in target_ops::shortname (this=0x0) at ../../binutils-gdb/gdb/target.h:449
  #1  0x0000000000ac08fb in target_shortname () at ../../binutils-gdb/gdb/target.h:1323
  #2  0x0000000000ac09ae in tui_locator_window::make_status_line[abi:cxx11]() const (this=0x23e1fa0 <_locator>) at ../../binutils-gdb/gdb/tui/tui-stack.c:86
  bminor#3  0x0000000000ac1043 in tui_locator_window::rerender (this=0x23e1fa0 <_locator>) at ../../binutils-gdb/gdb/tui/tui-stack.c:231
  bminor#4  0x0000000000ac1632 in tui_show_locator_content () at ../../binutils-gdb/gdb/tui/tui-stack.c:369
  bminor#5  0x0000000000ac63b6 in tui_set_key_mode (mode=TUI_COMMAND_MODE) at ../../binutils-gdb/gdb/tui/tui.c:321
  bminor#6  0x0000000000aaf9be in tui_inferior_exit (inf=0x2d446a0) at ../../binutils-gdb/gdb/tui/tui-hooks.c:181
  bminor#7  0x000000000044cddf in std::_Function_handler<void (inferior*), void (*)(inferior*)>::_M_invoke(std::_Any_data const&, inferior*&&) (__functor=..., __args#0=@0x7fffffffd650: 0x2d446a0)
      at /usr/include/c++/9/bits/std_function.h:300
  bminor#8  0x0000000000757db9 in std::function<void (inferior*)>::operator()(inferior*) const (this=0x2cf3168, __args#0=0x2d446a0) at /usr/include/c++/9/bits/std_function.h:690
  bminor#9  0x0000000000757876 in gdb::observers::observable<inferior*>::notify (this=0x23de0c0 <gdb::observers::inferior_exit>, args#0=0x2d446a0)
      at ../../binutils-gdb/gdb/gdbsupport/observable.h:106
  bminor#10 0x000000000075532d in exit_inferior_1 (inftoex=0x2d446a0, silent=1) at ../../binutils-gdb/gdb/inferior.c:191
  bminor#11 0x0000000000755460 in exit_inferior_silent (inf=0x2d446a0) at ../../binutils-gdb/gdb/inferior.c:234
  bminor#12 0x000000000059f47c in core_target::close (this=0x2d68590) at ../../binutils-gdb/gdb/corelow.c:265
  #13 0x0000000000a7688c in target_close (targ=0x2d68590) at ../../binutils-gdb/gdb/target.c:3293
  #14 0x0000000000a63d74 in target_stack::push (this=0x23e1800 <g_target_stack>, t=0x23c38c8 <the_amd64_linux_nat_target>) at ../../binutils-gdb/gdb/target.c:568
  #15 0x0000000000a63dbf in push_target (t=0x23c38c8 <the_amd64_linux_nat_target>) at ../../binutils-gdb/gdb/target.c:583
  #16 0x0000000000748088 in inf_ptrace_target::create_inferior (this=0x23c38c8 <the_amd64_linux_nat_target>, exec_file=0x2d58d30 "/usr/bin/cat", allargs="", env=0x25f12b0, from_tty=1)
      at ../../binutils-gdb/gdb/inf-ptrace.c:128
  #17 0x0000000000795ccb in linux_nat_target::create_inferior (this=0x23c38c8 <the_amd64_linux_nat_target>, exec_file=0x2d58d30 "/usr/bin/cat", allargs="", env=0x25f12b0, from_tty=1)
      at ../../binutils-gdb/gdb/linux-nat.c:1094
  #18 0x000000000074eae9 in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at ../../binutils-gdb/gdb/infcmd.c:639
  ...

The problem happens because 'tui_locator_window::make_status_line'
needs the value of 'target_shortname' in order to update the status
line.  'target_shortname' is a macro which expands to:

  #define	target_shortname	(current_top_target ()->shortname ())

and, in our scenario, 'current_top_target ()' returns NULL, which
obviously causes a segfault.  But why does it return NULL, since,
according to its comment on target.h, it should never do that?

What is happening is that we're being caught in the middle of a
"target switch".  We had the 'core_target' on top, because we were
inspecting a corefile, but when the user decided to invoke "run" GDB
had to actually create the inferior, which ends up detecting that we
have a target already, and tries to close it (from target.c):

  /* See target.h.  */

  void
  target_stack::push (target_ops *t)
  {
    /* If there's already a target at this stratum, remove it.  */
    strata stratum = t->stratum ();

    if (m_stack[stratum] != NULL)
      {
	target_ops *prev = m_stack[stratum];
	m_stack[stratum] = NULL;
	target_close (prev); // <-- here
      }
  ...

When the current target ('core_target') is being closed, it checks for
possible observers registered with it and calls them.  TUI is one of
those observers, it gets called, tries to update the status line, and
GDB crashes.

The real problem is that we are clearing 'm_stack[stratum]', but
forgetting to adjust 'm_top'.  Interestingly, this scenario is covered
in 'target_stack::unpush', but Pedro said he forgot to call it here..
The fix, therefore, is to call '::unpush' if there's a target on the
stack.

This patch has been tested on the Buildbot and no regressions have
been found.  I'm also submitting a testcase for it.

gdb/ChangeLog:
2019-11-18  Sergio Durigan Junior  <[email protected]>
	    Pedro Alves  <[email protected]>

	https://bugzilla.redhat.com/show_bug.cgi?id=1765117
	* target.c (target_stack::push): Call 'unpush' if there's a
	target on top of the stack.

gdb/testsuite/ChangeLog:
2019-11-18  Sergio Durigan Junior  <[email protected]>

	https://bugzilla.redhat.com/show_bug.cgi?id=1765117
	* gdb.tui/corefile-run.exp: New file.

Change-Id: I39e2f8b538c580c8ea5bf1d657ee877e47746c8f
MaxKellermann pushed a commit that referenced this pull request Mar 23, 2020
…eader

A double-free happens when using a JIT debug info reader that creates
more than one block.  In the loop that frees blocks in finalize_symtab,
at the very end, the gdb_block_iter_tmp variable is set initially, but
not changed as the loop advances.  If we have two blocks, the first
iteration frees the first block, the second iteration frees the second
block, but the third iteration tries to free the second block again, as
gdb_block_iter_tmp keeps pointing on the second block.

Fix it by assigning the gdb_block_iter_tmp variable in the loop.

I have improved the jit-reader.exp test to cover this case, by adding a
second "JIT-ed" function and creating a block for it.  I have renamed
the existing function to something I find a bit more descriptive.  There
are no significant changes to jit-reader.exp itself, only updates
following the renaming.  The important changes are in jithost.c
(generate a new function) and in jitreader.c (create a gdb_block for
that function).

This was found because of an ASan report:

$ ./gdb testsuite/outputs/gdb.base/jit-reader/jit-reader -ex "jit-reader-load /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/jit-reader/jitreader.so" -ex r
Reading symbols from testsuite/outputs/gdb.base/jit-reader/jit-reader...
Starting program: /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/jit-reader/jit-reader
=================================================================
==1751048==ERROR: AddressSanitizer: heap-use-after-free on address 0x604000042eb8 at pc 0x5650ef8eec88 bp 0x7ffe52767290 sp 0x7ffe52767280
READ of size 8 at 0x604000042eb8 thread T0
    #0 0x5650ef8eec87 in finalize_symtab /home/simark/src/binutils-gdb/gdb/jit.c:768
    #1 0x5650ef8eef88 in jit_object_close_impl /home/simark/src/binutils-gdb/gdb/jit.c:797
    #2 0x7fbbda986278 in read_debug_info /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/jitreader.c:71
    bminor#3 0x5650ef8ef56b in jit_reader_try_read_symtab /home/simark/src/binutils-gdb/gdb/jit.c:850
    bminor#4 0x5650ef8effe3 in jit_register_code /home/simark/src/binutils-gdb/gdb/jit.c:948
    bminor#5 0x5650ef8f2c92 in jit_event_handler(gdbarch*) /home/simark/src/binutils-gdb/gdb/jit.c:1396
    bminor#6 0x5650ef0d137e in handle_jit_event /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470
    [snip]

0x604000042eb8 is located 40 bytes inside of 48-byte region [0x604000042e90,0x604000042ec0)
freed by thread T0 here:
    #0 0x7fbbe57376b0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122
    #1 0x5650ef8f350b in xfree<gdb_block> /home/simark/src/binutils-gdb/gdb/gdbsupport/common-utils.h:62
    #2 0x5650ef8eeca9 in finalize_symtab /home/simark/src/binutils-gdb/gdb/jit.c:769
    bminor#3 0x5650ef8eef88 in jit_object_close_impl /home/simark/src/binutils-gdb/gdb/jit.c:797
    bminor#4 0x7fbbda986278 in read_debug_info /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/jitreader.c:71
    bminor#5 0x5650ef8ef56b in jit_reader_try_read_symtab /home/simark/src/binutils-gdb/gdb/jit.c:850
    bminor#6 0x5650ef8effe3 in jit_register_code /home/simark/src/binutils-gdb/gdb/jit.c:948
    bminor#7 0x5650ef8f2c92 in jit_event_handler(gdbarch*) /home/simark/src/binutils-gdb/gdb/jit.c:1396
    bminor#8 0x5650ef0d137e in handle_jit_event /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470
    [snip]

previously allocated by thread T0 here:
    #0 0x7fbbe5737cd8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153
    #1 0x5650eef662f3 in xcalloc /home/simark/src/binutils-gdb/gdb/alloc.c:100
    #2 0x5650ef8f34ea in xcnew<gdb_block> /home/simark/src/binutils-gdb/gdb/gdbsupport/poison.h:122
    bminor#3 0x5650ef8ed467 in jit_block_open_impl /home/simark/src/binutils-gdb/gdb/jit.c:557
    bminor#4 0x7fbbda98620a in read_debug_info /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/jitreader.c:60
    bminor#5 0x5650ef8ef56b in jit_reader_try_read_symtab /home/simark/src/binutils-gdb/gdb/jit.c:850
    bminor#6 0x5650ef8effe3 in jit_register_code /home/simark/src/binutils-gdb/gdb/jit.c:948
    bminor#7 0x5650ef8f2c92 in jit_event_handler(gdbarch*) /home/simark/src/binutils-gdb/gdb/jit.c:1396
    bminor#8 0x5650ef0d137e in handle_jit_event /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470
    [snip]

gdb/ChangeLog:

	* jit.c (finalize_symtab): Set gdb_block_iter_tmp in loop.

gdb/testsuite/ChangeLog:

	* gdb.base/jit-reader.exp (jit_reader_test): Rename
	jit_function_00 to jit_function_stack_mangle.
	* gdb.base/jithost.c (jit_function_t): Rename to...
	(jit_function_stack_mangle_t): ... this.
	(jit_function_add_t): New typedef.
	(jit_function_00_code): Rename to...
	(jit_function_stack_mangle_code): ... this, make static.
	(jit_function_add_code): New.
	(main): Generate "add" function and call it.  Adjust to changes
	in jithost_abi.
	* gdb.base/jithost.h (struct jithost_abi_bounds): New.
	(struct jithost_abi) <begin, end>: Remove fields.
	<object, function_stack_mangle, function_add>: New fields.
	* gdb.base/jitreader.c (struct reader_state) <code_begin,
	code_end>: Remove fields.
	<func_stack_mangle>: New field.
	(read_debug_info): Adjust to renaming, create block for "add"
	function.
	(read_sp, unwind_frame, get_frame_id): Adjust to other changes.
MaxKellermann pushed a commit that referenced this pull request Mar 23, 2020
I stumbled on some ASan failures when using the TUI, when tearing down a
TUI layout.  The simplest way to trigger it is to run:

  $ ./gdb --data-directory=data-directory -batch -ex "layout next"

The ASan report is:

    =================================================================
    ==2829136==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x608000009a20 in thread T0:
      object passed to delete has wrong type:
      size of the allocated type:   88 bytes;
      size of the deallocated type: 24 bytes.
        #0 0x7f470fe2507e in operator delete(void*, unsigned long) /build/gcc/src/gcc/libsanitizer/asan/asan_new_delete.cc:177
        #1 0x55f88c75700d in std::default_delete<tui_layout_base>::operator()(tui_layout_base*) const /usr/include/c++/9.2.0/bits/unique_ptr.h:81
        #2 0x55f88c756328 in std::unique_ptr<tui_layout_base, std::default_delete<tui_layout_base> >::~unique_ptr() /usr/include/c++/9.2.0/bits/unique_ptr.h:284
        bminor#3 0x7f470ee536a6 in __run_exit_handlers (/usr/lib/libc.so.6+0x3e6a6)
        bminor#4 0x7f470ee5385d in __GI_exit (/usr/lib/libc.so.6+0x3e85d)
        bminor#5 0x55f88c69f2ac in quit_force(int*, int) /home/simark/src/binutils-gdb/gdb/top.c:1766
        bminor#6 0x55f88becc29a in captured_main_1 /home/simark/src/binutils-gdb/gdb/main.c:1183
        bminor#7 0x55f88becc814 in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1192
        bminor#8 0x55f88becc8a9 in gdb_main(captured_main_args*) /home/simark/src/binutils-gdb/gdb/main.c:1217
        bminor#9 0x55f88b3159cd in main /home/simark/src/binutils-gdb/gdb/gdb.c:32
        bminor#10 0x7f470ee3c152 in __libc_start_main (/usr/lib/libc.so.6+0x27152)
        bminor#11 0x55f88b31579d in _start (/home/simark/build/binutils-gdb/gdb/gdb+0x11fb79d)

    0x608000009a20 is located 0 bytes inside of 88-byte region [0x608000009a20,0x608000009a78)
    allocated by thread T0 here:
        #0 0x7f470fe238f8 in operator new(unsigned long) /build/gcc/src/gcc/libsanitizer/asan/asan_new_delete.cc:104
        #1 0x55f88c750906 in tui_layout_split::clone() const /home/simark/src/binutils-gdb/gdb/tui/tui-layout.c:515
        #2 0x55f88c74e60e in show_layout /home/simark/src/binutils-gdb/gdb/tui/tui-layout.c:90
        bminor#3 0x55f88c74e7db in tui_set_layout(tui_layout_type) /home/simark/src/binutils-gdb/gdb/tui/tui-layout.c:116
        bminor#4 0x55f88c782f4f in tui_enable() /home/simark/src/binutils-gdb/gdb/tui/tui.c:481
        bminor#5 0x55f88c74eeb2 in tui_layout_command /home/simark/src/binutils-gdb/gdb/tui/tui-layout.c:286
        bminor#6 0x55f88b6f969b in do_const_cfunc /home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:107
        bminor#7 0x55f88b701859 in cmd_func(cmd_list_element*, char const*, int) /home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:1952
        bminor#8 0x55f88c69b455 in execute_command(char const*, int) /home/simark/src/binutils-gdb/gdb/top.c:652
        bminor#9 0x55f88bec9026 in catch_command_errors /home/simark/src/binutils-gdb/gdb/main.c:400
        bminor#10 0x55f88becc1f2 in captured_main_1 /home/simark/src/binutils-gdb/gdb/main.c:1167
        bminor#11 0x55f88becc814 in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1192
        bminor#12 0x55f88becc8a9 in gdb_main(captured_main_args*) /home/simark/src/binutils-gdb/gdb/main.c:1217
        #13 0x55f88b3159cd in main /home/simark/src/binutils-gdb/gdb/gdb.c:32
        #14 0x7f470ee3c152 in __libc_start_main (/usr/lib/libc.so.6+0x27152)

The problem is that the tui_layout_base is missing a virtual destructor.
We allocate a derived object (tui_layout_split), but delete it through a
tui_layout_base pointer.  Since the tui_layout_base destructor is not
virtual, the derived (tui_layout_split) destructor is not called, only
the base destructor.

That code is not in gdb-9-branch, so I don't think this patch is
relevant for the stable branch.

Note that this is caught as a diagnostic with clang:

    In file included from /home/simark/src/binutils-gdb/gdb/tui/tui-layout.c:22:
    In file included from /home/simark/src/binutils-gdb/gdb/defs.h:28:
    In file included from /home/simark/src/binutils-gdb/gdb/gdbsupport/common-defs.h:133:
    In file included from /home/simark/src/binutils-gdb/gdb/gdbsupport/common-exceptions.h:25:
    In file included from /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/memory:80:
    /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/unique_ptr.h:81:2: error: delete called on 'tui_layout_base' that is abstract but has non-virtual destructor [-Werror,-Wdelete-abstract-non-virtual-dtor]
            delete __ptr;
            ^
    /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/unique_ptr.h:284:4: note: in instantiation of member function 'std::default_delete<tui_layout_base>::operator()' requested here
              get_deleter()(std::move(__ptr));
              ^
    /home/simark/src/binutils-gdb/gdb/tui/tui-layout.c:54:41: note: in instantiation of member function 'std::unique_ptr<tui_layout_base, std::default_delete<tui_layout_base> >::~unique_ptr' requested here
    static std::unique_ptr<tui_layout_base> applied_layout;
                                            ^
    1 error generated.

GCC has the similar -Wdelete-non-virtual-dtor, enabled by -Wall, but it
doesn't show up because warnings are inhibited for system headers, where
std::unique_ptr is defined.  There is a bug about it here:

    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58876

gdb/ChangeLog:

	* tui/tui-layout.h (class tui_layout_base): Add virtual
	destructor.
MaxKellermann pushed a commit that referenced this pull request Mar 23, 2020
…ring

This commit extends the CLI a bit for multi-target, in three ways.

#1 - New "info connections" command.

This is a new command that lists the open connections (process_stratum
targets).  For example, if you're debugging two remote connections, a
couple local/native processes, and a core dump, all at the same time,
you might see something like this:

 (gdb) info connections
   Num  What                     Description
   1    remote 192.168.0.1:9999  Remote serial target in gdb-specific protocol
   2    remote 192.168.0.2:9998  Remote serial target in gdb-specific protocol
 * 3    native                   Native process
   4    core                     Local core dump file

#2 - New "info inferiors" "Connection" column

You'll also see a new matching "Connection" column in "info
inferiors", showing you which connection an inferior is bound to:

 (gdb) info inferiors
   Num  Description       Connection                   Executable
   1    process 18526     1 (remote 192.168.0.1:9999)  target:/tmp/a.out
   2    process 18531     2 (remote 192.168.0.2:9998)  target:/tmp/a.out
   3    process 19115     3 (native)                   /tmp/prog1
   4    process 6286      4 (core)                     myprogram
 * 5    process 19122     3 (native)                   /bin/hello

bminor#3 - Makes "add-inferior" show the inferior's target connection

"add-inferior" now shows you the connection you've just bound the
inferior to, which is the current process_stratum target:

 (gdb) add-inferior
 [New inferior 2]
 Added inferior 2 on connection 1 (extended-remote localhost:2346)

gdb/ChangeLog:
2020-01-10  Pedro Alves  <[email protected]>

	* Makefile.in (COMMON_SFILES): Add target-connection.c.
	* inferior.c (uiout_field_connection): New function.
	(print_inferior): Add new "connection-id" column.
	(add_inferior_command): Show connection number/string of added
	inferior.
	* process-stratum-target.h
	(process_stratum_target::connection_string): New virtual method.
	(process_stratum_target::connection_number): New field.
	* remote.c (remote_target::connection_string): New override.
	* target-connection.c: New file.
	* target-connection.h: New file.
	* target.c (decref_target): Remove process_stratum targets from
	the connection list.
	(target_stack::push): Add process_stratum targets to the
	connection list.

gdb/testsuite/ChangeLog:
2020-01-10  Pedro Alves  <[email protected]>

	* gdb.base/kill-detach-inferiors-cmd.exp: Adjust expected output
	of "add-inferior".
	* gdb.base/quit-live.exp: Likewise.
	* gdb.base/remote-exec-file.exp: Likewise.
	* gdb.guile/scm-progspace.exp: Likewise.
	* gdb.linespec/linespec.exp: Likewise.
	* gdb.mi/new-ui-mi-sync.exp: Likewise.
	* gdb.mi/user-selected-context-sync.exp: Likewise.
	* gdb.multi/multi-target.exp (setup): Add "info connection" and
	"info inferiors" tests.
	* gdb.multi/remove-inferiors.exp: Adjust expected output of
	"add-inferior".
	* gdb.multi/watchpoint-multi.exp: Likewise.
	* gdb.python/py-inferior.exp: Likewise.
	* gdb.server/extended-remote-restart.exp: Likewise.
	* gdb.threads/fork-plus-threads.exp: Adjust expected output of
	"info inferiors".
	* gdb.threads/forking-threads-plus-breakpoint.exp: Likewise.
	* gdb.trace/report.exp: Likewise.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant