Skip to content

Commit

Permalink
[Test] Enable printing stack trace after fatal errors
Browse files Browse the repository at this point in the history
  • Loading branch information
speth authored and ischoegl committed Jun 11, 2023
1 parent 5259b7f commit 3f24588
Show file tree
Hide file tree
Showing 14 changed files with 63 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/cantera/base/global.h
Expand Up @@ -275,6 +275,13 @@ bool legacy_rate_constants_used();
//! @copydoc Application::Messages::setLogger
void setLogger(Logger* logwriter);

//! Enables printing a stacktrace to `std::err` if a segfault occurs. The Boost
//! documentation says doing this from an error handler is not safe on all platforms
//! and risks deadlocking. However, it can be useful for debugging and is therefore
//! enabled when running tests.
//! @since New in Cantera 3.0
void printStackTraceOnSegfault();

//! Clip *value* such that lower <= value <= upper
template <class T>
inline T clip(const T& value, const T& lower, const T& upper)
Expand Down
1 change: 1 addition & 0 deletions interfaces/cython/cantera/_utils.pxd
Expand Up @@ -81,6 +81,7 @@ cdef extern from "cantera/base/global.h" namespace "Cantera":
cdef string CxxVersion "Cantera::version" ()
cdef cbool CxxUsesHDF5 "Cantera::usesHDF5" ()
cdef cbool CxxDebugModeEnabled "Cantera::debugModeEnabled" ()
cdef void CxxPrintStackTraceOnSegfault "Cantera::printStackTraceOnSegfault" ()


cdef extern from "cantera/cython/utils_utils.h":
Expand Down
9 changes: 9 additions & 0 deletions interfaces/cython/cantera/_utils.pyx
Expand Up @@ -72,6 +72,15 @@ _USE_SPARSE = False
def debug_mode_enabled():
return CxxDebugModeEnabled()

def print_stack_trace_on_segfault():
"""
Enable printing a stack trace if a segfault occurs. Not recommended for general
use as it is possible for this to deadlock.
.. versionadded:: 3.0
"""
CxxPrintStackTraceOnSegfault()

def appdelete():
""" Delete all global Cantera C++ objects """
CxxAppdelete()
Expand Down
25 changes: 25 additions & 0 deletions src/base/global.cpp
Expand Up @@ -6,8 +6,13 @@
#include "cantera/base/FactoryBase.h"
#include "application.h"
#include "cantera/base/AnyMap.h"

#define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED
#include <boost/stacktrace.hpp>
#include <boost/core/demangle.hpp>

#include <signal.h>

namespace Cantera
{

Expand Down Expand Up @@ -105,6 +110,26 @@ bool legacy_rate_constants_used()
return app()->legacy_rate_constants_used();
}

namespace {
void stacktraceWriter(int signum) {
if (signum == SIGSEGV) {
std::cerr << "\nSegmentation fault. Stack trace:\n";
} else {
std::cerr << "\nProcess terminated abnormally. Stack trace:\n";
}
::signal(signum, SIG_DFL);
std::cerr << boost::stacktrace::stacktrace();
::raise(signum);
}
}

void printStackTraceOnSegfault()
{
// Install signal handler to print stacktrace in case of segfault.
::signal(SIGSEGV, &stacktraceWriter);
::signal(SIGABRT, &stacktraceWriter);
}

// **************** Global Data ****************

void appdelete()
Expand Down
1 change: 1 addition & 0 deletions test/clib/test_clib.cpp
Expand Up @@ -230,6 +230,7 @@ int main(int argc, char** argv)
printf("Running main() from test_clib.cpp\n");
testing::InitGoogleTest(&argc, argv);
make_deprecation_warnings_fatal();
printStackTraceOnSegfault();
vector<string> fileNames = {"gtest-freeflame.yaml", "gtest-freeflame.h5"};
for (const auto& fileName : fileNames) {
if (std::ifstream(fileName).good()) {
Expand Down
1 change: 1 addition & 0 deletions test/equil/equil_gas.cpp
Expand Up @@ -315,6 +315,7 @@ int main(int argc, char** argv)
printf("Running main() from equil_gas.cpp\n");
testing::InitGoogleTest(&argc, argv);
make_deprecation_warnings_fatal();
printStackTraceOnSegfault();
int result = RUN_ALL_TESTS();
appdelete();
return result;
Expand Down
1 change: 1 addition & 0 deletions test/general/string_processing.cpp
Expand Up @@ -118,6 +118,7 @@ int main(int argc, char** argv)
printf("Running main() from string_processing.cpp\n");
testing::InitGoogleTest(&argc, argv);
Cantera::make_deprecation_warnings_fatal();
Cantera::printStackTraceOnSegfault();
int result = RUN_ALL_TESTS();
Cantera::appdelete();
return result;
Expand Down
11 changes: 11 additions & 0 deletions test/general/test_misc.cpp
@@ -0,0 +1,11 @@
// This file is part of Cantera. See License.txt in the top-level directory or
// at https://cantera.org/license.txt for license and copyright information.

#include "gtest/gtest.h"
#include "cantera/base/global.h"

using namespace Cantera;

TEST(FatalError, stacktrace) {
EXPECT_DEATH(std::abort(), "Stack trace");
}
1 change: 1 addition & 0 deletions test/kinetics/pdep.cpp
Expand Up @@ -226,6 +226,7 @@ int main(int argc, char** argv)
{
printf("Running main() from pdep.cpp\n");
Cantera::make_deprecation_warnings_fatal();
Cantera::printStackTraceOnSegfault();
testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
Cantera::appdelete();
Expand Down
1 change: 1 addition & 0 deletions test/oneD/test_oneD.cpp
Expand Up @@ -108,6 +108,7 @@ int main(int argc, char** argv)
printf("Running main() from test_oneD.cpp\n");
testing::InitGoogleTest(&argc, argv);
make_deprecation_warnings_fatal();
printStackTraceOnSegfault();
int result = RUN_ALL_TESTS();
appdelete();
return result;
Expand Down
1 change: 1 addition & 0 deletions test/python/utilities.py
Expand Up @@ -20,6 +20,7 @@

cantera.add_directory(TEST_DATA_PATH)
cantera.add_directory(CANTERA_DATA_PATH)
cantera.print_stack_trace_on_segfault()

@pytest.fixture
def allow_deprecated():
Expand Down
1 change: 1 addition & 0 deletions test/thermo/nasapoly.cpp
Expand Up @@ -132,6 +132,7 @@ int main(int argc, char** argv)
{
printf("Running main() from nasapoly.cpp\n");
Cantera::make_deprecation_warnings_fatal();
Cantera::printStackTraceOnSegfault();
testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
Cantera::appdelete();
Expand Down
2 changes: 2 additions & 0 deletions test/transport/transportFromScratch.cpp
Expand Up @@ -171,6 +171,8 @@ TEST_F(TransportFromScratch, thermalConductivityMulti)
int main(int argc, char** argv)
{
printf("Running main() from transportFromScratch.cpp\n");
make_deprecation_warnings_fatal();
printStackTraceOnSegfault();
testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
appdelete();
Expand Down
1 change: 1 addition & 0 deletions test/zeroD/test_zeroD.cpp
Expand Up @@ -197,6 +197,7 @@ int main(int argc, char** argv)
printf("Running main() from test_zeroD.cpp\n");
testing::InitGoogleTest(&argc, argv);
Cantera::make_deprecation_warnings_fatal();
printStackTraceOnSegfault();
int result = RUN_ALL_TESTS();
Cantera::appdelete();
return result;
Expand Down

0 comments on commit 3f24588

Please sign in to comment.