This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new 111513ea125 branch-4.1: [fix](be) Guard empty stack trace formatting
#65731 (#65743)
111513ea125 is described below
commit 111513ea12547eb0dc1830631a384ce89c5d5847
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Mon Jul 20 12:25:11 2026 +0800
branch-4.1: [fix](be) Guard empty stack trace formatting #65731 (#65743)
Cherry-picked from #65731
Co-authored-by: zclllyybb <[email protected]>
---
be/src/common/stack_trace.cpp | 23 ++++++++++++++++++-----
be/test/common/status_test.cpp | 29 +++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/be/src/common/stack_trace.cpp b/be/src/common/stack_trace.cpp
index 9ff2b3e7931..8ab6d76414a 100644
--- a/be/src/common/stack_trace.cpp
+++ b/be/src/common/stack_trace.cpp
@@ -44,6 +44,7 @@
#include "common/memory_sanitizer.h"
#include "common/symbol_index.h"
#include "exec/common/hex.h"
+#include "util/debug_points.h"
#include "util/string_util.h"
namespace {
@@ -304,11 +305,17 @@ StackTrace::StackTrace(const ucontext_t& signal_context) {
}
void StackTrace::tryCapture() {
+ int frame_count = 0;
#if defined(USE_UNWIND) && USE_UNWIND && defined(__x86_64__)
- size = unw_backtrace(frame_pointers.data(), capacity);
+ frame_count = unw_backtrace(frame_pointers.data(), capacity);
#else
- size = backtrace(frame_pointers.data(), capacity);
+ frame_count = backtrace(frame_pointers.data(), capacity);
#endif
+ size = frame_count > 0 ? static_cast<size_t>(frame_count) : 0;
+ if (doris::config::enable_debug_points &&
+
doris::DebugPoints::instance()->is_enable("StackTrace::tryCapture.empty_trace"))
{
+ size = 0;
+ }
__msan_unpoison(frame_pointers.data(), size * sizeof(frame_pointers[0]));
}
@@ -480,11 +487,17 @@ std::string StackTrace::toString(int start_pointers_index,
const std::string& dwarf_location_info_mode)
const {
// Default delete the first three frame pointers, which are inside the
stack_trace.cpp.
start_pointers_index += 3;
+ if (start_pointers_index < 0 || static_cast<size_t>(start_pointers_index)
>= size) {
+ // Unwind can legitimately return fewer frames than the internal
frames we normally hide.
+ return toStringCached({}, 0, 0, dwarf_location_info_mode);
+ }
+
+ const auto first_frame = static_cast<size_t>(start_pointers_index);
StackTrace::FramePointers frame_pointers_raw {};
- std::copy(frame_pointers.begin() + start_pointers_index,
frame_pointers.end(),
+ std::copy(frame_pointers.begin() + first_frame, frame_pointers.end(),
frame_pointers_raw.begin());
- return toStringCached(frame_pointers_raw, offset, size -
start_pointers_index,
- dwarf_location_info_mode);
+ return toStringCached(frame_pointers_raw, offset > first_frame ? offset -
first_frame : 0,
+ size - first_frame, dwarf_location_info_mode);
}
std::string StackTrace::toString(void** frame_pointers_raw, size_t offset,
size_t size,
diff --git a/be/test/common/status_test.cpp b/be/test/common/status_test.cpp
index f607e56f701..be555a0912c 100644
--- a/be/test/common/status_test.cpp
+++ b/be/test/common/status_test.cpp
@@ -21,11 +21,33 @@
#include <gtest/gtest-test-part.h>
#include "gtest/gtest_pred_impl.h"
+#include "util/debug_points.h"
namespace doris {
class StatusTest : public testing::Test {};
+class ScopedEmptyStackTraceFault {
+public:
+ ScopedEmptyStackTraceFault()
+ : _enable_debug_points(config::enable_debug_points),
+ _enable_stacktrace(config::enable_stacktrace) {
+ config::enable_debug_points = true;
+ config::enable_stacktrace = true;
+ DebugPoints::instance()->add("StackTrace::tryCapture.empty_trace");
+ }
+
+ ~ScopedEmptyStackTraceFault() {
+ DebugPoints::instance()->remove("StackTrace::tryCapture.empty_trace");
+ config::enable_stacktrace = _enable_stacktrace;
+ config::enable_debug_points = _enable_debug_points;
+ }
+
+private:
+ const bool _enable_debug_points;
+ const bool _enable_stacktrace;
+};
+
TEST_F(StatusTest, OK) {
// default
Status st;
@@ -117,6 +139,13 @@ TEST_F(StatusTest, Error) {
}
}
+TEST_F(StatusTest, EmptyCapturedStackTrace) {
+ ScopedEmptyStackTraceFault fault;
+
+ Status status = Status::NotFound("fault-injected empty stack trace");
+ EXPECT_NE(status.to_string().find("<Empty trace>"), std::string::npos);
+}
+
TEST_F(StatusTest /*unused*/, Format /*unused*/) {
// status == ok
Status st_ok = Status::OK();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]