Exceptions from backend to GDB core?

Simon Marchi simon.marchi@polymtl.ca
Thu Jul 13 11:17:00 GMT 2017


On 2017-07-11 17:49, Yao Qi wrote:
> Hi,
> I am fixing PR 21555.  It is caused by an exception thrown from amd64
> prologue analyzer during breakpoint reset,
> 
> (gdb) bt
> #0  memory_error_message (err=TARGET_XFER_E_IO, gdbarch=0x153db50,
> memaddr=93824992233232) at ../../binutils-gdb/gdb/corefile.c:192
> #1  0x00000000005718ed in memory_error (err=TARGET_XFER_E_IO,
> memaddr=memaddr@entry=93824992233232) at
> ../../binutils-gdb/gdb/corefile.c:220
> #2  0x00000000005719d6 in read_memory_object
> (object=object@entry=TARGET_OBJECT_CODE_MEMORY,
> memaddr=93824992233232, memaddr@entry=1,
>     myaddr=myaddr@entry=0x7fffffffd0a0 "P\333S\001", len=len@entry=1)
> at ../../binutils-gdb/gdb/corefile.c:259
> #3  0x0000000000571c6e in read_code (len=1, myaddr=0x7fffffffd0a0
> "P\333S\001", memaddr=<optimized out>) at
> ../../binutils-gdb/gdb/corefile.c:287
> #4  read_code_unsigned_integer (memaddr=memaddr@entry=93824992233232,
> len=len@entry=1, byte_order=byte_order@entry=BFD_ENDIAN_LITTLE)
>     at ../../binutils-gdb/gdb/corefile.c:362
> #5  0x000000000041d4a0 in amd64_analyze_prologue
> (gdbarch=gdbarch@entry=0x153db50, pc=pc@entry=93824992233232,
>     current_pc=current_pc@entry=18446744073709551615,
> cache=cache@entry=0x7fffffffd1e0) at
> ../../binutils-gdb/gdb/amd64-tdep.c:2310
> #6  0x000000000041e404 in amd64_skip_prologue (gdbarch=0x153db50,
> start_pc=93824992233232) at ../../binutils-gdb/gdb/amd64-tdep.c:2459
> #7  0x000000000067bfb0 in skip_prologue_sal
> (sal=sal@entry=0x7fffffffd4e0) at ../../binutils-gdb/gdb/symtab.c:3628
> #8  0x000000000067c4d8 in find_function_start_sal
> (sym=sym@entry=0x1549960, funfirstline=1) at
> ../../binutils-gdb/gdb/symtab.c:3501
> #9  0x000000000060999d in symbol_to_sal
> (result=result@entry=0x7fffffffd5f0, funfirstline=<optimized out>,
> sym=sym@entry=0x1549960)
>     at ../../binutils-gdb/gdb/linespec.c:3860
> #10 0x000000000060a3a1 in convert_linespec_to_sals
> (state=state@entry=0x7fffffffda40, ls=ls@entry=0x7fffffffda90) at
> ../../binutils-gdb/gdb/linespec.c:2001
> #11 0x000000000060dc34 in convert_explicit_location_to_sals
> (explicit_loc=0x157c238, result=0x7fffffffda90, self=0x7fffffffda40)
>     at ../../binutils-gdb/gdb/linespec.c:2123
> #12 event_location_to_sals (parser=parser@entry=0x7fffffffda10,
> location=location@entry=0x157c230) at
> ../../binutils-gdb/gdb/linespec.c:2512
> #13 0x000000000060e988 in decode_line_full (location=0x157c230,
> flags=flags@entry=1, search_pspace=<optimized out>,
> default_symtab=default_symtab@entry=0x0,
>     default_line=default_line@entry=0,
> canonical=canonical@entry=0x7fffffffdb30, select_mode=0x91cb07
> <multiple_symbols_all> "all", filter=0x0)
>     at ../../binutils-gdb/gdb/linespec.c:2560
> #14 0x0000000000545b3c in decode_location_default (b=<optimized out>,
> sals=0x7fffffffdbf0, search_pspace=<optimized out>,
> location=<optimized out>)
>     at ../../binutils-gdb/gdb/breakpoint.c:14372
> #15 tracepoint_decode_location (b=<optimized out>, location=<optimized
> out>, search_pspace=<optimized out>, sals=0x7fffffffdbf0)
>     at ../../binutils-gdb/gdb/breakpoint.c:13419
> #16 0x000000000054b733 in location_to_sals (b=b@entry=0x15792d0,
> location=0x157c230, search_pspace=search_pspace@entry=0x1148120,
>     found=found@entry=0x7fffffffdc64) at
> ../../binutils-gdb/gdb/breakpoint.c:14211
> #17 0x000000000054c1f5 in breakpoint_re_set_default (b=0x15792d0) at
> ../../binutils-gdb/gdb/breakpoint.c:14301
> #18 0x00000000005412a9 in breakpoint_re_set_one
> (bint=bint@entry=0x15792d0) at
> ../../binutils-gdb/gdb/breakpoint.c:14412
> 
> The fix can be using the right target code api which doesn't throw
> exception (I've already had the fix).  However, this means each 
> target's
> prologue analyzer or its implementation of gdbarch_skip_prologue
> shouldn't throw any exception.  I feel it is a strict requirement, and
> difficult to guarantee that each port follow this.  Why don't we catch
> the exception when calling gdbarch_skip_prologue?  This reminds me the
> discussion last year about the graceful unwinding termination when the
> data is not available (examining traceframes)
> https://sourceware.org/ml/gdb-patches/2016-05/msg00060.html  Currently,
> each GDB backend should handle the unavailable data (i386, amd64, and
> aarch64),  I suggested that we can handle the exception in the common
> code, like catching the exception when calling fi->unwind->this_id.
> 
> These two problems have a common part, that is, each backend's
> implementation may throw exception, the questions are
> 
>  1) where do we catch exception?  Should each target backend catch 
> them,
>  or the common gdb code catch them?
>  2) or exception shouldn't be thrown from gdbarch's skip_prologue
>  implementation.  I feel it is difficult to enforce this.

I think it's fine if the skip_prologue implementations throw exceptions 
if they
are not able to return a valid result, that's what exceptions are for 
after all.
We just need to handle them properly.

How to handle the exception probably depends on the context in which
gdbarch_skip_prologue is called.  If that context can't continue its 
work
if gdbarch_skip_prologue fails, then it should let the exception 
propagate.
In other cases, where it's not fatal that the prologue skipping fails, 
we
could have a gdbarch_skip_prologue_nothrow wrapper for 
gdbarch_skip_prologue,
which would catch exceptions.  I suppose it would return the pc it was 
passed
in parameter (as if no prologue was skipped).

Simon



More information about the Gdb-patches mailing list