Skip to content

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

@sbond75

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);

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