Skip to content

backward::SignalHandling crash_status not resetting to crash_status::running #351

Description

@sbond75

On Windows at least, there appears to be an edge case that only shows up when not linking against backward.cpp's singleton instance of backward::SignalHandling. Instead, in my code I was creating and destroying SignalHandling instances as needed. As a result, the reporter_thread_ exits shortly after starting, since crashed() returns crash_status::ending by the time that thread starts back up again in the new SignalHandling instance. Do you intend to support re-creating SignalHandling instances? If so, I have a potential fix below. It works in my testing, but only if at most one SignalHandling instance exists at a time (this doesn't make sense to support anyway).

diff --git a/backward.hpp b/backward.hpp
index 670aa45..632b372 100644
--- a/backward.hpp
+++ b/backward.hpp
@@ -4311,28 +4311,38 @@ private:
 class SignalHandling {
 public:
   SignalHandling(const std::vector<int> & = std::vector<int>())
-      : reporter_thread_([]() {
-          /* We handle crashes in a utility thread:
-            backward structures and some Windows functions called here
-            need stack space, which we do not have when we encounter a
-            stack overflow.
-            To support reporting stack traces during a stack overflow,
-            we create a utility thread at startup, which waits until a
-            crash happens or the program exits normally. */
-
-          {
-            std::unique_lock<std::mutex> lk(mtx());
-            cv().wait(lk, [] { return crashed() != crash_status::running; });
-          }
-          if (crashed() == crash_status::crashed) {
-            handle_stacktrace(skip_recs());
-          }
-          {
-            std::unique_lock<std::mutex> lk(mtx());
-            crashed() = crash_status::ending;
-          }
-          cv().notify_one();
-        }) {
+  {
+    // Reset crash status
+    {
+	  std::unique_lock<std::mutex> lk(mtx());
+	  crashed() = crash_status::running;
+    }
+
+    reporter_thread_ = std::thread([]() {
+	  /* We handle crashes in a utility thread:
+		backward structures and some Windows functions called here
+		need stack space, which we do not have when we encounter a
+		stack overflow.
+		To support reporting stack traces during a stack overflow,
+		we create a utility thread at startup, which waits until a
+		crash happens or the program exits normally. */
+
+	  crash_status status;
+	  {
+		std::unique_lock<std::mutex> lk(mtx());
+		cv().wait(lk, [] { return crashed() != crash_status::running; });
+		status = crashed();
+	  }
+	  if (status == crash_status::crashed) {
+		handle_stacktrace(skip_recs());
+	  }
+	  {
+		std::unique_lock<std::mutex> lk(mtx());
+		crashed() = crash_status::ending;
+	  }
+	  cv().notify_one();
+	});
+
     SetUnhandledExceptionFilter(crash_handler);
 
     signal(SIGABRT, signal_handler);

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions