Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture c++ stack traces from core dump files on linux #38600

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
4 changes: 3 additions & 1 deletion Framework/Kernel/inc/MantidKernel/ErrorReporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class MANTID_KERNEL_DLL ErrorReporter {
const std::string &textBox);
/// Constructor
ErrorReporter(std::string application, Types::Core::time_duration startTime, std::string exitCode, bool share,
std::string name, std::string email, std::string textBox, std::string stacktrace);
std::string name, std::string email, std::string textBox, std::string stacktrace,
std::string cppTraces);
/// Sends an error report
Kernel::InternetHelper::HTTPStatus sendErrorReport();
/// Generates an error string in json format
Expand All @@ -50,6 +51,7 @@ class MANTID_KERNEL_DLL ErrorReporter {
const std::string m_textbox;
std::string m_url;
const std::string m_stacktrace;
const std::string m_cppTraces;
};

} // namespace Kernel
Expand Down
10 changes: 6 additions & 4 deletions Framework/Kernel/src/ErrorReporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ Logger g_log("ErrorReporter");
*/
ErrorReporter::ErrorReporter(const std::string &application, const Types::Core::time_duration &upTime,
const std::string &exitCode, const bool share)
: ErrorReporter(application, upTime, exitCode, share, "", "", "", "") {}
: ErrorReporter(application, upTime, exitCode, share, "", "", "", "", "") {}

/** Constructor
*/
ErrorReporter::ErrorReporter(const std::string &application, const Types::Core::time_duration &upTime,
const std::string &exitCode, const bool share, const std::string &name,
const std::string &email, const std::string &textBox)
: ErrorReporter(application, upTime, exitCode, share, name, email, textBox, "") {}
: ErrorReporter(application, upTime, exitCode, share, name, email, textBox, "", "") {}

ErrorReporter::ErrorReporter(std::string application, Types::Core::time_duration upTime, std::string exitCode,
const bool share, std::string name, std::string email, std::string textBox,
std::string traceback)
std::string traceback, std::string cppTraces)
: m_application(std::move(application)), m_exitCode(std::move(exitCode)), m_upTime(std::move(upTime)),
m_share(share), m_name(std::move(name)), m_email(std::move(email)), m_textbox(std::move(textBox)),
m_stacktrace(std::move(traceback)) {
m_stacktrace(std::move(traceback)), m_cppTraces(std::move(cppTraces)) {
auto url = Mantid::Kernel::ConfigService::Instance().getValue<std::string>("errorreports.rooturl");
if (!url.has_value()) {
g_log.debug() << "Failed to load error report url\n";
Expand Down Expand Up @@ -113,11 +113,13 @@ std::string ErrorReporter::generateErrorMessage() const {
message["email"] = m_email;
message["name"] = m_name;
message["stacktrace"] = m_stacktrace;
message["cppCompressedTraces"] = m_cppTraces;
} else {
message["email"] = "";
message["name"] = "";
message["textBox"] = m_textbox;
message["stacktrace"] = "";
message["cppCompressedTraces"] = "";
}

return Mantid::JsonHelpers::jsonToString(message);
Expand Down
13 changes: 8 additions & 5 deletions Framework/Kernel/test/ErrorReporterTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class ErrorReporterTest : public CxxTest::TestSuite {
const std::string appName = "My testing application name";
const Mantid::Types::Core::time_duration upTime(5, 0, 7, 0);
const std::string stackTrace = "File \" C :\\file\\path\\file.py\", line 194, in broken_function";
TestableErrorReporter reporter(appName, upTime, "0", true, "name", "email", "textBox", stackTrace);
TestableErrorReporter reporter(appName, upTime, "0", true, "name", "email", "textBox", stackTrace, "");
const std::string message = reporter.generateErrorMessage();

::Json::Value root;
Expand Down Expand Up @@ -102,7 +102,7 @@ class ErrorReporterTest : public CxxTest::TestSuite {
void test_errorMessageWithShareAndRecoveryFileHash() {
const std::string name = "My testing application name";
const Mantid::Types::Core::time_duration upTime(5, 0, 7, 0);
TestableErrorReporter errorService(name, upTime, "0", true, "name", "email", "textBox", "stacktrace");
TestableErrorReporter errorService(name, upTime, "0", true, "name", "email", "textBox", "stacktrace", "cppTraces");
const std::string message = errorService.generateErrorMessage();

::Json::Value root;
Expand All @@ -111,7 +111,7 @@ class ErrorReporterTest : public CxxTest::TestSuite {
const std::vector<std::string> expectedMembers{
"ParaView", "application", "host", "mantidSha1", "mantidVersion", "osArch",
"osName", "osReadable", "osVersion", "uid", "facility", "upTime",
"exitCode", "textBox", "name", "email", "stacktrace"};
"exitCode", "textBox", "name", "email", "stacktrace", "cppCompressedTraces"};
for (auto expectedMember : expectedMembers) {
TSM_ASSERT(expectedMember + " not found",
std::find(members.begin(), members.end(), expectedMember) != members.end());
Expand All @@ -124,12 +124,13 @@ class ErrorReporterTest : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(root["email"].asString(), "email");
TS_ASSERT_EQUALS(root["textBox"].asString(), "textBox");
TS_ASSERT_EQUALS(root["stacktrace"].asString(), "stacktrace");
TS_ASSERT_EQUALS(root["cppCompressedTraces"].asString(), "cppTraces");
}

void test_errorMessageWithNoShareAndRecoveryFileHash() {
const std::string name = "My testing application name";
const Mantid::Types::Core::time_duration upTime(5, 0, 7, 0);
TestableErrorReporter errorService(name, upTime, "0", false, "name", "email", "textBox", "stacktrace");
TestableErrorReporter errorService(name, upTime, "0", false, "name", "email", "textBox", "stacktrace", "cppTraces");
const std::string message = errorService.generateErrorMessage();

::Json::Value root;
Expand All @@ -138,7 +139,8 @@ class ErrorReporterTest : public CxxTest::TestSuite {
const std::vector<std::string> expectedMembers{
"ParaView", "application", "host", "mantidSha1", "mantidVersion", "osArch",
"osName", "osReadable", "osVersion", "uid", "facility", "upTime",
"exitCode", "textBox", "name", "email", "stacktrace"};
"exitCode", "textBox", "name", "email", "stacktrace", "upTime",
"exitCode", "textBox", "name", "email", "stacktrace", "cppCompressedTraces"};
for (auto expectedMember : expectedMembers) {
TSM_ASSERT(expectedMember + " not found",
std::find(members.begin(), members.end(), expectedMember) != members.end());
Expand All @@ -151,5 +153,6 @@ class ErrorReporterTest : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(root["email"].asString(), "");
TS_ASSERT_EQUALS(root["textBox"].asString(), "textBox");
TS_ASSERT_EQUALS(root["stacktrace"].asString(), "");
TS_ASSERT_EQUALS(root["cppCompressedTraces"].asString(), "");
}
};
3 changes: 3 additions & 0 deletions Framework/Properties/Mantid.properties.template
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ usagereports.enabled = @ENABLE_USAGE_REPORTS@
errorreports.rooturl = https://errorreports.mantidproject.org
usagereports.rooturl = https://reports.mantidproject.org

# Location of core dump files (linux only feature)
errorreports.core_dumps =

# Where to load Grouping files (that are shipped with Mantid) from
groupingFiles.directory = @MANTID_ROOT@/instrument/Grouping

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ void export_ErrorReporter() {
std::string>())

.def(init<std::string, Mantid::Types::Core::time_duration, std::string, bool, std::string, std::string,
std::string, std::string>())
std::string, std::string, std::string>())

.def("sendErrorReport", &ErrorReporter::sendErrorReport, arg("self"), "Sends an error report")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ def test_properties_documented(self):
"UpdateInstrumentDefinitions.URL", # shouldn't be changed by users
"docs.html.root", # shouldn't be changed by users
"errorreports.rooturl", # shouldn't be changed by users
"errorreports.core_dumps",
"usagereports.rooturl", # shouldn't be changed by users
"workspace.sendto.SansView.arguments",
"workspace.sendto.SansView.saveusing", # related to SASview in menu
Expand Down
2 changes: 2 additions & 0 deletions conda/recipes/mantid-developer/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ requirements:
- libboost-python-devel {{ libboost_python_devel }}
- libopenblas {{ libopenblas }} # [osx or linux]
- librdkafka {{ librdkafka }}
- lz4 # [linux]
- matplotlib {{ matplotlib }}
- mkl {{ mkl }} # [win]
- muparser {{ muparser }}
Expand All @@ -36,6 +37,7 @@ requirements:
- pycifrw
- pydantic
- pyqt {{ pyqt }}
- pystack # [linux]
- python-dateutil {{ python_dateutil }}
- python {{ python }}
- python.app # [osx]
Expand Down
2 changes: 2 additions & 0 deletions conda/recipes/mantidworkbench/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ requirements:
- versioningit {{ versioningit }}
run:
- ipykernel
- lz4 # [linux]
- psutil {{ psutil }}
- {{ pin_compatible("python", max_pin="x.x") }}
- matplotlib {{ matplotlib }}
- mslice {{ mslice }}
- python.app # [osx]
- pystack # [linux]
- qtconsole {{ qtconsole }}
- {{ pin_compatible("setuptools", max_pin="x.x") }}
{% if environ.get('INCLUDE_MANTIDDOCS', 'True') != 'False' %}
Expand Down
3 changes: 3 additions & 0 deletions docs/source/release/v6.12.0/Workbench/New_features/38405.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Added property ``errorreports.core_dumps``. Linux users can set this to the directory on their system where core dump files are put after a crash (e.g ``errorreports.core_dumps=/var/lib/apport/coredump``).
Workbench will then be able to use this property to extract useful information from the core dump file created after a crash and give that to the error reporting service.
This will help us to diagnose some problems where previously no stacktrace was available after a crash. On Linux, core dumps are now always turned on for the workbench process.
Loading
Loading