[gdb] Fix rethrow exception slicing in insert_bp_location
authorTom de Vries <tdevries@suse.de>
Mon, 24 Oct 2022 12:20:49 +0000 (14:20 +0200)
committerTom de Vries <tdevries@suse.de>
Mon, 24 Oct 2022 12:20:49 +0000 (14:20 +0200)
The preferred way of rethrowing an exception is by using throw without
expression, because it avoids object slicing of the exception [1].

Fix this in insert_bp_location.

Tested on x86_64-linux.

[1] https://en.cppreference.com/w/cpp/language/throw

Approved-By: Andrew Burgess <aburgess@redhat.com>
gdb/breakpoint.c

index a0653f189b974c54abad23d2605abc562f15356c..a001e78cfb42ae90f238494feb01e44556f3ec3b 100644 (file)
@@ -2647,6 +2647,24 @@ breakpoint_kind (const struct bp_location *bl, CORE_ADDR *addr)
     return gdbarch_breakpoint_kind_from_pc (bl->gdbarch, addr);
 }
 
+#define RETHROW_ON_TARGET_CLOSE_ERROR(E)                               \
+  do                                                                   \
+    {                                                                  \
+      if ((E).reason != 0)                                             \
+       {                                                               \
+         /* Can't set the breakpoint.  */                              \
+                                                                       \
+         if ((E).error == TARGET_CLOSE_ERROR)                          \
+           /* If the target has closed then it will have deleted any   \
+              breakpoints inserted within the target inferior, as a    \
+              result any further attempts to interact with the         \
+              breakpoint objects is not possible.  Just rethrow the    \
+              error.  Don't use E to rethrow, to prevent object        \
+              slicing of the exception.  */                            \
+           throw;                                                      \
+       }                                                               \
+    } while (0)
+
 /* Insert a low-level "breakpoint" of some type.  BL is the breakpoint
    location.  Any error messages are printed to TMP_ERROR_STREAM; and
    DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems.
@@ -2734,6 +2752,7 @@ insert_bp_location (struct bp_location *bl,
            }
          catch (gdb_exception &e)
            {
+             RETHROW_ON_TARGET_CLOSE_ERROR (e);
              bp_excpt = std::move (e);
            }
        }
@@ -2773,6 +2792,7 @@ insert_bp_location (struct bp_location *bl,
                    }
                  catch (gdb_exception &e)
                    {
+                     RETHROW_ON_TARGET_CLOSE_ERROR (e);
                      bp_excpt = std::move (e);
                    }
 
@@ -2797,6 +2817,7 @@ insert_bp_location (struct bp_location *bl,
                }
              catch (gdb_exception &e)
                {
+                 RETHROW_ON_TARGET_CLOSE_ERROR (e);
                  bp_excpt = std::move (e);
                }
            }
@@ -2811,13 +2832,6 @@ insert_bp_location (struct bp_location *bl,
       if (bp_excpt.reason != 0)
        {
          /* Can't set the breakpoint.  */
-
-         /* If the target has closed then it will have deleted any
-            breakpoints inserted within the target inferior, as a result
-            any further attempts to interact with the breakpoint objects
-            is not possible.  Just rethrow the error.  */
-         if (bp_excpt.error == TARGET_CLOSE_ERROR)
-           throw bp_excpt;
          gdb_assert (bl->owner != nullptr);
 
          /* In some cases, we might not be able to insert a