Bug 20977 - GDB exception handling is broken on i686-w64-mingw32
Summary: GDB exception handling is broken on i686-w64-mingw32
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 7.12.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-12-16 14:07 UTC by Yao Qi
Modified: 2017-03-07 15:46 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yao Qi 2016-12-16 14:07:32 UTC
GDB 7.12 branch is crashed if I start it and type command "kill".

GNU gdb (GDB) 7.12.0.20161209-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) [New Thread 2936.0xb80]
kill

Thread 1 received signal SIGSEGV, Segmentation fault.
0x03ff662b in ?? ()
top?bt 15
#0  0x03ff662b in ?? ()
#1  0x00526b92 in stdin_event_handler (error=0, client_data=0x172ed8)
    at ../../binutils-gdb/gdb/event-top.c:555
#2  0x00525a94 in handle_file_event (ready_mask=<optimized out>,
    file_ptr=0x3ff5cb8) at ../../binutils-gdb/gdb/event-loop.c:733
#3  gdb_wait_for_event (block=block@entry=1)
    at ../../binutils-gdb/gdb/event-loop.c:884
#4  0x00525bfb in gdb_do_one_event ()
    at ../../binutils-gdb/gdb/event-loop.c:347
#5  0x00525ce5 in start_event_loop ()
    at ../../binutils-gdb/gdb/event-loop.c:371
#6  0x0051fada in captured_command_loop (data=0x0)
    at ../../binutils-gdb/gdb/main.c:324
#7  0x0051cf5d in catch_errors (
    func=func@entry=0x51fab0 <captured_command_loop(void*)>,
    func_args=func_args@entry=0x0,
    errstring=errstring@entry=0x7922bf <VEC_interp_factory_p_quick_push(VEC_inte
rp_factory_p*, interp_factory*, char const*, unsigned int)::__PRETTY_FUNCTION__+
351> "", mask=mask@entry=RETURN_MASK_ALL)
    at ../../binutils-gdb/gdb/exceptions.c:236
#8  0x00520f0c in captured_main (data=0x328feb4)
    at ../../binutils-gdb/gdb/main.c:1149
#9  gdb_main (args=args@entry=0x328feb4) at ../../binutils-gdb/gdb/main.c:1159
#10 0x0071e400 in main (argc=1, argv=0x171220)
    at ../../binutils-gdb/gdb/gdb.c:32
top?
Comment 1 Sourceware Commits 2016-12-20 16:23:52 UTC
The master branch has been updated by Pedro Alves <palves@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2693a26216c329bd7ec2aae7743409f572de4fa5

commit 2693a26216c329bd7ec2aae7743409f572de4fa5
Author: Pedro Alves <palves@redhat.com>
Date:   Tue Dec 20 15:46:44 2016 +0000

    Fix longjmp across readline w/ --enable-sjlj-exceptions toolchains
    
    Nowadays, GDB propagates C++ exceptions across readline using
    setjmp/longjmp 89525768cd08 ("Propagate GDB/C++ exceptions across
    readline using sj/lj-based TRY/CATCH") because DWARF-based unwinding
    can't cross C functions compiled without -fexceptions (see details
    from the commit above).
    
    Unfortunately, toolchains that use SjLj-based C++ exceptions got
    broken with that fix, because _Unwind_SjLj_Unregister, which is put at
    the exit of a function, is not executed due to the longjmp added by
    that commit.
    
     (gdb) [New Thread 2936.0xb80]
     kill
    
     Thread 1 received signal SIGSEGV, Segmentation fault.
     0x03ff662b in ?? ()
     top?bt 15
     #0  0x03ff662b in ?? ()
     #1  0x00526b92 in stdin_event_handler (error=0, client_data=0x172ed8)
        at ../../binutils-gdb/gdb/event-top.c:555
     #2  0x00525a94 in handle_file_event (ready_mask=<optimized out>,
        file_ptr=0x3ff5cb8) at ../../binutils-gdb/gdb/event-loop.c:733
     #3  gdb_wait_for_event (block=block@entry=1)
        at ../../binutils-gdb/gdb/event-loop.c:884
     #4  0x00525bfb in gdb_do_one_event ()
        at ../../binutils-gdb/gdb/event-loop.c:347
     #5  0x00525ce5 in start_event_loop ()
        at ../../binutils-gdb/gdb/event-loop.c:371
     #6  0x0051fada in captured_command_loop (data=0x0)
        at ../../binutils-gdb/gdb/main.c:324
     #7  0x0051cf5d in catch_errors (
        func=func@entry=0x51fab0 <captured_command_loop(void*)>,
        func_args=func_args@entry=0x0,
        errstring=errstring@entry=0x7922bf <VEC_interp_factory_p_quick_push(VEC_inte rp_factory_p*, interp_factory*, char const*, unsigned int)::__PRETTY_FUNCTION__+351> "", mask=mask@entry=RETURN_MASK_ALL)
        at ../../binutils-gdb/gdb/exceptions.c:236
     #8  0x00520f0c in captured_main (data=0x328feb4)
        at ../../binutils-gdb/gdb/main.c:1149
     #9  gdb_main (args=args@entry=0x328feb4) at ../../binutils-gdb/gdb/main.c:1159
     #10 0x0071e400 in main (argc=1, argv=0x171220)
        at ../../binutils-gdb/gdb/gdb.c:32
    
    Fix this by making the functions involved in setjmp/longjmp as
    noexcept, so that the compiler knows it doesn't need to emit the
    _Unwind_SjLj_Register / _Unwind_SjLj_Unregister calls for C++
    exceptions.
    
    Tested on x86_64 Fedora 23 with:
     - GCC 5.3.1 w/ DWARF-based exceptions.
     - GCC 7 built with --enable-sjlj-exceptions.
    
    gdb/ChangeLog:
    2016-12-20  Pedro Alves  <palves@redhat.com>
    	    Yao Qi  <yao.qi@linaro.org>
    
    	PR gdb/20977
    	* event-top.c (gdb_rl_callback_read_char_wrapper_noexcept): New
    	noexcept function, factored out from ...
    	(gdb_rl_callback_read_char_wrapper): ... this.
    	(gdb_rl_callback_handler): Mark noexcept.
Comment 2 Sourceware Commits 2016-12-20 16:31:16 UTC
The gdb-7.12-branch branch has been updated by Pedro Alves <palves@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ada8ff522ce970e11dae4a3463c899b64e6f5006

commit ada8ff522ce970e11dae4a3463c899b64e6f5006
Author: Pedro Alves <palves@redhat.com>
Date:   Tue Dec 20 16:25:54 2016 +0000

    Fix longjmp across readline w/ --enable-sjlj-exceptions toolchains
    
    Nowadays, GDB propagates C++ exceptions across readline using
    setjmp/longjmp 89525768cd08 ("Propagate GDB/C++ exceptions across
    readline using sj/lj-based TRY/CATCH") because DWARF-based unwinding
    can't cross C functions compiled without -fexceptions (see details
    from the commit above).
    
    Unfortunately, toolchains that use SjLj-based C++ exceptions got
    broken with that fix, because _Unwind_SjLj_Unregister, which is put at
    the exit of a function, is not executed due to the longjmp added by
    that commit.
    
     (gdb) [New Thread 2936.0xb80]
     kill
    
     Thread 1 received signal SIGSEGV, Segmentation fault.
     0x03ff662b in ?? ()
     top?bt 15
     #0  0x03ff662b in ?? ()
     #1  0x00526b92 in stdin_event_handler (error=0, client_data=0x172ed8)
        at ../../binutils-gdb/gdb/event-top.c:555
     #2  0x00525a94 in handle_file_event (ready_mask=<optimized out>,
        file_ptr=0x3ff5cb8) at ../../binutils-gdb/gdb/event-loop.c:733
     #3  gdb_wait_for_event (block=block@entry=1)
        at ../../binutils-gdb/gdb/event-loop.c:884
     #4  0x00525bfb in gdb_do_one_event ()
        at ../../binutils-gdb/gdb/event-loop.c:347
     #5  0x00525ce5 in start_event_loop ()
        at ../../binutils-gdb/gdb/event-loop.c:371
     #6  0x0051fada in captured_command_loop (data=0x0)
        at ../../binutils-gdb/gdb/main.c:324
     #7  0x0051cf5d in catch_errors (
        func=func@entry=0x51fab0 <captured_command_loop(void*)>,
        func_args=func_args@entry=0x0,
        errstring=errstring@entry=0x7922bf <VEC_interp_factory_p_quick_push(VEC_inte rp_factory_p*, interp_factory*, char const*, unsigned int)::__PRETTY_FUNCTION__+351> "", mask=mask@entry=RETURN_MASK_ALL)
        at ../../binutils-gdb/gdb/exceptions.c:236
     #8  0x00520f0c in captured_main (data=0x328feb4)
        at ../../binutils-gdb/gdb/main.c:1149
     #9  gdb_main (args=args@entry=0x328feb4) at ../../binutils-gdb/gdb/main.c:1159
     #10 0x0071e400 in main (argc=1, argv=0x171220)
        at ../../binutils-gdb/gdb/gdb.c:32
    
    Fix this by making the functions involved in setjmp/longjmp as
    noexcept, so that the compiler knows it doesn't need to emit the
    _Unwind_SjLj_Register / _Unwind_SjLj_Unregister calls for C++
    exceptions.
    
    Tested on x86_64 Fedora 23 with:
     - GCC 5.3.1 w/ DWARF-based exceptions.
     - GCC 7 built with --enable-sjlj-exceptions.
    
    gdb/ChangeLog:
    2016-12-20  Pedro Alves  <palves@redhat.com>
    	    Yao Qi  <yao.qi@linaro.org>
    
    	PR gdb/20977
    	* event-top.c (gdb_rl_callback_read_char_wrapper_noexcept): New
    	noexcept function, factored out from ...
    	(gdb_rl_callback_read_char_wrapper): ... this.
    	(gdb_rl_callback_handler): Mark noexcept.
Comment 3 Pedro Alves 2016-12-20 16:32:40 UTC
Fixed.
Comment 4 Sourceware Commits 2016-12-20 19:41:02 UTC
The gdb-7.12-branch branch has been updated by Pedro Alves <palves@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9bfe0298332782a9c082fb475bdf8eeeef8cf45e

commit 9bfe0298332782a9c082fb475bdf8eeeef8cf45e
Author: Pedro Alves <palves@redhat.com>
Date:   Tue Dec 20 19:18:15 2016 +0000

    gdb: Fix C and C++03 builds
    
    The readline/sjlj-exceptions fix added an unconditional use of
    noexcept, but that's only valid C++11, and 7.12 must build with C and
    C++03 too.  Fix this by adding a GDB_EXCEPT macro that compiles away
    to nothing in C, and to throw() in C++03, which I've confirmed fixes
    the original issue just the same as noexcept, with GCC 7 + -std=gnu+03
    + sjlj-exceptions.
    
    gdb/ChangeLog:
    2016-12-20  Pedro Alves  <palves@redhat.com>
    
    	PR gdb/20977
    	* event-top.c (GDB_NOEXCEPT): Define.
    	(gdb_rl_callback_read_char_wrapper_noexcept): Use GDB_NOEXCEPT
    	instead of noexcept and use (void) instead of ().
    	(gdb_rl_callback_handler): Use GDB_NOEXCEPT instead of noexcept.
Comment 5 Orgad Shaneh 2017-03-07 12:59:37 UTC
It still happens with 7.12.1 when I type an invalid command. Trace:

1  msvcrt!abort
2  uw_init_context_1
3  _Unwind_RaiseException
4  __cxa_throw
5  throw_exception_cxx                        common-exceptions.c 303
6  throw_exception                            common-exceptions.c 317
7  throw_it                                   common-exceptions.c 373
8  throw_verror                               common-exceptions.c 379
9  verror                                     utils.c             525
10 error                                      errors.c            43
11 undef_cmd_error                            cli-decode.c        1475
12 lookup_cmd                                 cli-decode.c        1517
13 execute_command                            top.c               630
14 command_handler                            event-top.c         641
15 command_line_handler                       event-top.c         833
16 gdb_rl_callback_handler                    event-top.c         213
17 rl_callback_read_char                      callback.c          220
18 gdb_rl_callback_read_char_wrapper_noexcept event-top.c         175
19 gdb_rl_callback_read_char_wrapper          event-top.c         192
20 stdin_event_handler                        event-top.c         568
21 handle_file_event                          event-loop.c        733
22 gdb_wait_for_event                         event-loop.c        884
23 gdb_do_one_event                           event-loop.c        347
24 gdb_do_one_event                           common-exceptions.h 225
25 start_event_loop                           event-loop.c        371
26 captured_command_loop                      main.c              324
27 catch_errors                               exceptions.c        236
28 captured_main                              main.c              1149
29 gdb_main                                   main.c              1159
30 main                                       gdb.c               32
Comment 6 Yao Qi 2017-03-07 14:52:02 UTC
(In reply to Orgad Shaneh from comment #5)
> It still happens with 7.12.1 when I type an invalid command. Trace:
> 
> 1  msvcrt!abort
> 2  uw_init_context_1
> 3  _Unwind_RaiseException
> 4  __cxa_throw
> 5  throw_exception_cxx                        common-exceptions.c 303
> 6  throw_exception                            common-exceptions.c 317
> 7  throw_it                                   common-exceptions.c 373
> 8  throw_verror                               common-exceptions.c 379
> 9  verror                                     utils.c             525
> 10 error                                      errors.c            43
> 11 undef_cmd_error                            cli-decode.c        1475
> 12 lookup_cmd                                 cli-decode.c        1517
> 13 execute_command                            top.c               630
> 14 command_handler                            event-top.c         641
> 15 command_line_handler                       event-top.c         833
> 16 gdb_rl_callback_handler                    event-top.c         213
> 17 rl_callback_read_char                      callback.c          220
> 18 gdb_rl_callback_read_char_wrapper_noexcept event-top.c         175
> 19 gdb_rl_callback_read_char_wrapper          event-top.c         192
> 20 stdin_event_handler                        event-top.c         568
> 21 handle_file_event                          event-loop.c        733
> 22 gdb_wait_for_event                         event-loop.c        884
> 23 gdb_do_one_event                           event-loop.c        347
> 24 gdb_do_one_event                           common-exceptions.h 225
> 25 start_event_loop                           event-loop.c        371
> 26 captured_command_loop                      main.c              324
> 27 catch_errors                               exceptions.c        236
> 28 captured_main                              main.c              1149
> 29 gdb_main                                   main.c              1159
> 30 main                                       gdb.c               32

What is your compiler building GDB?  So far, we only tested on DW2 and SJLJ
exception implementations.  If your compiler is MSVC, Structured Exception Handling (SEH) is possibly used.  As far as I am aware of, we didn't test it before.
Comment 7 Orgad Shaneh 2017-03-07 14:53:39 UTC
> What is your compiler building GDB?

mingw32 (on msys2 environment). It works fine with mingw64, but fails with 32.

There's actually a separate bug report for this: https://sourceware.org/bugzilla/show_bug.cgi?id=21078
Comment 8 Yao Qi 2017-03-07 15:14:12 UTC
(In reply to Orgad Shaneh from comment #7)
> > What is your compiler building GDB?
> 
> mingw32 (on msys2 environment). It works fine with mingw64, but fails with
> 32.
> 

Could you elaborate on what does work and what doesn't (mingw32 and mingw64)?  This PR is about i686-w64-mingw32, and it was fixed.

> There's actually a separate bug report for this:
> https://sourceware.org/bugzilla/show_bug.cgi?id=21078
Comment 9 Orgad Shaneh 2017-03-07 15:17:37 UTC
> Could you elaborate on what does work and what doesn't (mingw32 and mingw64)?  This PR is about i686-w64-mingw32, and it was fixed.

mingw64 seems to work fine.

mingw32 (i686-w64-mingw32) crashes when entering an invalid command. Tested with 7.12.1.
Comment 10 Pedro Alves 2017-03-07 15:20:58 UTC
#1 - What does "i686-w64-mingw32-gcc -v" say?  Is this a SJLJ or a DW2 toolchain?

#2 - Could you try relinking gdb without -static-libgcc and -static-libstdc++ ?
Comment 11 Orgad Shaneh 2017-03-07 15:38:54 UTC
> #1 - What does "i686-w64-mingw32-gcc -v" say?  Is this a SJLJ or a DW2 toolchain?

--disable-sjlj-exceptions --with-dwarf2

> #2 - Could you try relinking gdb without -static-libgcc and -static-libstdc++ ?

That solves it.
Comment 12 Pedro Alves 2017-03-07 15:46:22 UTC
> > #2 - Could you try relinking gdb without -static-libgcc and -static-libstdc++ ?

> That solves it.

OK, there's a pending patch to add a configure option to disable those already.  See bug 21187.