aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/terminate_handler
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/terminate_handler
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/terminate_handler')
-rw-r--r--library/cpp/terminate_handler/sample/exception/main.cpp15
-rw-r--r--library/cpp/terminate_handler/sample/exception/ya.make13
-rw-r--r--library/cpp/terminate_handler/sample/pure-virtual/main.cpp22
-rw-r--r--library/cpp/terminate_handler/sample/pure-virtual/ya.make13
-rw-r--r--library/cpp/terminate_handler/sample/rethrow/main.cpp20
-rw-r--r--library/cpp/terminate_handler/sample/rethrow/ya.make13
-rw-r--r--library/cpp/terminate_handler/sample/segv/main.cpp15
-rw-r--r--library/cpp/terminate_handler/sample/segv/ya.make13
-rw-r--r--library/cpp/terminate_handler/sample/ya.make6
-rw-r--r--library/cpp/terminate_handler/segv_handler.cpp34
-rw-r--r--library/cpp/terminate_handler/segv_handler.h3
-rw-r--r--library/cpp/terminate_handler/terminate_handler.cpp36
-rw-r--r--library/cpp/terminate_handler/ya.make13
13 files changed, 216 insertions, 0 deletions
diff --git a/library/cpp/terminate_handler/sample/exception/main.cpp b/library/cpp/terminate_handler/sample/exception/main.cpp
new file mode 100644
index 0000000000..35bfae8874
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/exception/main.cpp
@@ -0,0 +1,15 @@
+#include <util/generic/yexception.h>
+
+
+void Foo(unsigned i = 0) {
+ if (i >= 10) {
+ ythrow yexception() << "from Foo()";
+ } else {
+ Foo(i + 1);
+ }
+}
+
+int main() {
+ Foo();
+ return 0;
+}
diff --git a/library/cpp/terminate_handler/sample/exception/ya.make b/library/cpp/terminate_handler/sample/exception/ya.make
new file mode 100644
index 0000000000..958c26f89a
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/exception/ya.make
@@ -0,0 +1,13 @@
+PROGRAM(exception_sample)
+
+OWNER(nga)
+
+SRCS(
+ main.cpp
+)
+
+PEERDIR(
+ library/cpp/terminate_handler
+)
+
+END()
diff --git a/library/cpp/terminate_handler/sample/pure-virtual/main.cpp b/library/cpp/terminate_handler/sample/pure-virtual/main.cpp
new file mode 100644
index 0000000000..58217d5f24
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/pure-virtual/main.cpp
@@ -0,0 +1,22 @@
+
+struct TFoo {
+ TFoo() {
+ Baz();
+ }
+
+ void Baz() {
+ Bar();
+ }
+
+ virtual void Bar() = 0;
+};
+
+struct TQux: public TFoo {
+ void Bar() override {
+ }
+};
+
+int main() {
+ TQux();
+ return 0;
+}
diff --git a/library/cpp/terminate_handler/sample/pure-virtual/ya.make b/library/cpp/terminate_handler/sample/pure-virtual/ya.make
new file mode 100644
index 0000000000..4100da630d
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/pure-virtual/ya.make
@@ -0,0 +1,13 @@
+PROGRAM()
+
+OWNER(nga)
+
+SRCS(
+ main.cpp
+)
+
+PEERDIR(
+ library/cpp/terminate_handler
+)
+
+END()
diff --git a/library/cpp/terminate_handler/sample/rethrow/main.cpp b/library/cpp/terminate_handler/sample/rethrow/main.cpp
new file mode 100644
index 0000000000..fcd8592613
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/rethrow/main.cpp
@@ -0,0 +1,20 @@
+#include <util/generic/yexception.h>
+
+
+void Bar() {
+ ythrow yexception() << "from Foo()";
+}
+
+void Foo() {
+ try {
+ Bar();
+ } catch (...) {
+ Cerr << "caught; rethrowing\n";
+ throw;
+ }
+}
+
+int main() {
+ Foo();
+ return 0;
+}
diff --git a/library/cpp/terminate_handler/sample/rethrow/ya.make b/library/cpp/terminate_handler/sample/rethrow/ya.make
new file mode 100644
index 0000000000..4100da630d
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/rethrow/ya.make
@@ -0,0 +1,13 @@
+PROGRAM()
+
+OWNER(nga)
+
+SRCS(
+ main.cpp
+)
+
+PEERDIR(
+ library/cpp/terminate_handler
+)
+
+END()
diff --git a/library/cpp/terminate_handler/sample/segv/main.cpp b/library/cpp/terminate_handler/sample/segv/main.cpp
new file mode 100644
index 0000000000..52851bdb19
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/segv/main.cpp
@@ -0,0 +1,15 @@
+#include "../../segv_handler.h"
+
+void Bar(int* x) {
+ *x = 11;
+}
+
+void Foo(int* x) {
+ Bar(x);
+}
+
+int main() {
+ InstallSegvHandler();
+ Foo((int*)1);
+ return 0;
+}
diff --git a/library/cpp/terminate_handler/sample/segv/ya.make b/library/cpp/terminate_handler/sample/segv/ya.make
new file mode 100644
index 0000000000..4100da630d
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/segv/ya.make
@@ -0,0 +1,13 @@
+PROGRAM()
+
+OWNER(nga)
+
+SRCS(
+ main.cpp
+)
+
+PEERDIR(
+ library/cpp/terminate_handler
+)
+
+END()
diff --git a/library/cpp/terminate_handler/sample/ya.make b/library/cpp/terminate_handler/sample/ya.make
new file mode 100644
index 0000000000..af089abc65
--- /dev/null
+++ b/library/cpp/terminate_handler/sample/ya.make
@@ -0,0 +1,6 @@
+RECURSE(
+ exception
+ pure-virtual
+ rethrow
+ segv
+)
diff --git a/library/cpp/terminate_handler/segv_handler.cpp b/library/cpp/terminate_handler/segv_handler.cpp
new file mode 100644
index 0000000000..f24ece4125
--- /dev/null
+++ b/library/cpp/terminate_handler/segv_handler.cpp
@@ -0,0 +1,34 @@
+#include <util/system/platform.h>
+#include <util/system/yassert.h>
+#include <util/stream/output.h>
+#include <util/system/backtrace.h>
+
+#ifdef _unix_
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+
+#include "segv_handler.h"
+
+#ifndef _win_
+static void SegvHandler(int sig) {
+ Y_UNUSED(sig);
+ const char msg[] = "Got SEGV\n";
+ Y_UNUSED(write(STDERR_FILENO, msg, sizeof(msg)));
+ //PrintBackTrace();
+ sig_t r = signal(SIGSEGV, SIG_DFL);
+ if (r == SIG_ERR) {
+ abort();
+ }
+ // returning back and failing
+}
+#endif // !_win_
+
+void InstallSegvHandler() {
+#ifndef _win_
+ sig_t r = signal(SIGSEGV, &SegvHandler);
+ Y_VERIFY(r != SIG_ERR, "signal failed: %s", strerror(errno));
+#endif // !_win_
+}
diff --git a/library/cpp/terminate_handler/segv_handler.h b/library/cpp/terminate_handler/segv_handler.h
new file mode 100644
index 0000000000..c9f9051c7d
--- /dev/null
+++ b/library/cpp/terminate_handler/segv_handler.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void InstallSegvHandler();
diff --git a/library/cpp/terminate_handler/terminate_handler.cpp b/library/cpp/terminate_handler/terminate_handler.cpp
new file mode 100644
index 0000000000..d7e8fbed95
--- /dev/null
+++ b/library/cpp/terminate_handler/terminate_handler.cpp
@@ -0,0 +1,36 @@
+#include <cstdlib>
+#include <exception>
+
+#include <util/stream/output.h>
+#include <util/system/backtrace.h>
+#include <util/generic/yexception.h>
+
+namespace {
+ // Avoid infinite recursion if std::terminate is triggered anew by the
+ // FancyTerminateHandler.
+ thread_local int TerminateCount = 0;
+
+ void FancyTerminateHandler() {
+ switch (++TerminateCount) {
+ case 1:
+ break;
+ case 2:
+ Cerr << "FancyTerminateHandler called recursively" << Endl;
+ [[fallthrough]];
+ default:
+ abort();
+ break;
+ }
+
+ if (std::current_exception()) {
+ Cerr << "Uncaught exception: " << CurrentExceptionMessage() << '\n';
+ } else {
+ Cerr << "Terminate for unknown reason (no current exception)\n";
+ }
+ PrintBackTrace();
+ Cerr.Flush();
+ abort();
+ }
+
+ [[maybe_unused]] auto _ = std::set_terminate(&FancyTerminateHandler);
+}
diff --git a/library/cpp/terminate_handler/ya.make b/library/cpp/terminate_handler/ya.make
new file mode 100644
index 0000000000..70a9712fed
--- /dev/null
+++ b/library/cpp/terminate_handler/ya.make
@@ -0,0 +1,13 @@
+LIBRARY()
+
+OWNER(
+ ilnurkh
+ eeight
+)
+
+SRCS(
+ GLOBAL terminate_handler.cpp
+ segv_handler.cpp
+)
+
+END()