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

[ubsan-minimal] Switch to weak symbols for callbacks to allow overriding in client code #119242

Merged
merged 6 commits into from
Dec 13, 2024

Conversation

kstoimenov
Copy link
Contributor

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Dec 9, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Kirill Stoimenov (kstoimenov)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/119242.diff

1 Files Affected:

  • (modified) compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp (+3-2)
diff --git a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
index 53a3273e4e6980..aa91a66cb6d32e 100644
--- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
+++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
@@ -97,8 +97,9 @@ constexpr unsigned kAddrBuf = SANITIZER_WORDSIZE / 4;
 #define MSG_BUF_LEN(msg) (sizeof(MSG_TMPL(msg)) + kAddrBuf + 1)
 
 #define HANDLER_RECOVER(name, msg)                               \
-  INTERFACE void __ubsan_handle_##name##_minimal() {             \
-    uintptr_t caller = GET_CALLER_PC();                  \
+  SANITIZER_INTERFACE_WEAK_DEF(                                  \
+    void, __ubsan_handle_##name##_minimal, void) {               \
+    uintptr_t caller = GET_CALLER_PC();                          \
     if (!report_this_error(caller)) return;                      \
     char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg);              \
     decorate_msg(MSG_TMPL_END(msg_buf, msg), caller);            \

@kstoimenov kstoimenov requested a review from vitalybuka December 9, 2024 18:23
Copy link

github-actions bot commented Dec 9, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

#include <stdio.h>
#include <stdint.h>

void __ubsan_handle_implicit_conversion_minimal() {
Copy link
Collaborator

@vitalybuka vitalybuka Dec 9, 2024

Choose a reason for hiding this comment

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

I think it's going to be hard to maintain on client size, when we add more types of checks

I believe it should be single function with simple interface.

Maybe just existing:
void SANITIZER_CDECL __sanitizer_report_error_summary(const char *error_summary);

With exactly the same format of output.
"SUMMARY: ubsan: morestuff"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I renamed report_this_error to __sanitizer_report_ubsan_error so we have a single handler now. PTAL.

Copy link
Collaborator

Choose a reason for hiding this comment

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

There is function declared as:

void SANITIZER_CDECL
__sanitizer_report_error_summary(const char *error_summary);

if we abandon callerpc we can use that one
Do you see good usecase of it?

Copy link
Collaborator

@vitalybuka vitalybuka Dec 12, 2024

Choose a reason for hiding this comment

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

Maybe just

INTERFACE void __ubsan_handle_##name##_minimal() {                           \
    uintptr_t caller = GET_CALLER_PC();                                        \
    if (!report_this_error(caller))                                            \
      return;                                                                  \
    char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg);                            \
    decorate_msg(MSG_TMPL_END(msg_buf, msg), caller);                          \
    message(msg_buf);                                                          \
    __sanitizer_report_error_summary(msg_buf);                                 \
  }

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually just

NTERFACE void __ubsan_handle_##name##_minimal() {                           \
    uintptr_t caller = GET_CALLER_PC();                                        \
    if (!report_this_error(caller))                                            \
      return;                                                                  \
    char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg);                            \
    decorate_msg(MSG_TMPL_END(msg_buf, msg), caller);                          \
    __sanitizer_report_error_summary(msg_buf);                                 \
  }

With default implementation of __sanitizer_report_error_summary as write

uintptr_t caller = GET_CALLER_PC(); \
if (!report_this_error(caller)) return; \
uintptr_t caller = GET_CALLER_PC(); \
if (!__sanitizer_report_ubsan_error(caller, #name)) \
Copy link
Collaborator

Choose a reason for hiding this comment

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

we want msg, not name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We will need the name if we want to increment a counter. The way I am thinking about this is that we will have a 2 dimensional hash map and the logic will be to increment error_count[caller][name]. We additionally could pass the message also.

@@ -20,20 +20,21 @@ static __sanitizer::atomic_uintptr_t caller_pcs[kMaxCallerPcs];
// that "too many errors" has already been reported.
static __sanitizer::atomic_uint32_t caller_pcs_sz;

__attribute__((noinline)) static bool report_this_error(uintptr_t caller) {
SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error, uintptr_t caller,
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe sinc into __ubsan_report_error

    char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg);              \
    decorate_msg(MSG_TMPL_END(msg_buf, msg), caller);            

Copy link
Collaborator

Choose a reason for hiding this comment

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

and we can remove decorated_msg

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can't because it uses compile time string lengths: MSG_BUF_LEN(msg) is a constant.

Copy link
Collaborator

Choose a reason for hiding this comment

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

and lets flip orcer
__ubsan_report_error(caller, msg); -> __ubsan_report_error(kind, caller);

}
char msg_buf[128] = MSG_PREFIX;
const char *end = msg_buf + sizeof(msg_buf);
char *p = append_str(msg, msg_buf + sizeof(MSG_PREFIX) - 1, end);
Copy link
Collaborator

@vitalybuka vitalybuka Dec 13, 2024

Choose a reason for hiding this comment

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

insted of sizeof(MSG_PREFIX) - 1, making

char msg_buf[128];
p = msg_buf;
p = append_str(PREFIX, p, end);
p = append_str(msg, p, end);

Copy link
Collaborator

Choose a reason for hiding this comment

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

let's keep decorate_msg all printing tu
decorate_msg(buff, kind ,caller)

and just call decorate_msg twice for android, so we cant remove abort parameter

kstoimenov added a commit that referenced this pull request Dec 13, 2024
#119920)

This refactoring will allow to make this function weak later on so that
it could be overloaded by a client. See #119242.
@kstoimenov kstoimenov closed this Dec 13, 2024
@kstoimenov kstoimenov reopened this Dec 13, 2024
@kstoimenov kstoimenov merged commit 71d2fa7 into llvm:main Dec 13, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants