Skip to content

Commit

Permalink
Add stacktrace to ASSERTs (envoyproxy#38139)
Browse files Browse the repository at this point in the history
Commit Message: Add stacktrace to ASSERTs
Additional Description: Before this change, ASSERTs provoke a
stacktrace, but it is always the useless two-line stacktrace
```
#0: sigHandler()
#1: restore_rt
```
as demonstrated by the test case added in this PR not passing before the
change.
It's a bit odd that after this change there will be two stacktraces
output on assert, but at least one of them will be useful.

Risk Level: Minimal, it's just output from asserts so if it does
anything it's during a crash anyway.
Testing: Added a test case, and used to debug my production issue which
I couldn't with the original version.
Docs Changes: n/a
Release Notes: n/a
Platform Specific Features: n/a

---------

Signed-off-by: Raven Black <[email protected]>
  • Loading branch information
ravenblackx authored and bazmurphy committed Jan 29, 2025
1 parent d4b3681 commit d2a562e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
3 changes: 3 additions & 0 deletions source/common/common/assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ void resetEnvoyBugCountersForTest();
ENVOY_LOG_TO_LOGGER(Envoy::Logger::Registry::getLog(Envoy::Logger::Id::assert), critical, \
"assert failure: {}.{}{}", CONDITION_STR, \
details.empty() ? "" : " Details: ", details); \
Envoy::Assert::EnvoyBugStackTrace st; \
st.capture(); \
st.logStackTrace(); \
ACTION; \
} \
} while (false)
Expand Down
14 changes: 14 additions & 0 deletions test/common/common/assert_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace Envoy {

static void releaseAssertInAFunction() { RELEASE_ASSERT(0, ""); }

TEST(ReleaseAssertDeathTest, VariousLogs) {
EXPECT_DEATH({ RELEASE_ASSERT(0, ""); }, ".*assert failure: 0.*");
EXPECT_DEATH({ RELEASE_ASSERT(0, "With some logs"); },
Expand All @@ -15,6 +17,18 @@ TEST(ReleaseAssertDeathTest, VariousLogs) {
".*assert failure: 0 == EAGAIN. Details: using fmt.*");
}

TEST(ReleaseAssertDeathTest, AssertIncludesStackTrace) {
#ifdef NDEBUG
GTEST_SKIP() << "optimized build inlines functions so the stack trace won't be reliable";
#endif
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
GTEST_SKIP() << "memory sanitizer build inlines functions so the stack trace won't be reliable";
#endif
#endif
EXPECT_DEATH({ releaseAssertInAFunction(); }, "releaseAssertInAFunction");
}

TEST(AssertDeathTest, VariousLogs) {
int expected_counted_failures;
// Use 2 assert action registrations to verify that action chaining is working correctly.
Expand Down

0 comments on commit d2a562e

Please sign in to comment.