Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sentry_sdk/integrations/gnu_backtrace.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
FUNCTION_RE = r"[^@]+?)\s+@\s+0x[0-9a-fA-F]+"

FRAME_RE = r"""
^(?P<index>\d+)\.\s+(?P<function>{FUNCTION_RE}\s+in\s+(?P<package>.+)$
^(?P<index>\d+)\.\s+(?P<function>{FUNCTION_RE}(?:\s+in\s+(?P<package>.+))?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential bug: The `FUNCTION_RE` regex is syntactically incorrect, causing compilation to fail. This silently breaks the entire GNU backtrace integration, preventing stacktrace parsing.
  • Description: The FUNCTION_RE variable contains a malformed regular expression with an unbalanced parenthesis. When this is formatted into the main FRAME_RE, it results in a regex that cannot be compiled by re.compile. Because this compilation happens inside a capture_internal_exceptions() block, the re.error is caught and suppressed. Consequently, the GNU backtrace integration silently fails to parse any backtraces, leading to a complete loss of this debugging functionality without any warning to the user.
  • Suggested fix: The FUNCTION_RE constant is malformed with an extra parenthesis. It should be corrected to r&#x27;[^@]+?&#x27;. Consequently, FRAME_RE must be updated to explicitly include the address pattern (\s+@\s+0x[0-9a-fA-F]+) and correctly close the function capture group, ensuring the final regex is syntactically valid.
    severity: 0.8, confidence: 0.95

Did we get this right? 👍 / 👎 to inform future reviews.

""".format(
FUNCTION_RE=FUNCTION_RE,
)
Expand Down
30 changes: 29 additions & 1 deletion tests/integrations/test_gnu_backtrace.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,36 @@
24. ? @ 0x00000000000d162c in /usr/lib/aarch64-linux-gnu/libc-2.31.so
"""

LINES_NO_PATH = r"""
0. DB::Exception::Exception(DB::Exception::MessageMasked&&, int, bool) @ 0x000000000bfc38a4
1. DB::Exception::Exception<String, String>(int, FormatStringHelperImpl<std::type_identity<String>::type, std::type_identity<String>::type>, String&&, String&&) @ 0x00000000075d242c
2. DB::ActionsMatcher::visit(DB::ASTIdentifier const&, std::shared_ptr<DB::IAST> const&, DB::ActionsMatcher::Data&) @ 0x0000000010b1c648
3. DB::ActionsMatcher::visit(DB::ASTFunction const&, std::shared_ptr<DB::IAST> const&, DB::ActionsMatcher::Data&) @ 0x0000000010b1f58c
4. DB::ActionsMatcher::visit(DB::ASTFunction const&, std::shared_ptr<DB::IAST> const&, DB::ActionsMatcher::Data&) @ 0x0000000010b1f58c
5. DB::ActionsMatcher::visit(std::shared_ptr<DB::IAST> const&, DB::ActionsMatcher::Data&) @ 0x0000000010b1c394
6. DB::InDepthNodeVisitor<DB::ActionsMatcher, true, false, std::shared_ptr<DB::IAST> const>::doVisit(std::shared_ptr<DB::IAST> const&) @ 0x0000000010b154a0
7. DB::ExpressionAnalyzer::getRootActions(std::shared_ptr<DB::IAST> const&, bool, std::shared_ptr<DB::ActionsDAG>&, bool) @ 0x0000000010af83b4
8. DB::SelectQueryExpressionAnalyzer::appendSelect(DB::ExpressionActionsChain&, bool) @ 0x0000000010aff168
9. DB::ExpressionAnalysisResult::ExpressionAnalysisResult(DB::SelectQueryExpressionAnalyzer&, std::shared_ptr<DB::StorageInMemoryMetadata const> const&, bool, bool, bool, std::shared_ptr<DB::FilterDAGInfo> const&, std::shared_ptr<DB::FilterDAGInfo> const&, DB::Block const&) @ 0x0000000010b05b74
10. DB::InterpreterSelectQuery::getSampleBlockImpl() @ 0x00000000111559fc
11. DB::InterpreterSelectQuery::InterpreterSelectQuery(std::shared_ptr<DB::IAST> const&, std::shared_ptr<DB::Context> const&, std::optional<DB::Pipe>, std::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::vector<String, std::allocator<String>> const&, std::shared_ptr<DB::StorageInMemoryMetadata const> const&, std::shared_ptr<DB::PreparedSets>)::$_0::operator()(bool) const @ 0x0000000011148254
12. DB::InterpreterSelectQuery::InterpreterSelectQuery(std::shared_ptr<DB::IAST> const&, std::shared_ptr<DB::Context> const&, std::optional<DB::Pipe>, std::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::vector<String, std::allocator<String>> const&, std::shared_ptr<DB::StorageInMemoryMetadata const> const&, std::shared_ptr<DB::PreparedSets>) @ 0x00000000111413e8
13. DB::InterpreterSelectWithUnionQuery::InterpreterSelectWithUnionQuery(std::shared_ptr<DB::IAST> const&, std::shared_ptr<DB::Context>, DB::SelectQueryOptions const&, std::vector<String, std::allocator<String>> const&) @ 0x00000000111d3708
14. DB::InterpreterFactory::get(std::shared_ptr<DB::IAST>&, std::shared_ptr<DB::Context>, DB::SelectQueryOptions const&) @ 0x0000000011100b64
15. DB::executeQueryImpl(char const*, char const*, std::shared_ptr<DB::Context>, bool, DB::QueryProcessingStage::Enum, DB::ReadBuffer*) @ 0x00000000114c3f3c
16. DB::executeQuery(String const&, std::shared_ptr<DB::Context>, bool, DB::QueryProcessingStage::Enum) @ 0x00000000114c0ec8
17. DB::TCPHandler::runImpl() @ 0x00000000121bb5d8
18. DB::TCPHandler::run() @ 0x00000000121cb728
19. Poco::Net::TCPServerConnection::start() @ 0x00000000146d9404
20. Poco::Net::TCPServerDispatcher::run() @ 0x00000000146da900
21. Poco::PooledThread::run() @ 0x000000001484da7c
22. Poco::ThreadImpl::runnableEntry(void*) @ 0x000000001484bc24
23. start_thread @ 0x0000000000007624
24. ? @ 0x00000000000d162c
"""


@pytest.mark.parametrize("input", LINES.strip().splitlines())
@pytest.mark.parametrize("input", LINES.strip().splitlines() + LINES_NO_PATH.strip().splitlines())
def test_basic(sentry_init, capture_events, input):
sentry_init(integrations=[GnuBacktraceIntegration()])
events = capture_events()
Expand Down
Loading