aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2021-03-19 15:26:41 +0000
committerHåvard Pettersen <havardpe@oath.com>2021-03-19 15:26:41 +0000
commit9a36eda856266bcdd5986ac4ca93fc9240abeb07 (patch)
tree71c4507c3cb1ac33c08dd297e816a19614dad4e6
parent028c4e6a1414a4180b198ae9b2bbfeb8f877f69f (diff)
added UnwindMessage/unwind_msg
-rw-r--r--vespalib/CMakeLists.txt1
-rw-r--r--vespalib/src/tests/unwind_message/CMakeLists.txt9
-rw-r--r--vespalib/src/tests/unwind_message/unwind_message_test.cpp37
-rw-r--r--vespalib/src/vespa/vespalib/util/CMakeLists.txt1
-rw-r--r--vespalib/src/vespa/vespalib/util/unwind_message.cpp37
-rw-r--r--vespalib/src/vespa/vespalib/util/unwind_message.h33
6 files changed, 118 insertions, 0 deletions
diff --git a/vespalib/CMakeLists.txt b/vespalib/CMakeLists.txt
index 5c0574aad8a..9e06bb152fd 100644
--- a/vespalib/CMakeLists.txt
+++ b/vespalib/CMakeLists.txt
@@ -133,6 +133,7 @@ vespa_define_module(
src/tests/tutorial/simple
src/tests/tutorial/threads
src/tests/typify
+ src/tests/unwind_message
src/tests/util/bfloat16
src/tests/util/file_area_freelist
src/tests/util/generationhandler
diff --git a/vespalib/src/tests/unwind_message/CMakeLists.txt b/vespalib/src/tests/unwind_message/CMakeLists.txt
new file mode 100644
index 00000000000..92295ada035
--- /dev/null
+++ b/vespalib/src/tests/unwind_message/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(vespalib_unwind_message_test_app TEST
+ SOURCES
+ unwind_message_test.cpp
+ DEPENDS
+ vespalib
+ GTest::GTest
+)
+vespa_add_test(NAME vespalib_unwind_message_test_app COMMAND vespalib_unwind_message_test_app)
diff --git a/vespalib/src/tests/unwind_message/unwind_message_test.cpp b/vespalib/src/tests/unwind_message/unwind_message_test.cpp
new file mode 100644
index 00000000000..53a7bf26c90
--- /dev/null
+++ b/vespalib/src/tests/unwind_message/unwind_message_test.cpp
@@ -0,0 +1,37 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/vespalib/util/unwind_message.h>
+#include <vespa/vespalib/gtest/gtest.h>
+#include <stdexcept>
+
+using vespalib::unwind_msg;
+using vespalib::UnwindMessage;
+
+//-----------------------------------------------------------------------------
+
+struct MyObj {
+ UnwindMessage msg1 = UnwindMessage("this SHOULD be printed (1/2)");
+ UnwindMessage msg2 = UnwindMessage("this should NOT be printed (1)");
+ ~MyObj() {
+ EXPECT_EQ(std::uncaught_exceptions(), 1);
+ auto not_printed_1 = std::move(msg2);
+ auto not_printed_2 = unwind_msg("this should NOT be printed (2)");
+ }
+};
+
+TEST(UnwindMessageTest, unwind_messages_are_printed_when_appropriate) {
+ using E = std::invalid_argument;
+ auto not_printed_3 = unwind_msg("this should NOT be printed (3)");
+ EXPECT_THROW(
+ {
+ EXPECT_EQ(std::uncaught_exceptions(), 0);
+ auto printed = unwind_msg("this SHOULD be printed (2/2)");
+ { auto not_printed_4 = unwind_msg("this should NOT be printed (4)"); }
+ MyObj my_obj;
+ throw E("just testing");
+ }, E);
+}
+
+//-----------------------------------------------------------------------------
+
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/vespalib/src/vespa/vespalib/util/CMakeLists.txt b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
index 080b7715646..17fc14d0e9e 100644
--- a/vespalib/src/vespa/vespalib/util/CMakeLists.txt
+++ b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
@@ -63,6 +63,7 @@ vespa_add_library(vespalib_vespalib_util OBJECT
threadstackexecutor.cpp
threadstackexecutorbase.cpp
time.cpp
+ unwind_message.cpp
valgrind.cpp
zstdcompressor.cpp
DEPENDS
diff --git a/vespalib/src/vespa/vespalib/util/unwind_message.cpp b/vespalib/src/vespa/vespalib/util/unwind_message.cpp
new file mode 100644
index 00000000000..8e96aa2110d
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/unwind_message.cpp
@@ -0,0 +1,37 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "unwind_message.h"
+#include "stringfmt.h"
+#include <exception>
+
+namespace vespalib {
+
+UnwindMessage::UnwindMessage(const vespalib::string &msg)
+ : _num_active(std::uncaught_exceptions()),
+ _message(msg)
+{
+}
+
+UnwindMessage::UnwindMessage(UnwindMessage &&rhs)
+ : _num_active(std::uncaught_exceptions()),
+ _message(rhs._message)
+{
+ rhs._message.clear();
+}
+
+UnwindMessage::~UnwindMessage() {
+ if ((std::uncaught_exceptions() != _num_active) && !_message.empty()) {
+ fprintf(stderr, "%s\n", _message.c_str());
+ }
+}
+
+UnwindMessage unwind_msg(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vespalib::string msg = make_string_va(fmt, ap);
+ va_end(ap);
+ return {msg};
+}
+
+} // namespace
diff --git a/vespalib/src/vespa/vespalib/util/unwind_message.h b/vespalib/src/vespa/vespalib/util/unwind_message.h
new file mode 100644
index 00000000000..5133e92742d
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/unwind_message.h
@@ -0,0 +1,33 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/vespalib/stllike/string.h>
+
+namespace vespalib {
+
+/**
+ * This class contains a message that will be printed to stderr if the
+ * object is destructed due to stack unwinding caused by an exception.
+ **/
+class UnwindMessage {
+private:
+ int _num_active;
+ vespalib::string _message;
+public:
+ UnwindMessage(const vespalib::string &msg);
+ UnwindMessage(UnwindMessage &&rhs);
+ UnwindMessage(const UnwindMessage &) = delete;
+ UnwindMessage &operator=(const UnwindMessage &) = delete;
+ UnwindMessage &operator=(UnwindMessage &&) = delete;
+ ~UnwindMessage();
+};
+
+extern UnwindMessage unwind_msg(const char *fmt, ...)
+#ifdef __GNUC__
+ // Add printf format checks with gcc
+ __attribute__ ((format (printf,1,2)))
+#endif
+ ;
+
+} // namespace