Repository: getsentry/sentry

Issue:
native symbolicated 'const' functions incorrectly trimmed
### Environment

self-hosted (https://develop.sentry.dev/self-hosted/)

### Steps to Reproduce

Have the following verbose native frame `ShellCorona::screenInvariants() const [clone .cold] (shellcorona.cpp:847)`

The event has platform:native and the project has platform:native-qt in case that makes a difference

Full json blob of the frame:
```
            {
              "function": "const",
              "raw_function": "ShellCorona::screenInvariants() const [clone .cold]",
              "symbol": "_ZNK11ShellCorona16screenInvariantsEv.cold",
              "package": "/usr/bin/plasmashell",
              "filename": "shellcorona.cpp",
              "abs_path": "obj-x86_64-linux-gnu/shell/shell/shellcorona.cpp",
              "lineno": 847,
              "in_app": false,
              "vars": {},
              "data": {
                "orig_in_app": -1,
                "symbolicator_status": "symbolicated"
              },
              "instruction_addr": "0x558ba221ba82"
            },
```

### Expected Result

Trimmed name should be something like `ShellCorona::screenInvariants (shellcorona.cpp:847)`

### Actual Result

Trimmed name is `const (shellcorona.cpp:847)`

### Product Area

Issues

### Link

_No response_

### DSN

_No response_

### Version

_No response_


Discussion:
Assigning to @getsentry/support for [routing](https://open.sentry.io/triage/#2-route) ⏲️
This does not look like a self-hosted specific issue. Are you saying you expect `raw_function` to be `ShellCorona::screenInvariants (shellcorona.cpp:847)`?
> Are you saying you expect raw_function to be ShellCorona::screenInvariants (shellcorona.cpp:847)?

The `raw_function` is fine, the trimmed `function` on the other hand should be something like `ShellCorona::screenInvariants (shellcorona.cpp:847)`
Assigning to @getsentry/support for [routing](https://open.sentry.io/triage/#2-route) ⏲️
This issue is indeed unrelated to self-hosting but rather a problem in the function `trim_native_function_name()`: https://github.com/getsentry/sentry/blob/cb7125245b6f2c3e04d1930bc6c0da2a7a5494af/src/sentry/stacktraces/functions.py#L202-L208.

The removal of the `[clone .]`-suffix happens after the removal of `const` (via regex here: https://github.com/getsentry/sentry/blob/cb7125245b6f2c3e04d1930bc6c0da2a7a5494af/src/sentry/stacktraces/functions.py#L139-L144). This leaves the trailing `const` in the function name but later processing expects it to be removed: https://github.com/getsentry/sentry/blob/cb7125245b6f2c3e04d1930bc6c0da2a7a5494af/src/sentry/stacktraces/functions.py#L221-L234.

Since the heuristic of "the last token being the function name" no longer holds, we end up with "const" instead of the actual function name.

CC: @Swatinem, @kahest 

This should be moved to https://github.com/getsentry/sentry.

Resolving patch:
diff --git a/src/sentry/stacktraces/functions.py b/src/sentry/stacktraces/functions.py
--- a/src/sentry/stacktraces/functions.py
+++ b/src/sentry/stacktraces/functions.py
@@ -136,6 +136,14 @@ def trim_native_function_name(function, platform, normalize_lambdas=True):
     if function.startswith(("[", "+[", "-[")):
         return function
 
+    # Remove special `[clone .foo]` annotations for cloned/split functions
+    def process_brackets(value, start):
+        if value.startswith("clone ."):
+            return ""
+        return "[%s]" % value
+
+    function = replace_enclosed_string(function, "[", "]", process_brackets).rstrip()
+
     # Chop off C++ trailers
     while True:
         match = _cpp_trailer_re.search(function)
@@ -199,14 +207,6 @@ def process_generics(value, start):
 
     function = replace_enclosed_string(function, "<", ">", process_generics)
 
-    # Remove special `[clone .foo]` annotations for cloned/split functions
-    def process_brackets(value, start):
-        if value.startswith("clone ."):
-            return ""
-        return "[%s]" % value
-
-    function = replace_enclosed_string(function, "[", "]", process_brackets)
-
     is_thunk = "thunk for " in function  # swift
 
     tokens = split_func_tokens(function)


Test patch:
diff --git a/tests/sentry/stacktraces/test_functions.py b/tests/sentry/stacktraces/test_functions.py
--- a/tests/sentry/stacktraces/test_functions.py
+++ b/tests/sentry/stacktraces/test_functions.py
@@ -92,6 +92,7 @@
         ["lambda_7156c3ceaa11256748687ab67e3ef4cd", "lambda"],
         ["<lambda_7156c3ceaa11256748687ab67e3ef4cd>::operator()", "<lambda>::operator()"],
         ["trigger_crash_a(int*) [clone .constprop.0]", "trigger_crash_a"],
+        ["ShellCorona::screenInvariants() const [clone .cold]", "ShellCorona::screenInvariants"],
         [
             "__gnu_cxx::__verbose_terminate_handler() [clone .cold]",
             "__gnu_cxx::__verbose_terminate_handler",