From 9b9f2c212a0080c99ab5bdc5440e017435355392 Mon Sep 17 00:00:00 2001 From: Nikolay Volosatov Date: Mon, 26 Aug 2024 19:08:54 +0100 Subject: [PATCH] Move demangle filter to an optional module (#540) * Move demangle to an optional filter * Fix code * Fix package * Add to sample * Fix format * Fix test * Add privacy info * Add subspec * Add demangling to installations * Add tests * Fix Swift demangle returning non-nil on failure * Add scheme * Add protocol pragma mark * Update README * Fix format * Fix missing import * Fix README --- .clang-format-ignore | 8 +- .../xcschemes/KSCrash-Package.xcscheme | 24 +++ KSCrash.podspec | 7 + Package.swift | 39 +++- README.md | 25 ++- Samples/Common/Package.swift | 1 + .../CrashTriggers/KSCrashTriggersList.mm | 11 +- .../LibraryBridge/ReportingSample.swift | 2 + .../KSCrashReportFilterDemangle.m | 171 ++++++++++++++++++ .../KSDemangle_CPP.cpp | 0 .../KSDemangle_CPP.h | 0 .../KSDemangle_Swift.cpp | 2 +- .../KSDemangle_Swift.h | 0 .../Resources/PrivacyInfo.xcprivacy | 14 ++ .../include/KSCrashReportFilterDemangle.h | 60 ++++++ .../llvm/ADT/KSOptional.h | 0 .../llvm/ADT/None.h | 0 .../llvm/ADT/StringRef.h | 0 .../llvm/Config/llvm-config.h | 0 .../llvm/LICENSE.TXT | 0 .../llvm/Support/AlignOf.h | 0 .../llvm/Support/Casting.h | 0 .../llvm/Support/Compiler.h | 0 .../llvm/Support/type_traits.h | 0 .../swift/Basic/Config.h | 0 .../swift/Basic/Context.cpp | 0 .../swift/Basic/Demangle.cpp | 0 .../swift/Basic/Demangle.h | 0 .../swift/Basic/DemangleNodes.def | 0 .../swift/Basic/DemangleNodes.h | 0 .../swift/Basic/Demangler.cpp | 0 .../swift/Basic/Demangler.h | 0 .../swift/Basic/Fallthrough.h | 0 .../swift/Basic/LLVM.h | 0 .../swift/Basic/Malloc.h | 0 .../swift/Basic/ManglingMacros.h | 0 .../swift/Basic/ManglingUtils.cpp | 0 .../swift/Basic/ManglingUtils.h | 0 .../swift/Basic/NodePrinter.cpp | 0 .../swift/Basic/OldDemangler.cpp | 0 .../swift/Basic/Platform.h | 0 .../swift/Basic/Punycode.cpp | 0 .../swift/Basic/Punycode.h | 0 .../swift/Basic/ReferenceStorage.def | 0 .../swift/Basic/STLExtras.h | 0 .../swift/Basic/StandardTypesMangling.def | 0 .../swift/Basic/SwiftDemangle.h | 0 .../swift/Basic/ValueWitnessMangling.def | 0 .../swift/Basic/Visibility.h | 0 .../swift/LICENSE.txt | 0 .../swift/SwiftStrings.h | 0 .../KSCrashInstallation.m | 11 +- .../include/KSCrashInstallation.h | 6 + Sources/KSCrashRecording/KSCrashReportFixer.c | 41 +---- .../KSCrashReportFilterDemangle_Tests.m | 161 +++++++++++++++++ .../Resources/processed.json | 4 +- 56 files changed, 530 insertions(+), 57 deletions(-) create mode 100644 Sources/KSCrashDemangleFilter/KSCrashReportFilterDemangle.m rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/KSDemangle_CPP.cpp (100%) rename Sources/{KSCrashRecordingCore/include => KSCrashDemangleFilter}/KSDemangle_CPP.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/KSDemangle_Swift.cpp (94%) rename Sources/{KSCrashRecordingCore/include => KSCrashDemangleFilter}/KSDemangle_Swift.h (100%) create mode 100644 Sources/KSCrashDemangleFilter/Resources/PrivacyInfo.xcprivacy create mode 100644 Sources/KSCrashDemangleFilter/include/KSCrashReportFilterDemangle.h rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/ADT/KSOptional.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/ADT/None.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/ADT/StringRef.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/Config/llvm-config.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/LICENSE.TXT (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/Support/AlignOf.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/Support/Casting.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/Support/Compiler.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/llvm/Support/type_traits.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Config.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Context.cpp (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Demangle.cpp (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Demangle.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/DemangleNodes.def (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/DemangleNodes.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Demangler.cpp (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Demangler.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Fallthrough.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/LLVM.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Malloc.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/ManglingMacros.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/ManglingUtils.cpp (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/ManglingUtils.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/NodePrinter.cpp (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/OldDemangler.cpp (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Platform.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Punycode.cpp (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Punycode.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/ReferenceStorage.def (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/STLExtras.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/StandardTypesMangling.def (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/SwiftDemangle.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/ValueWitnessMangling.def (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/Basic/Visibility.h (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/LICENSE.txt (100%) rename Sources/{KSCrashRecordingCore => KSCrashDemangleFilter}/swift/SwiftStrings.h (100%) create mode 100644 Tests/KSCrashDemangleFilterTests/KSCrashReportFilterDemangle_Tests.m diff --git a/.clang-format-ignore b/.clang-format-ignore index e866a0e03..fe95f175d 100644 --- a/.clang-format-ignore +++ b/.clang-format-ignore @@ -1,5 +1,5 @@ Sources/KSCrashRecordingCore/KSObjCApple.h -Sources/KSCrashRecordingCore/llvm/* -Sources/KSCrashRecordingCore/llvm/*/* -Sources/KSCrashRecordingCore/swift/* -Sources/KSCrashRecordingCore/swift/*/* +Sources/KSCrashDemangleFilter/llvm/* +Sources/KSCrashDemangleFilter/llvm/*/* +Sources/KSCrashDemangleFilter/swift/* +Sources/KSCrashDemangleFilter/swift/*/* diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/KSCrash-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/KSCrash-Package.xcscheme index aa89a5e89..cb5c54638 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/KSCrash-Package.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/KSCrash-Package.xcscheme @@ -91,6 +91,20 @@ ReferencedContainer = "container:"> + + + + + + + + #import +namespace sample_namespace +{ +class Report +{ + public: + static void crash() { throw std::runtime_error("C++ exception"); } +}; +} // namespace sample_namespace + @implementation KSCrashTriggersList + (void)trigger_nsException_genericNSException @@ -46,7 +55,7 @@ + (void)trigger_nsException_nsArrayOutOfBounds + (void)trigger_cpp_runtimeException { - throw std::runtime_error("C++ exception"); + sample_namespace::Report::crash(); } + (void)trigger_mach_badAccess diff --git a/Samples/Common/Sources/LibraryBridge/ReportingSample.swift b/Samples/Common/Sources/LibraryBridge/ReportingSample.swift index a2cf3610f..a21510ca1 100644 --- a/Samples/Common/Sources/LibraryBridge/ReportingSample.swift +++ b/Samples/Common/Sources/LibraryBridge/ReportingSample.swift @@ -28,6 +28,7 @@ import Foundation import KSCrashRecording import KSCrashFilters import KSCrashSinks +import KSCrashDemangleFilter import Logging public class ReportingSample { @@ -58,6 +59,7 @@ public class ReportingSample { public static func sampleLogToConsole() { KSCrash.shared.sink = CrashReportFilterPipeline(filtersArray: [ + CrashReportFilterDemangle(), SampleFilter(), SampleSink(), ]) diff --git a/Sources/KSCrashDemangleFilter/KSCrashReportFilterDemangle.m b/Sources/KSCrashDemangleFilter/KSCrashReportFilterDemangle.m new file mode 100644 index 000000000..e12870be8 --- /dev/null +++ b/Sources/KSCrashDemangleFilter/KSCrashReportFilterDemangle.m @@ -0,0 +1,171 @@ +// +// KSCrashReportFilterDemangle.m +// +// Created by Nikolay Volosatov on 2024-08-16. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "KSCrashReportFilterDemangle.h" + +#import "KSCrashReport.h" +#import "KSCrashReportFields.h" +#import "KSDemangle_CPP.h" +#import "KSSystemCapabilities.h" +#if KSCRASH_HAS_SWIFT +#import "KSDemangle_Swift.h" +#endif + +// #define KSLogger_LocalLevel TRACE +#import "KSLogger.h" + +@interface KSCrashReportFilterDemangle () + +@end + +@implementation KSCrashReportFilterDemangle + ++ (NSString *)demangledCppSymbol:(NSString *)symbol +{ + char *demangled = ksdm_demangleCPP(symbol.UTF8String); + if (demangled != NULL) { + NSString *result = [[NSString alloc] initWithBytesNoCopy:demangled + length:strlen(demangled) + encoding:NSUTF8StringEncoding + freeWhenDone:YES]; + KSLOG_DEBUG(@"Demangled a C++ symbol '%@' -> '%@'", symbol, result); + return result; + } + return nil; +} + ++ (NSString *)demangledSwiftSymbol:(NSString *)symbol +{ +#if KSCRASH_HAS_SWIFT + char *demangled = ksdm_demangleSwift(symbol.UTF8String); + if (demangled != NULL) { + NSString *result = [[NSString alloc] initWithBytesNoCopy:demangled + length:strlen(demangled) + encoding:NSUTF8StringEncoding + freeWhenDone:YES]; + KSLOG_DEBUG(@"Demangled a Swift symbol '%@' -> '%@'", symbol, result); + return result; + } +#endif + return nil; +} + ++ (NSString *)demangledSymbol:(NSString *)symbol +{ + return [self demangledCppSymbol:symbol] ?: [self demangledSwiftSymbol:symbol]; +} + +/** Recurcively demangles strings within the report. + * @param reportObj An object within the report (dictionary, array, string etc) + * @param path An array of strings representing keys in dictionaries. An empty key means an itteration within the array. + * @param depth Current depth of the path + * @return An updated object or `nil` if no changes were applied. + */ ++ (id)demangleReportObj:(id)reportObj path:(NSArray *)path depth:(NSUInteger)depth +{ + // Check for NSString and try demangle + if (depth == path.count) { + if ([reportObj isKindOfClass:[NSString class]] == NO) { + return nil; + } + NSString *demangled = [self demangledSymbol:reportObj]; + return demangled; + } + + NSString *pathComponent = path[depth]; + + // NSArray: + if (pathComponent.length == 0) { + if ([reportObj isKindOfClass:[NSArray class]] == NO) { + return nil; + } + NSArray *reportArray = reportObj; + NSMutableArray *__block result = nil; + [reportArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *_Nonnull stop) { + id demangled = [self demangleReportObj:obj path:path depth:depth + 1]; + if (demangled != nil && result == nil) { + // Initializing the updated array only on first demangled result + result = [NSMutableArray arrayWithCapacity:reportArray.count]; + for (NSUInteger subIdx = 0; subIdx < idx; ++subIdx) { + [result addObject:reportArray[subIdx]]; + } + } + result[idx] = demangled ?: obj; + }]; + return [result copy]; + } + + // NSDictionary: + if ([reportObj isKindOfClass:[NSDictionary class]] == NO) { + return nil; + } + NSDictionary *reportDict = reportObj; + id demangledElement = [self demangleReportObj:reportDict[pathComponent] path:path depth:depth + 1]; + if (demangledElement == nil) { + return nil; + } + NSMutableDictionary *result = [reportDict mutableCopy]; + result[pathComponent] = demangledElement; + return [result copy]; +} + +#pragma mark - KSCrashReportFilter + +- (void)filterReports:(NSArray> *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion +{ + NSArray *demanglePaths = @[ + @[ + KSCrashField_Crash, KSCrashField_Threads, @"", KSCrashField_Backtrace, KSCrashField_Contents, @"", + KSCrashField_SymbolName + ], + @[ + KSCrashField_RecrashReport, KSCrashField_Crash, KSCrashField_Threads, @"", KSCrashField_Backtrace, + KSCrashField_Contents, @"", KSCrashField_SymbolName + ], + @[ KSCrashField_Crash, KSCrashField_Error, KSCrashField_CPPException, KSCrashField_Name ], + @[ + KSCrashField_RecrashReport, KSCrashField_Crash, KSCrashField_Error, KSCrashField_CPPException, + KSCrashField_Name + ], + ]; + + NSMutableArray> *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReportDictionary *report in reports) { + if ([report isKindOfClass:[KSCrashReportDictionary class]] == NO) { + KSLOG_ERROR(@"Unexpected non-dictionary report: %@", report); + continue; + } + NSDictionary *reportDict = report.value; + for (NSArray *path in demanglePaths) { + reportDict = [[self class] demangleReportObj:reportDict path:path depth:0] ?: reportDict; + } + [filteredReports addObject:[KSCrashReportDictionary reportWithValue:reportDict]]; + } + + kscrash_callCompletion(onCompletion, filteredReports, YES, nil); +} + +@end diff --git a/Sources/KSCrashRecordingCore/KSDemangle_CPP.cpp b/Sources/KSCrashDemangleFilter/KSDemangle_CPP.cpp similarity index 100% rename from Sources/KSCrashRecordingCore/KSDemangle_CPP.cpp rename to Sources/KSCrashDemangleFilter/KSDemangle_CPP.cpp diff --git a/Sources/KSCrashRecordingCore/include/KSDemangle_CPP.h b/Sources/KSCrashDemangleFilter/KSDemangle_CPP.h similarity index 100% rename from Sources/KSCrashRecordingCore/include/KSDemangle_CPP.h rename to Sources/KSCrashDemangleFilter/KSDemangle_CPP.h diff --git a/Sources/KSCrashRecordingCore/KSDemangle_Swift.cpp b/Sources/KSCrashDemangleFilter/KSDemangle_Swift.cpp similarity index 94% rename from Sources/KSCrashRecordingCore/KSDemangle_Swift.cpp rename to Sources/KSCrashDemangleFilter/KSDemangle_Swift.cpp index bf738aac5..0e24c8e59 100644 --- a/Sources/KSCrashRecordingCore/KSDemangle_Swift.cpp +++ b/Sources/KSCrashDemangleFilter/KSDemangle_Swift.cpp @@ -32,7 +32,7 @@ extern "C" char *ksdm_demangleSwift(const char *mangledSymbol) { swift::Demangle::DemangleOptions options = swift::Demangle::DemangleOptions::SimplifiedUIDemangleOptions(); std::string demangled = swift::Demangle::demangleSymbolAsString(mangledSymbol, options); - if (demangled.length() == 0) { + if (demangled.length() == 0 || strcmp(mangledSymbol, demangled.c_str()) == 0) { return NULL; } return strdup(demangled.c_str()); diff --git a/Sources/KSCrashRecordingCore/include/KSDemangle_Swift.h b/Sources/KSCrashDemangleFilter/KSDemangle_Swift.h similarity index 100% rename from Sources/KSCrashRecordingCore/include/KSDemangle_Swift.h rename to Sources/KSCrashDemangleFilter/KSDemangle_Swift.h diff --git a/Sources/KSCrashDemangleFilter/Resources/PrivacyInfo.xcprivacy b/Sources/KSCrashDemangleFilter/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 000000000..0d1c54ca4 --- /dev/null +++ b/Sources/KSCrashDemangleFilter/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + diff --git a/Sources/KSCrashDemangleFilter/include/KSCrashReportFilterDemangle.h b/Sources/KSCrashDemangleFilter/include/KSCrashReportFilterDemangle.h new file mode 100644 index 000000000..e0ba776c9 --- /dev/null +++ b/Sources/KSCrashDemangleFilter/include/KSCrashReportFilterDemangle.h @@ -0,0 +1,60 @@ +// +// KSCrashReportFilterDemangle.h +// +// Created by Nikolay Volosatov on 2024-08-16. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "KSCrashReportFilter.h" +#import "KSJSONCodecObjC.h" + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** Demangle symbols in raw crash reports. + * + * Input: NSDictionary + * Output: NSDictionary + */ +NS_SWIFT_NAME(CrashReportFilterDemangle) +@interface KSCrashReportFilterDemangle : NSObject + +/** Demangles a C++ symbol. + * + * @param symbol The mangled symbol. + * + * @return A demangled symbol, or `nil` if demangling failed. + */ ++ (NSString *)demangledCppSymbol:(NSString *)symbol; + +/** Demangles a Swift symbol. + * + * @param symbol The mangled symbol. + * + * @return A demangled symbol, or `nil` if demangling failed. + */ ++ (NSString *)demangledSwiftSymbol:(NSString *)symbol; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/KSCrashRecordingCore/llvm/ADT/KSOptional.h b/Sources/KSCrashDemangleFilter/llvm/ADT/KSOptional.h similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/ADT/KSOptional.h rename to Sources/KSCrashDemangleFilter/llvm/ADT/KSOptional.h diff --git a/Sources/KSCrashRecordingCore/llvm/ADT/None.h b/Sources/KSCrashDemangleFilter/llvm/ADT/None.h similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/ADT/None.h rename to Sources/KSCrashDemangleFilter/llvm/ADT/None.h diff --git a/Sources/KSCrashRecordingCore/llvm/ADT/StringRef.h b/Sources/KSCrashDemangleFilter/llvm/ADT/StringRef.h similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/ADT/StringRef.h rename to Sources/KSCrashDemangleFilter/llvm/ADT/StringRef.h diff --git a/Sources/KSCrashRecordingCore/llvm/Config/llvm-config.h b/Sources/KSCrashDemangleFilter/llvm/Config/llvm-config.h similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/Config/llvm-config.h rename to Sources/KSCrashDemangleFilter/llvm/Config/llvm-config.h diff --git a/Sources/KSCrashRecordingCore/llvm/LICENSE.TXT b/Sources/KSCrashDemangleFilter/llvm/LICENSE.TXT similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/LICENSE.TXT rename to Sources/KSCrashDemangleFilter/llvm/LICENSE.TXT diff --git a/Sources/KSCrashRecordingCore/llvm/Support/AlignOf.h b/Sources/KSCrashDemangleFilter/llvm/Support/AlignOf.h similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/Support/AlignOf.h rename to Sources/KSCrashDemangleFilter/llvm/Support/AlignOf.h diff --git a/Sources/KSCrashRecordingCore/llvm/Support/Casting.h b/Sources/KSCrashDemangleFilter/llvm/Support/Casting.h similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/Support/Casting.h rename to Sources/KSCrashDemangleFilter/llvm/Support/Casting.h diff --git a/Sources/KSCrashRecordingCore/llvm/Support/Compiler.h b/Sources/KSCrashDemangleFilter/llvm/Support/Compiler.h similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/Support/Compiler.h rename to Sources/KSCrashDemangleFilter/llvm/Support/Compiler.h diff --git a/Sources/KSCrashRecordingCore/llvm/Support/type_traits.h b/Sources/KSCrashDemangleFilter/llvm/Support/type_traits.h similarity index 100% rename from Sources/KSCrashRecordingCore/llvm/Support/type_traits.h rename to Sources/KSCrashDemangleFilter/llvm/Support/type_traits.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Config.h b/Sources/KSCrashDemangleFilter/swift/Basic/Config.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Config.h rename to Sources/KSCrashDemangleFilter/swift/Basic/Config.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Context.cpp b/Sources/KSCrashDemangleFilter/swift/Basic/Context.cpp similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Context.cpp rename to Sources/KSCrashDemangleFilter/swift/Basic/Context.cpp diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Demangle.cpp b/Sources/KSCrashDemangleFilter/swift/Basic/Demangle.cpp similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Demangle.cpp rename to Sources/KSCrashDemangleFilter/swift/Basic/Demangle.cpp diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Demangle.h b/Sources/KSCrashDemangleFilter/swift/Basic/Demangle.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Demangle.h rename to Sources/KSCrashDemangleFilter/swift/Basic/Demangle.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/DemangleNodes.def b/Sources/KSCrashDemangleFilter/swift/Basic/DemangleNodes.def similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/DemangleNodes.def rename to Sources/KSCrashDemangleFilter/swift/Basic/DemangleNodes.def diff --git a/Sources/KSCrashRecordingCore/swift/Basic/DemangleNodes.h b/Sources/KSCrashDemangleFilter/swift/Basic/DemangleNodes.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/DemangleNodes.h rename to Sources/KSCrashDemangleFilter/swift/Basic/DemangleNodes.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Demangler.cpp b/Sources/KSCrashDemangleFilter/swift/Basic/Demangler.cpp similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Demangler.cpp rename to Sources/KSCrashDemangleFilter/swift/Basic/Demangler.cpp diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Demangler.h b/Sources/KSCrashDemangleFilter/swift/Basic/Demangler.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Demangler.h rename to Sources/KSCrashDemangleFilter/swift/Basic/Demangler.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Fallthrough.h b/Sources/KSCrashDemangleFilter/swift/Basic/Fallthrough.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Fallthrough.h rename to Sources/KSCrashDemangleFilter/swift/Basic/Fallthrough.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/LLVM.h b/Sources/KSCrashDemangleFilter/swift/Basic/LLVM.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/LLVM.h rename to Sources/KSCrashDemangleFilter/swift/Basic/LLVM.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Malloc.h b/Sources/KSCrashDemangleFilter/swift/Basic/Malloc.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Malloc.h rename to Sources/KSCrashDemangleFilter/swift/Basic/Malloc.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/ManglingMacros.h b/Sources/KSCrashDemangleFilter/swift/Basic/ManglingMacros.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/ManglingMacros.h rename to Sources/KSCrashDemangleFilter/swift/Basic/ManglingMacros.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/ManglingUtils.cpp b/Sources/KSCrashDemangleFilter/swift/Basic/ManglingUtils.cpp similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/ManglingUtils.cpp rename to Sources/KSCrashDemangleFilter/swift/Basic/ManglingUtils.cpp diff --git a/Sources/KSCrashRecordingCore/swift/Basic/ManglingUtils.h b/Sources/KSCrashDemangleFilter/swift/Basic/ManglingUtils.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/ManglingUtils.h rename to Sources/KSCrashDemangleFilter/swift/Basic/ManglingUtils.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/NodePrinter.cpp b/Sources/KSCrashDemangleFilter/swift/Basic/NodePrinter.cpp similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/NodePrinter.cpp rename to Sources/KSCrashDemangleFilter/swift/Basic/NodePrinter.cpp diff --git a/Sources/KSCrashRecordingCore/swift/Basic/OldDemangler.cpp b/Sources/KSCrashDemangleFilter/swift/Basic/OldDemangler.cpp similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/OldDemangler.cpp rename to Sources/KSCrashDemangleFilter/swift/Basic/OldDemangler.cpp diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Platform.h b/Sources/KSCrashDemangleFilter/swift/Basic/Platform.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Platform.h rename to Sources/KSCrashDemangleFilter/swift/Basic/Platform.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Punycode.cpp b/Sources/KSCrashDemangleFilter/swift/Basic/Punycode.cpp similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Punycode.cpp rename to Sources/KSCrashDemangleFilter/swift/Basic/Punycode.cpp diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Punycode.h b/Sources/KSCrashDemangleFilter/swift/Basic/Punycode.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Punycode.h rename to Sources/KSCrashDemangleFilter/swift/Basic/Punycode.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/ReferenceStorage.def b/Sources/KSCrashDemangleFilter/swift/Basic/ReferenceStorage.def similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/ReferenceStorage.def rename to Sources/KSCrashDemangleFilter/swift/Basic/ReferenceStorage.def diff --git a/Sources/KSCrashRecordingCore/swift/Basic/STLExtras.h b/Sources/KSCrashDemangleFilter/swift/Basic/STLExtras.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/STLExtras.h rename to Sources/KSCrashDemangleFilter/swift/Basic/STLExtras.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/StandardTypesMangling.def b/Sources/KSCrashDemangleFilter/swift/Basic/StandardTypesMangling.def similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/StandardTypesMangling.def rename to Sources/KSCrashDemangleFilter/swift/Basic/StandardTypesMangling.def diff --git a/Sources/KSCrashRecordingCore/swift/Basic/SwiftDemangle.h b/Sources/KSCrashDemangleFilter/swift/Basic/SwiftDemangle.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/SwiftDemangle.h rename to Sources/KSCrashDemangleFilter/swift/Basic/SwiftDemangle.h diff --git a/Sources/KSCrashRecordingCore/swift/Basic/ValueWitnessMangling.def b/Sources/KSCrashDemangleFilter/swift/Basic/ValueWitnessMangling.def similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/ValueWitnessMangling.def rename to Sources/KSCrashDemangleFilter/swift/Basic/ValueWitnessMangling.def diff --git a/Sources/KSCrashRecordingCore/swift/Basic/Visibility.h b/Sources/KSCrashDemangleFilter/swift/Basic/Visibility.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/Basic/Visibility.h rename to Sources/KSCrashDemangleFilter/swift/Basic/Visibility.h diff --git a/Sources/KSCrashRecordingCore/swift/LICENSE.txt b/Sources/KSCrashDemangleFilter/swift/LICENSE.txt similarity index 100% rename from Sources/KSCrashRecordingCore/swift/LICENSE.txt rename to Sources/KSCrashDemangleFilter/swift/LICENSE.txt diff --git a/Sources/KSCrashRecordingCore/swift/SwiftStrings.h b/Sources/KSCrashDemangleFilter/swift/SwiftStrings.h similarity index 100% rename from Sources/KSCrashRecordingCore/swift/SwiftStrings.h rename to Sources/KSCrashDemangleFilter/swift/SwiftStrings.h diff --git a/Sources/KSCrashInstallations/KSCrashInstallation.m b/Sources/KSCrashInstallations/KSCrashInstallation.m index e12f43637..f004fd202 100644 --- a/Sources/KSCrashInstallations/KSCrashInstallation.m +++ b/Sources/KSCrashInstallations/KSCrashInstallation.m @@ -32,6 +32,7 @@ #import "KSCrashInstallation+Private.h" #import "KSCrashReportFilterAlert.h" #import "KSCrashReportFilterBasic.h" +#import "KSCrashReportFilterDemangle.h" #import "KSJSONCodecObjC.h" #import "KSLogger.h" #import "KSNSErrorHelper.h" @@ -144,6 +145,7 @@ - (id)init - (id)initWithRequiredProperties:(NSArray *)requiredProperties { if ((self = [super init])) { + _isDemangleEnabled = YES; _crashHandlerDataBacking = [NSMutableData dataWithLength:sizeof(*self.crashHandlerData) + sizeof(*self.crashHandlerData->reportFields) * kMaxProperties]; @@ -311,7 +313,14 @@ - (void)sendAllReportsWithCompletion:(KSCrashReportFilterCompletion)onCompletion return; } - sink = [KSCrashReportFilterPipeline filterWithFilters:self.prependedFilters, sink, nil]; + NSMutableArray *sinkFilters = [@[ + self.prependedFilters, + sink, + ] mutableCopy]; + if (self.isDemangleEnabled) { + [sinkFilters insertObject:[KSCrashReportFilterDemangle new] atIndex:0]; + } + sink = [KSCrashReportFilterPipeline filterWithFiltersArray:sinkFilters]; KSCrash *handler = [KSCrash sharedInstance]; handler.sink = sink; diff --git a/Sources/KSCrashInstallations/include/KSCrashInstallation.h b/Sources/KSCrashInstallations/include/KSCrashInstallation.h index 7131799de..100518078 100644 --- a/Sources/KSCrashInstallations/include/KSCrashInstallation.h +++ b/Sources/KSCrashInstallations/include/KSCrashInstallation.h @@ -50,6 +50,12 @@ NS_SWIFT_NAME(CrashInstallation) */ @property(atomic, readwrite, assign, nullable) KSReportWriteCallback onCrash; +/** Flag for disabling built-in demangling pre-filter. + * If enabled an additional KSCrashReportFilterDemangle filter will be applied first. + * @note Enabled by-default. + */ +@property(nonatomic, assign) BOOL isDemangleEnabled; + /** Install this crash handler with a specific configuration. * Call this method instead of `-[KSCrash installWithConfiguration:error:]` to set up the crash handler * tailored for your specific backend requirements. diff --git a/Sources/KSCrashRecording/KSCrashReportFixer.c b/Sources/KSCrashRecording/KSCrashReportFixer.c index d97076ab2..1030f3135 100644 --- a/Sources/KSCrashRecording/KSCrashReportFixer.c +++ b/Sources/KSCrashRecording/KSCrashReportFixer.c @@ -24,18 +24,14 @@ // THE SOFTWARE. // -#include "KSCrashReportFields.h" -#include "KSDemangle_CPP.h" -#include "KSJSONCodec.h" -#include "KSSystemCapabilities.h" -#if KSCRASH_HAS_SWIFT -#include "KSDemangle_Swift.h" -#endif #include #include +#include "KSCrashReportFields.h" #include "KSDate.h" +#include "KSJSONCodec.h" #include "KSLogger.h" +#include "KSSystemCapabilities.h" #define MAX_DEPTH 100 #define MAX_NAME_LENGTH 100 @@ -47,17 +43,6 @@ static const char *datePaths[][MAX_DEPTH] = { }; static int datePathsCount = sizeof(datePaths) / sizeof(*datePaths); -static const char *demanglePaths[][MAX_DEPTH] = { - { "", KSCrashField_Crash, KSCrashField_Threads, "", KSCrashField_Backtrace, KSCrashField_Contents, "", - KSCrashField_SymbolName }, - { "", KSCrashField_RecrashReport, KSCrashField_Crash, KSCrashField_Threads, "", KSCrashField_Backtrace, - KSCrashField_Contents, "", KSCrashField_SymbolName }, - { "", KSCrashField_Crash, KSCrashField_Error, KSCrashField_CPPException, KSCrashField_Name }, - { "", KSCrashField_RecrashReport, KSCrashField_Crash, KSCrashField_Error, KSCrashField_CPPException, - KSCrashField_Name }, -}; -static int demanglePathsCount = sizeof(demanglePaths) / sizeof(*demanglePaths); - static const char *versionPaths[][MAX_DEPTH] = { { "", KSCrashField_Report, KSCrashField_Version }, { "", KSCrashField_RecrashReport, KSCrashField_Report, KSCrashField_Version }, @@ -134,11 +119,6 @@ static bool matchesMinVersion(FixupContext *context, int major, int minor, int p return result; } -static bool shouldDemangle(FixupContext *context, const char *name) -{ - return matchesAPath(context, name, demanglePaths, demanglePathsCount); -} - static bool shouldFixDate(FixupContext *context, const char *name) { return matchesAPath(context, name, datePaths, datePathsCount); @@ -197,22 +177,7 @@ static int onStringElement(const char *const name, const char *const value, void { FixupContext *context = (FixupContext *)userData; const char *stringValue = value; - char *demangled = NULL; - if (shouldDemangle(context, name)) { - demangled = ksdm_demangleCPP(value); -#if KSCRASH_HAS_SWIFT - if (demangled == NULL) { - demangled = ksdm_demangleSwift(value); - } -#endif - if (demangled != NULL) { - stringValue = demangled; - } - } int result = ksjson_addStringElement(context->encodeContext, name, stringValue, (int)strlen(stringValue)); - if (demangled != NULL) { - free(demangled); - } if (shouldSaveVersion(context, name)) { memset(context->reportVersionComponents, 0, sizeof(context->reportVersionComponents)); int versionPartsIndex = 0; diff --git a/Tests/KSCrashDemangleFilterTests/KSCrashReportFilterDemangle_Tests.m b/Tests/KSCrashDemangleFilterTests/KSCrashReportFilterDemangle_Tests.m new file mode 100644 index 000000000..5dac3daba --- /dev/null +++ b/Tests/KSCrashDemangleFilterTests/KSCrashReportFilterDemangle_Tests.m @@ -0,0 +1,161 @@ +// +// KSCrashReportFilterDemangle_Tests.m +// +// Created by Nikolay Volosatov on 2024-08-25. +// +// Copyright (c) 2012 Karl Stenerud. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall remain in place +// in this source code. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +#import "KSCrashReport.h" +#import "KSCrashReportFilterDemangle.h" + +@interface KSCrashReportFilterDemangle_Tests : XCTestCase + +@end + +@implementation KSCrashReportFilterDemangle_Tests + +- (void)setUp +{ +} + +#pragma mark – C++ demangling + +- (void)testIncorrectCppSymbols +{ + XCTAssertNil([KSCrashReportFilterDemangle demangledCppSymbol:@""]); + XCTAssertNil([KSCrashReportFilterDemangle demangledCppSymbol:@"23"]); + XCTAssertNil([KSCrashReportFilterDemangle demangledCppSymbol:@"Not a symbol"]); + XCTAssertNil([KSCrashReportFilterDemangle + demangledCppSymbol:@"sScS12ContinuationV5yieldyAB11YieldResultOyx__GxnF"]); // Swift +} + +- (void)testCorrectCppSymbols +{ + XCTAssertEqualObjects([KSCrashReportFilterDemangle demangledCppSymbol:@"_Z3foov"], @"foo()"); + XCTAssertEqualObjects( + [KSCrashReportFilterDemangle demangledCppSymbol:@"_ZN6Widget14setStyleOptionERK12StyleOptionsb"], + @"Widget::setStyleOption(StyleOptions const&, bool)"); + XCTAssertEqualObjects([KSCrashReportFilterDemangle demangledCppSymbol:@"_ZNSt8ios_base15sync_with_stdioEb"], + @"std::ios_base::sync_with_stdio(bool)"); + XCTAssertEqualObjects([KSCrashReportFilterDemangle demangledCppSymbol:@"_ZNKSt5ctypeIcE13_M_widen_initEv"], + @"std::ctype::_M_widen_init() const"); +} + +#pragma mark – Swift demangling + +- (void)testIncorrectSwiftSymbols +{ + XCTAssertNil([KSCrashReportFilterDemangle demangledSwiftSymbol:@""]); + XCTAssertNil([KSCrashReportFilterDemangle demangledSwiftSymbol:@"23"]); + XCTAssertNil([KSCrashReportFilterDemangle demangledSwiftSymbol:@"Not a symbol"]); + XCTAssertNil([KSCrashReportFilterDemangle demangledSwiftSymbol:@"_ZNSt8ios_base15sync_with_stdioEb"]); // C++ +} + +- (void)testCorrectSwiftSymbols +{ + XCTAssertEqualObjects([KSCrashReportFilterDemangle demangledSwiftSymbol:@"$s5HelloAAC8sayHelloyyF"], + @"Hello.sayHello()"); + XCTAssertEqualObjects([KSCrashReportFilterDemangle demangledSwiftSymbol:@"$s3Foo3BarC11doSomethingyyFZ"], + @"static Bar.doSomething()"); + XCTAssertEqualObjects([KSCrashReportFilterDemangle demangledSwiftSymbol:@"$s3app5ModelC5valueSSvg"], + @"Model.value.getter"); + XCTAssertEqualObjects([KSCrashReportFilterDemangle demangledSwiftSymbol:@"$s3Foo3BarC11doSomethingySiSS_SbtF"], + @"Bar.doSomething(_:_:)"); +} + +#pragma mark - Report + +- (void)testReportDemangle +{ + KSCrashReportFilterDemangle *filter = [KSCrashReportFilterDemangle new]; + KSCrashReportDictionary *mangledReport = [KSCrashReportDictionary reportWithValue:@{ + @"other_root_key" : @"A", + KSCrashField_Crash : @ { + @"other_crash_key" : @"B", + KSCrashField_Threads : @[ + @{ + KSCrashField_Backtrace : @ { + @"other_backtrace_key" : @"C", + KSCrashField_Contents : @[ + @{ + @"other_symbol_key" : @"D", + KSCrashField_SymbolName : @"_Z3foov", + }, + @{ + KSCrashField_SymbolName : @"$s5HelloAAC8sayHelloyyF", + }, + @{ + KSCrashField_SymbolName : @"Not_Mangled()", + }, + ], + }, + }, + @{ + @"empty_thread_key" : @"F", + }, + ], + }, + }]; + + KSCrashReportDictionary *expectedReport = [KSCrashReportDictionary reportWithValue:@{ + @"other_root_key" : @"A", + KSCrashField_Crash : @ { + @"other_crash_key" : @"B", + KSCrashField_Threads : @[ + @{ + KSCrashField_Backtrace : @ { + @"other_backtrace_key" : @"C", + KSCrashField_Contents : @[ + @{ + @"other_symbol_key" : @"D", + KSCrashField_SymbolName : @"foo()", + }, + @{ + KSCrashField_SymbolName : @"Hello.sayHello()", + }, + @{ + KSCrashField_SymbolName : @"Not_Mangled()", + }, + ], + }, + }, + @{ + @"empty_thread_key" : @"F", + }, + ], + }, + }]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"Filter callback called"]; + [filter filterReports:@[ mangledReport ] + onCompletion:^(NSArray> *filteredReports, BOOL completed, NSError *error) { + KSCrashReportDictionary *demangledReport = filteredReports.firstObject; + XCTAssertEqualObjects(demangledReport, expectedReport); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:0.1]; +} + +@end diff --git a/Tests/KSCrashRecordingTests/Resources/processed.json b/Tests/KSCrashRecordingTests/Resources/processed.json index 7f72b9b17..55f684ceb 100644 --- a/Tests/KSCrashRecordingTests/Resources/processed.json +++ b/Tests/KSCrashRecordingTests/Resources/processed.json @@ -2044,7 +2044,7 @@ { "object_name": "Crash-Tester", "object_addr": 929792, - "symbol_name": "MyCPPClass::throwAnException()", + "symbol_name": "_ZN10MyCPPClass16throwAnExceptionEv", "symbol_addr": 940800, "instruction_addr": 940935 }, @@ -2570,7 +2570,7 @@ "reason": "Something bad happened...", "type": "cpp_exception", "cpp_exception": { - "name": "MyException" + "name": "11MyException" } } },