This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix GDB crash when registers cannot be modified.


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

commit ee3c5f8968e7b43854204898fa46933b3a1b5991
Author: Philippe Waroquiers <philippe.waroquiers@skynet.be>
Date:   Sat Apr 13 10:22:41 2019 +0200

    Fix GDB crash when registers cannot be modified.
    
    This crash was detected when using GDB with the valgrind gdbserver.
    To reproduce:
    
    valgrind sleep 10000
    
    In another window:
    gdb
    target remote | vgdb
    p printf("make sleep print something\n")
    =>
    terminate called after throwing an instance of 'gdb_exception_error'
    Aborted
    
    The problem is that the valgrind gdbserver does not allow to change
    registers when the inferior is blocked in a system call.
    GDB then raises an exception.  The exception causes the destructor
    of
     typedef std::unique_ptr<infcall_suspend_state, infcall_suspend_state_deleter>
        infcall_suspend_state_up;
    to be called.  This destructor itself tries to restore the value of
    the registers, and fails similarly.  We must catch the exception in
    the destructor to avoid crashing GDB.
    If the destructor encounters a problem, no warning is produced if
    there is an uncaught exception, as in this case, the user will already
    be informed of a problem via this exception.
    
    With this change, no crash anymore, and all the valgrind 3.15 tests
    pass succesfully.
    
    gdb/ChangeLog
    2019-04-19  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
    
    	* inferior.h (struct infcall_suspend_state_deleter):
    	Catch exception in destructor to avoid crash.

Diff:
---
 gdb/inferior.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/gdb/inferior.h b/gdb/inferior.h
index f98e67d..9e0e3b3 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -68,7 +68,18 @@ struct infcall_suspend_state_deleter
 {
   void operator() (struct infcall_suspend_state *state) const
   {
-    restore_infcall_suspend_state (state);
+    try
+      {
+	restore_infcall_suspend_state (state);
+      }
+    catch (const gdb_exception_error &e)
+      {
+	/* If we are restoring the inferior state due to an exception,
+	   some error message will be printed.  So, only warn the user
+	   when we cannot restore during normal execution.  */
+	if (!std::uncaught_exception ())
+	  warning (_("Failed to restore inferior state: %s"), e.what ());
+      }
   }
 };


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]