[PATCH] gdb: improve error reporting from the disassembler
Andrew Burgess
andrew.burgess@embecosm.com
Wed Oct 13 09:40:03 GMT 2021
* Simon Marchi <simark@simark.ca> [2021-10-12 11:23:51 -0400]:
> On 2021-10-11 9:10 a.m., Andrew Burgess wrote:
> > If the libopcodes disassembler returns a negative value then this
> > indicates that the disassembly failed for some reason. In disas.c, in
> > the function gdb_disassembler::print_insn we can see how this is
> > handled; when we get a negative value back, we call the memory_error
> > function, which throws an exception.
> >
> > The problem here is that the address used in the memory_error call is
> > gdb_disassembler::m_err_memaddr, which is set in
> > gdb_disassembler::dis_asm_memory_error, which is called from within
> > the libopcodes disassembler through the
> > disassembler_info::memory_error_func callback.
> >
> > However, for this to work correctly, every time the libopcodes
> > disassembler returns a negative value, the libopcodes disassembler
> > must have first called the memory_error_func callback.
> >
> > My first plan was to make m_err_memaddr a gdb::optional, and assert
> > that it always had a value prior to calling memory_error, however, a
> > quick look in opcodes/*-dis.c shows that there _are_ cases where a
> > negative value is returned without first calling the memory_error_func
> > callback, for example in arc-dis.c and cris-dis.c.
> >
> > Now, I think that a good argument can be made that these disassemblers
> > must therefore be broken, except for the case where we can't read
> > memory, we should always be able to disassemble the memory contents to
> > _something_, even if it's just '.word 0x....'. However, I certainly
> > don't plan to go and fix all of the disassemblers.
> >
> > What I do propose to do then, is make m_err_memaddr a gdb::optional,
> > but now, instead of always calling memory_error, I add a new path
> > which just calls error complaining about an unknown error. This new
> > path is only used if m_err_memaddr doesn't have a value (indicating
> > that the memory_error_func callback was not called).
> >
> > To test this I just augmented one of the disassemblers to always
> > return -1, before this patch I see this:
> >
> > Dump of assembler code for function main:
> > 0x000101aa <+0>: Cannot access memory at address 0x0
> >
> > And after this commit I now see:
> >
> > Dump of assembler code for function main:
> > 0x000101aa <+0>: unknown disassembler error (error = -1)
> >
> > This doesn't really help much, but that's because there's no way to
> > report non memory errors out of the disasembler, because, it was not
> > expected that the disassembler would ever report non memory errors.
>
> The patch LGTM since it makes GDB more resilient against the bugs in
> opcodes. Given infinite time, we would fix opcodes, but this looks like
> a good compromise.
Thanks. I agree fixing libopcodes would be best in an ideal world,
but it's nice to harden GDB against these things.
> I'm wondering how you stumbled on that, did you actually get bitten by
> opcodes returning -1 but not calling memory_error_func?
No. I have an incoming patch to add a Python API for the
disassembler. As part of this work I was reviewing when the
disassembler can return -1. I initially reasoned that it should only
return -1 following a memory_error, but a quick grep disproved that
idea.
Thanks,
Andrew
More information about the Gdb-patches
mailing list