aboutsummaryrefslogtreecommitdiff
path: root/gdb/xml-syscall.h
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2018-11-26 12:48:05 +0000
committerAndrew Burgess <andrew.burgess@embecosm.com>2018-12-12 17:33:14 +0000
commit6bf78e29a1dea7121f050c6ee4990298eec679dd (patch)
tree97d751a6362da3d9417abbde65bed3546c5f8fe0 /gdb/xml-syscall.h
parent4de3d8d06673d130e256a6ad81e5df2e412934c1 (diff)
downloadbinutils-6bf78e29a1dea7121f050c6ee4990298eec679dd.zip
binutils-6bf78e29a1dea7121f050c6ee4990298eec679dd.tar.gz
binutils-6bf78e29a1dea7121f050c6ee4990298eec679dd.tar.bz2
gdb/infcall: Make infcall_suspend_state into a class
I ran into a situation where attempting to make an inferior function call would trigger an assertion, like this: (gdb) call some_inferior_function () ../../src/gdb/regcache.c:310: internal-error: void regcache::restore(readonly_detached_regcache*): Assertion `src != NULL' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) The problem that triggers the assertion is that in the function save_infcall_suspend_state, we basically did this: 1. Create empty infcall_suspend_state object. 2. Fill fields of infcall_suspend_state object. The problem is causes is that if filling any of the fields triggered an exception then the infcall_suspend_state object would be deleted while in a partially filled in state. In the specific case I encountered, I had a remote RISC-V target that claimed in its target description to support floating point registers. However, this was not true, and when GDB tried to read a floating point register the remote sent back an error. This error would cause an exception to be thrown while creating the readonly_detached_regcache, which in turn caused GDB to try and delete an infcall_suspend_state which didn't have any register state, and this triggered the assertion. To prevent this problem we have two possibilities, either, rewrite the restore code the handle partially initialised infcall_suspend_state objects, or, prevent partially initialised infcall_suspend_state objects from existing. The second of these seems like a better solution. So, in this patch, I move the filling in of the different infcall_suspend_state fields within a new constructor for infcall_suspend_state. Now, if generating one of those fields fails the destructor for infcall_suspend_state will not be executed and GDB will not try to restore the partially saved state. With this patch in place GDB now behaves like this: (gdb) call some_inferior_function () Could not fetch register "ft0"; remote failure reply 'E99' (gdb) The inferior function call is aborted due to the error. This has been tested against x86-64/Linux native, native-gdbserver, and native-extended-gdbserver with no regressions. I've manually tested this against my baddly behaving target and confirmed the inferior function call is aborted as described above. gdb/ChangeLog: * infrun.c (infcall_suspend_state::infcall_suspend_state): New. (infcall_suspend_state::registers): New. (infcall_suspend_state::restore): New. (infcall_suspend_state::thread_suspend): Rename to... (infcall_suspend_state::m_thread_suspend): ...this. (infcall_suspend_state::registers): Rename to... (infcall_suspend_state::m_registers): ...this. (infcall_suspend_state::siginfo_gdbarch): Rename to... (infcall_suspend_state::m_siginfo_gdbarch): ...this. (infcall_suspend_state::siginfo_data): Rename to... (infcall_suspend_state::m_siginfo_data): ...this. (save_infcall_suspend_state): Rewrite to use infcall_suspend_state constructor. (restore_infcall_suspend_state): Rewrite to use infcall_suspend_state::restore method. (get_infcall_suspend_state_regcache): Use infcall_suspend_state::registers method.
Diffstat (limited to 'gdb/xml-syscall.h')
0 files changed, 0 insertions, 0 deletions