binutils-gdb/gdb/tui
Simon Marchi 9b30da15e7 Add virtual destructor to tui_layout_base
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
        #3 0x7f470ee536a6 in __run_exit_handlers (/usr/lib/libc.so.6+0x3e6a6)
        #4 0x7f470ee5385d in __GI_exit (/usr/lib/libc.so.6+0x3e85d)
        #5 0x55f88c69f2ac in quit_force(int*, int) /home/simark/src/binutils-gdb/gdb/top.c:1766
        #6 0x55f88becc29a in captured_main_1 /home/simark/src/binutils-gdb/gdb/main.c:1183
        #7 0x55f88becc814 in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1192
        #8 0x55f88becc8a9 in gdb_main(captured_main_args*) /home/simark/src/binutils-gdb/gdb/main.c:1217
        #9 0x55f88b3159cd in main /home/simark/src/binutils-gdb/gdb/gdb.c:32
        #10 0x7f470ee3c152 in __libc_start_main (/usr/lib/libc.so.6+0x27152)
        #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
        #3 0x55f88c74e7db in tui_set_layout(tui_layout_type) /home/simark/src/binutils-gdb/gdb/tui/tui-layout.c:116
        #4 0x55f88c782f4f in tui_enable() /home/simark/src/binutils-gdb/gdb/tui/tui.c:481
        #5 0x55f88c74eeb2 in tui_layout_command /home/simark/src/binutils-gdb/gdb/tui/tui-layout.c:286
        #6 0x55f88b6f969b in do_const_cfunc /home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:107
        #7 0x55f88b701859 in cmd_func(cmd_list_element*, char const*, int) /home/simark/src/binutils-gdb/gdb/cli/cli-decode.c:1952
        #8 0x55f88c69b455 in execute_command(char const*, int) /home/simark/src/binutils-gdb/gdb/top.c:652
        #9 0x55f88bec9026 in catch_command_errors /home/simark/src/binutils-gdb/gdb/main.c:400
        #10 0x55f88becc1f2 in captured_main_1 /home/simark/src/binutils-gdb/gdb/main.c:1167
        #11 0x55f88becc814 in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1192
        #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.
2019-12-17 15:01:15 -05:00
..
ChangeLog-1998-2003
tui-command.c Remove struct tui_point 2019-12-11 15:49:01 -07:00
tui-command.h Remove can_highlight from TUI windows 2019-11-10 10:33:07 -07:00
tui-data.c Fix the "winheight" command 2019-11-19 13:27:25 -07:00
tui-data.h Remove struct tui_point 2019-12-11 15:49:01 -07:00
tui-disasm.c Allow using less horizontal space in TUI source window 2019-12-01 11:59:23 -07:00
tui-disasm.h Some i18n fixes for the TUI 2019-08-20 16:22:03 -06:00
tui-file.c Update copyright year range in all GDB files. 2019-01-01 10:01:51 +04:00
tui-file.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
tui-hooks.c Remove some includes of readline.h 2019-11-06 07:29:43 -07:00
tui-hooks.h Normalize include guards in gdb 2019-02-07 03:27:23 -07:00
tui-interp.c Remove some includes of readline.h 2019-11-06 07:29:43 -07:00
tui-io.c Add TUI border colors 2019-12-01 11:59:23 -07:00
tui-io.h Add TUI border colors 2019-12-01 11:59:23 -07:00
tui-layout.c Change "winheight" resizing to use new layout code 2019-12-11 15:49:03 -07:00
tui-layout.h Add virtual destructor to tui_layout_base 2019-12-17 15:01:15 -05:00
tui-out.c Introduce metadata style 2019-10-01 15:12:40 -06:00
tui-out.h Introduce metadata style 2019-10-01 15:12:40 -06:00
tui-regs.c Don't call erase_data_content from tui_data_window::show_registers 2019-10-09 16:50:36 -06:00
tui-regs.h Introduce the tui_gen_win_info::min_height method 2019-12-11 15:49:00 -07:00
tui-source.c Allow using less horizontal space in TUI source window 2019-12-01 11:59:23 -07:00
tui-source.h Style disassembly in the TUI 2019-11-05 15:23:36 -07:00
tui-stack.c Make TUI window handle a unique_ptr 2019-10-09 16:50:35 -06:00
tui-stack.h Introduce the tui_gen_win_info::min_height method 2019-12-11 15:49:00 -07:00
tui-win.c Change "winheight" resizing to use new layout code 2019-12-11 15:49:03 -07:00
tui-win.h Allow using less horizontal space in TUI source window 2019-12-01 11:59:23 -07:00
tui-wingeneral.c Remove struct tui_point 2019-12-11 15:49:01 -07:00
tui-wingeneral.h Make TUI window handle a unique_ptr 2019-10-09 16:50:35 -06:00
tui-winsource.c Fix latent bug in tui_copy_source_line 2019-12-01 12:29:50 -07:00
tui-winsource.h Allow using less horizontal space in TUI source window 2019-12-01 11:59:23 -07:00
tui.c Re-highlight windows when needed during TUI startup 2019-12-01 11:59:24 -07:00
tui.h Remove two TUI comments 2019-10-09 16:50:33 -06:00