From c7cbf32f5770c5eec2a2dd6eb7cf3153e654ed08 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 16 Nov 2020 13:46:44 -0800 Subject: [crashlog] Implement parser for JSON encoded crashlogs Add a parser for JSON crashlogs. The CrashLogParser now defers to either the JSONCrashLogParser or the TextCrashLogParser. It first tries to interpret the input as JSON, and if that fails falling back to the textual parser. Differential revision: https://reviews.llvm.org/D91130 --- .../Python/Crashlog/Inputs/Assertion.check | 1 + .../Python/Crashlog/Inputs/a.out.crash | 49 ++++++++ .../Python/Crashlog/Inputs/a.out.ips | 96 +++++++++++++++ .../Python/Crashlog/Inputs/test.c | 8 ++ .../Python/Crashlog/crashlog.test | 135 --------------------- .../ScriptInterpreter/Python/Crashlog/json.test | 10 ++ .../Python/Crashlog/parser_json.test | 45 +++++++ .../Python/Crashlog/parser_text.test | 135 +++++++++++++++++++++ .../Python/Crashlog/patch-crashlog.py | 60 +++++++++ .../ScriptInterpreter/Python/Crashlog/text.test | 10 ++ 10 files changed, 414 insertions(+), 135 deletions(-) create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/Assertion.check create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/a.out.crash create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/a.out.ips create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/test.c delete mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/crashlog.test create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/json.test create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/parser_json.test create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/parser_text.test create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/patch-crashlog.py create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/Crashlog/text.test (limited to 'lldb/test/Shell/ScriptInterpreter/Python') diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/Assertion.check b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/Assertion.check new file mode 100644 index 0000000..d92fb50 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/Assertion.check @@ -0,0 +1 @@ +# CHECK-NOT: AssertionError diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/a.out.crash b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/a.out.crash new file mode 100644 index 0000000..27ffd9e --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/a.out.crash @@ -0,0 +1,49 @@ +Process: a.out [21606] +Path: /private/tmp/a.out +Identifier: a.out +Version: 0 +Code Type: X86-64 (Native) +Parent Process: fish [88883] +User ID: 501 + +Date/Time: 2020-11-11 14:47:34.600 -0800 +OS Version: macOS 11.0.1 +Report Version: 12 +Bridge OS Version: redacted +Anonymous UUID: DCEF35CB-68D5-F524-FF13-060901F52EA8 + + +Time Awake Since Boot: 400000 seconds + +System Integrity Protection: enabled + +Crashed Thread: 0 Dispatch queue: com.apple.main-thread + +Exception Type: EXC_BAD_ACCESS (SIGSEGV) +Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000 +Exception Note: EXC_CORPSE_NOTIFY + +Termination Signal: Segmentation fault: 11 +Termination Reason: Namespace SIGNAL, Code 0xb +Terminating Process: exc handler [21606] + +Thread 0 Crashed:: Dispatch queue: com.apple.main-thread +0 a.out @foo@ foo + 16 (test.c:3) +1 a.out @bar@ bar + 9 (test.c:6) +2 a.out @main@ main + 20 (test.c:8) +3 libdyld.dylib 0x0000000100000000 start + 1 + +Thread 0 crashed with X86 Thread State (64-bit): + rax: 0x0000000000000000 rbx: 0x0000000000000000 rcx: 0x00007ffee42d81d0 rdx: 0x00007ffee42d8080 + rdi: 0x0000000000000001 rsi: 0x00007ffee42d8070 rbp: 0x00007ffee42d8020 rsp: 0x00007ffee42d8020 + r8: 0x0000000000000000 r9: 0x0000000000000000 r10: 0x0000000000000000 r11: 0x0000000000000000 + r12: 0x0000000000000000 r13: 0x0000000000000000 r14: 0x0000000000000000 r15: 0x0000000000000000 + rip: 0x000000010b92af70 rfl: 0x0000000000010202 cr2: 0x0000000000000000 + +Logical CPU: 2 +Error Code: 0x00000006 (no mapping for user data write) +Trap Number: 14 + + +Binary Images: + 0x100000000 - 0x200000000 +a.out (0) <@UUID@> @EXEC@ diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/a.out.ips b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/a.out.ips new file mode 100644 index 0000000..703acce --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/a.out.ips @@ -0,0 +1,96 @@ +{"app_name":"a.out","timestamp":"2020-11-11 16:12:18.00 -0800","app_version":"","slice_uuid":"9b76648c-9b4e-33a9-a97e-10856e911631","build_version":"","platform":1,"share_with_app_devs":1,"is_first_party":1,"bug_type":"309","os_version":"macOS 11.0.1","incident_id":"598C4706-28B0-4D96-A2F9-AE6973BEC635","name":"a.out"} +{ + "uptime" : 180, + "procLaunch" : "2020-11-11 16:12:12.4375 -0800", + "procRole" : "Unspecified", + "exception" : { + "type" : "EXC_BAD_ACCESS", + "signal" : "SIGSEGV", + "subtype" : "KERN_INVALID_ADDRESS at 0x00000000" + }, + "userID" : 501, + "modelCode" : "iMacPro1,1", + "coalitionID" : 471, + "osVersion" : { + "train" : "macOS 11.0.1", + "build" : "", + "releaseType" : "" + }, + "captureTime" : "2020-11-11 16:12:12.6267 -0800", + "incident" : "598C4706-28B0-4D96-A2F9-AE6973BEC635", + "pid" : 2187, + "cpuType" : "X86-64", + "procName" : "a.out", + "procPath" : "\/private\/tmp\/a.out", + "parentProc" : "fish", + "parentPid" : 1651, + "coalitionName" : "io.alacritty", + "crashReporterKey" : "DCEF35CB-68D5-F524-FF13-060901F52EA8", + "responsiblePid" : 428, + "responsibleProc" : "alacritty", + "bridgeVersion" : {"build":"","train":""}, + "sip" : "enabled", + "is_corpse" : 1, + "termination" : {"reason":"Namespace SIGNAL, Code 0xb","signal":"Segmentation fault: 11","byProc":"exc handler","code":11,"namespace":"SIGNAL","byPid":2187,"flags":0}, + "asi" : ["dyld2 mode"], + "extMods" : {"caller":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"system":{"thread_create":0,"thread_set_state":0,"task_for_pid":2067},"targeted":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"warnings":0}, + "threads" : [{"triggered":true,"id":22172,"queue":"com.apple.main-thread","frames":[[0,16240],[0,16265],[0,16292],[1,87601]]}], + "threadState" : { + "r13" : 0, + "rax" : 0, + "rflags" : 66054, + "cpu" : 6, + "rsi" : 140732908048520, + "r14" : 0, + "trap_description" : "(no mapping for user data write)", + "r8" : 0, + "cr2" : 0, + "rdx" : 140732908048536, + "r10" : 0, + "r9" : 0, + "r15" : 0, + "rbx" : 0, + "trap" : 14, + "err" : 6, + "r11" : 0, + "rip" : 4307689328, + "rbp" : 140732908048432, + "rsp" : 140732908048432, + "r12" : 0, + "rcx" : 140732908048880, + "flavor" : "x86_THREAD_STATE", + "rdi" : 1 +}, + "usedImages" : [ + [ + "@UUID@", + 0, + "P" + ], + [ + "6a1f593e-3705-314d-bb40-e7f9d502bf81", + 140733737017344, + "P" + ] +], + "legacyInfo" : { + "imageExtraInfo" : [ + { + "size" : 16384, + "arch" : "x86_64", + "path" : "@EXEC@", + "name" : "@NAME@" + }, + { + "size" : 241664, + "arch" : "x86_64", + "path" : "\/usr\/lib\/system\/libdyld.dylib", + "name" : "libdyld.dylib" + } + ], + "threadTriggered" : { + "index" : 0, + "queue" : "com.apple.main-thread" + } +} +} diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/test.c b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/test.c new file mode 100644 index 0000000..3f0819b --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/test.c @@ -0,0 +1,8 @@ +void foo() { + int *i = 0; + *i = 1; +} + +void bar() { foo(); } + +int main(int argc, char **argv) { bar(); } diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/crashlog.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/crashlog.test deleted file mode 100644 index 6ac9392..0000000 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/crashlog.test +++ /dev/null @@ -1,135 +0,0 @@ -# -*- python -*- -# DEBUG: cd %S/../../../../../examples/python && cat %s | %lldb && false -# RUN: cd %S/../../../../../examples/python && cat %s | %lldb | FileCheck %s -# CHECK-LABEL: {{S}}KIP BEYOND CHECKS -script -import crashlog -crash_log_parser = crashlog.CrashLogParser -crash_log = crashlog.CrashLog -images = [ -"0x10b60b000 - 0x10f707fff com.apple.LLDB.framework (1.1000.11.38.2 - 1000.11.38.2) <96E36F5C-1A83-39A1-8713-5FDD9701C3F1> /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/LLDB", -# CHECK: 0x10b60b000 -# CHECK: 0x10f707fff -# CHECK: com.apple.LLDB.framework -# CHECK: 96E36F5C-1A83-39A1-8713-5FDD9701C3F1 -# CHECK: /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/LLDB - -"0x104591000 - 0x1055cfff7 +llvm-dwarfdump (0) /Users/USER 1/Documents/*/llvm-dwarfdump", -# CHECK: 0x104591000 -# CHECK: 0x1055cfff7 -# CHECK: llvm-dwarfdump -# CHECK: (0) -# CHECK: B104CFA1-046A-36A6-8EB4-07DDD7CC2DF3 -# CHECK: /Users/USER 1/Documents/*/llvm-dwarfdump - -"0x7fff63f20000 - 0x7fff63f77ff7 libc++.1.dylib (400.9.4) /usr/lib/libc++.1.dylib", -# CHECK: 0x7fff63f20000 -# CHECK: 0x7fff63f77ff7 -# CHECK: libc++.1.dylib -# CHECK: (400.9.4) -# CHECK: D4AB366F-48A9-3C7D-91BD-41198F69DD57 -# CHECK: /usr/lib/libc++.1.dylib - -"0x1111111 - 0x22222 +MyApp Pro arm64 <01234> /tmp/MyApp Pro.app/MyApp Pro", -# CHECK: 0x1111111 -# CHECK: 0x22222 -# CHECK: MyApp Pro -# CHECK: arm64 -# CHECK: 01234 -# CHECK: /tmp/MyApp Pro.app/MyApp Pro - -"0x1111111 - 0x22222 +MyApp Pro (0) <01234> /tmp/MyApp Pro.app/MyApp Pro", -# CHECK: 0x1111111 -# CHECK: 0x22222 -# CHECK: MyApp Pro -# CHECK: (0) -# CHECK: 01234 -# CHECK: /tmp/MyApp Pro.app/MyApp Pro - -"0x1111111 - 0x2222222 MyFramework Plus.dylib (1.11 - MyFramework 1.11) <01234> /tmp/MyFramework Plus.dylib", -# CHECK: 0x1111111 -# CHECK: 0x2222222 -# CHECK: MyFramework Plus.dylib -# CHECK: ({{.*}} -# CHECK: 1.11 - MyFramework 1.11 -# CHECK: <{{.*}} -# CHECK: 01234 -# CHECK: /tmp/MyFramework Plus.dylib - -"0x1111111 - 0x2222222 MyFramework-dev.dylib (1.0.0svn - 1.0.0svn) <01234> /MyFramework-dev.dylib", -# CHECK: 0x1111111 -# CHECK: 0x2222222 -# CHECK: MyFramework-dev.dylib -# CHECK: ({{.*}} -# CHECK: 1.0.0svn - 1.0.0svn -# CHECK: <{{.*}} -# CHECK: 01234 -# CHECK: /MyFramework-dev.dylib - -"0x7fff63f20000 - 0x7fff63f77ff7 libc++.1.dylib (400.9.4) /usr/lib/libc++.1.dylib", -# CHECK: 0x7fff63f20000 -# CHECK: 0x7fff63f77ff7 -# CHECK: libc++.1.dylib -# CHECK: ({{.*}} -# CHECK: 400.9.4 -# CHECK: None -# CHECK: None -# CHECK: /usr/lib/libc++.1.dylib - -"0x1047b8000 - 0x10481ffff dyld arm64e /usr/lib/dyld" -# CHECK: 0x1047b8000 -# CHECK: 0x10481ffff -# CHECK: dyld -# CHECK: {{.*}} -# CHECK: arm64e -# CHECK: <{{.*}} -# CHECK: cfa789d10da63f9a8996daf84ed9d04f -# CHECK: /usr/lib/dyld -] -# CHECK-LABEL: FRAMES -frames = [ -"0 libsystem_kernel.dylib 0x00007fff684b78a6 read + 10", -# CHECK: 0 -# CHECK: libsystem_kernel.dylib -# CHECK: 0x00007fff684b78a6 -# CHECK: read + 10 -"1 com.apple.LLDB.framework 0x000000010f7954af lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*) + 105", -# CHECK: 1 -# CHECK: com.apple.LLDB.framework -# CHECK: 0x000000010f7954af -# CHECK: lldb_private{{.*}} + 105 -"2 MyApp Pro arm64 0x000000019b0db3a8 foo + 72", -# CHECK: 2 -# CHECK: MyApp Pro -# CHECK: a -# CHECK: arm64 -# CHECK: a -# CHECK: 0x000000019b0db3a8 -# CHECK: foo + 72 -"3 He 0x1 0x000000019b0db3a8 foo + 72" -# CHECK: 3 -# CHECK: He 0x1 -# CHECK: 0x000000019b0db3a8 -# CHECK: foo + 72 -] - - -# Avoid matching the text inside the input. -print("SKIP BEYOND CHECKS") -for image in images: - print('"%s"'%image) - print("--------------") - match = crash_log_parser.image_regex_uuid.search(image) - for group in match.groups(): - print(group) - -print("FRAMES") -for frame in frames: - print('"%s"'%frame) - print("--------------") - match = crash_log_parser.frame_regex.search(frame) - for group in match.groups(): - print(group) - -exit() -quit diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/json.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/json.test new file mode 100644 index 0000000..c92be0b --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/json.test @@ -0,0 +1,10 @@ +# RUN: %clang_host -g %S/Inputs/test.c -o %t.out +# RUN: cp %S/Inputs/a.out.ips %t.crash +# RUN: python %S/patch-crashlog.py %t.out %t.crash +# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog %t.crash' 2>&1 | FileCheck %s + +# CHECK: Thread[0] EXC_BAD_ACCESS (SIGSEGV) (KERN_INVALID_ADDRESS at 0x00000000) +# CHECK: [ 0] {{.*}}out`foo + 16 at test.c +# CHECK: [ 1] {{.*}}out`bar + 8 at test.c +# CHECK: [ 2] {{.*}}out`main + 19 at test.c +# CHECK: [ 3] {{.*}}start diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/parser_json.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/parser_json.test new file mode 100644 index 0000000..50da725 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/parser_json.test @@ -0,0 +1,45 @@ +# -*- python -*- +# RUN: cd %S/../../../../../examples/python && cat %s | %lldb 2>&1 > %t.out +# RUN: cat %t.out | FileCheck %S/Inputs/Assertion.check +script +import crashlog +import json + +parser = crashlog.JSONCrashLogParser("", "", False) + +process_info_json = json.loads('{"pid" : 287, "procName" : "mediaserverd", "procPath" : "\/usr\/sbin\/mediaserverd"}') +parser.parse_process_info(process_info_json) + +assert parser.crashlog.process_id == 287 +assert parser.crashlog.process_identifier == "mediaserverd" +assert parser.crashlog.process_path == "/usr/sbin/mediaserverd" + +crash_reason_json = json.loads('{"type" : "EXC_BAD_ACCESS", "signal" : "SIGSEGV", "subtype" : "KERN_INVALID_ADDRESS"}') +assert parser.parse_crash_reason(crash_reason_json) == "EXC_BAD_ACCESS (SIGSEGV) (KERN_INVALID_ADDRESS)" + +crash_reason_json = json.loads('{"type" : "EXC_BAD_ACCESS", "signal" : "SIGSEGV"}') +assert parser.parse_crash_reason(crash_reason_json) == "EXC_BAD_ACCESS (SIGSEGV)" + +crash_reason_json = json.loads('{"type" : "EXC_BAD_ACCESS", "signal" : "SIGSEGV", "codes" : "0x0000000000000000, 0x0000000000000000"}') +assert parser.parse_crash_reason(crash_reason_json) == "EXC_BAD_ACCESS (SIGSEGV) (0x0000000000000000, 0x0000000000000000)" + +thread_state_json = json.loads('{"x":[268451845,117442566],"lr":7309751904,"cpsr":1073741824,"fp":6093236784,"sp":6093236704,"esr":1442840704,"pc":7309755088}') +registers = parser.parse_thread_registers(thread_state_json) +assert registers['x0'] == 268451845 +assert registers['x1'] == 117442566 +assert registers['lr'] == 7309751904 +assert registers['cpsr'] ==1073741824 +assert registers['fp'] == 6093236784 +assert registers['sp'] == 6093236704 +assert registers['esr'] == 1442840704 +assert registers['pc'] == 7309755088 + +parser.data = json.loads('{"usedImages":[["f4d85377-f215-3da3-921e-3fe870e622e9",7309737984,"P"]],"legacyInfo":{"imageExtraInfo":[{"size":204800,"arch":"arm64e","path":"/usr/lib/system/libsystem_kernel.dylib","name":"libsystem_kernel.dylib"}]}}') +thread_json = json.loads('[{"triggered":true,"id":3835,"queue":"com.apple.bwgraph.devicevendor","frames":[[0,101472],[0,408892]]}]') +parser.parse_threads(thread_json) +assert len(parser.crashlog.threads) == 1 +assert parser.crashlog.threads[0].queue == "com.apple.bwgraph.devicevendor" +assert len(parser.crashlog.threads[0].frames) == 2 +assert parser.crashlog.threads[0].frames[0].pc == 7309839456 +assert parser.crashlog.threads[0].frames[0].description == 101472 +exit() diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/parser_text.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/parser_text.test new file mode 100644 index 0000000..7251d85 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/parser_text.test @@ -0,0 +1,135 @@ +# -*- python -*- +# DEBUG: cd %S/../../../../../examples/python && cat %s | %lldb && false +# RUN: cd %S/../../../../../examples/python && cat %s | %lldb | FileCheck %s +# CHECK-LABEL: {{S}}KIP BEYOND CHECKS +script +import crashlog +crash_log_parser = crashlog.TextCrashLogParser +crash_log = crashlog.CrashLog +images = [ +"0x10b60b000 - 0x10f707fff com.apple.LLDB.framework (1.1000.11.38.2 - 1000.11.38.2) <96E36F5C-1A83-39A1-8713-5FDD9701C3F1> /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/LLDB", +# CHECK: 0x10b60b000 +# CHECK: 0x10f707fff +# CHECK: com.apple.LLDB.framework +# CHECK: 96E36F5C-1A83-39A1-8713-5FDD9701C3F1 +# CHECK: /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/LLDB + +"0x104591000 - 0x1055cfff7 +llvm-dwarfdump (0) /Users/USER 1/Documents/*/llvm-dwarfdump", +# CHECK: 0x104591000 +# CHECK: 0x1055cfff7 +# CHECK: llvm-dwarfdump +# CHECK: (0) +# CHECK: B104CFA1-046A-36A6-8EB4-07DDD7CC2DF3 +# CHECK: /Users/USER 1/Documents/*/llvm-dwarfdump + +"0x7fff63f20000 - 0x7fff63f77ff7 libc++.1.dylib (400.9.4) /usr/lib/libc++.1.dylib", +# CHECK: 0x7fff63f20000 +# CHECK: 0x7fff63f77ff7 +# CHECK: libc++.1.dylib +# CHECK: (400.9.4) +# CHECK: D4AB366F-48A9-3C7D-91BD-41198F69DD57 +# CHECK: /usr/lib/libc++.1.dylib + +"0x1111111 - 0x22222 +MyApp Pro arm64 <01234> /tmp/MyApp Pro.app/MyApp Pro", +# CHECK: 0x1111111 +# CHECK: 0x22222 +# CHECK: MyApp Pro +# CHECK: arm64 +# CHECK: 01234 +# CHECK: /tmp/MyApp Pro.app/MyApp Pro + +"0x1111111 - 0x22222 +MyApp Pro (0) <01234> /tmp/MyApp Pro.app/MyApp Pro", +# CHECK: 0x1111111 +# CHECK: 0x22222 +# CHECK: MyApp Pro +# CHECK: (0) +# CHECK: 01234 +# CHECK: /tmp/MyApp Pro.app/MyApp Pro + +"0x1111111 - 0x2222222 MyFramework Plus.dylib (1.11 - MyFramework 1.11) <01234> /tmp/MyFramework Plus.dylib", +# CHECK: 0x1111111 +# CHECK: 0x2222222 +# CHECK: MyFramework Plus.dylib +# CHECK: ({{.*}} +# CHECK: 1.11 - MyFramework 1.11 +# CHECK: <{{.*}} +# CHECK: 01234 +# CHECK: /tmp/MyFramework Plus.dylib + +"0x1111111 - 0x2222222 MyFramework-dev.dylib (1.0.0svn - 1.0.0svn) <01234> /MyFramework-dev.dylib", +# CHECK: 0x1111111 +# CHECK: 0x2222222 +# CHECK: MyFramework-dev.dylib +# CHECK: ({{.*}} +# CHECK: 1.0.0svn - 1.0.0svn +# CHECK: <{{.*}} +# CHECK: 01234 +# CHECK: /MyFramework-dev.dylib + +"0x7fff63f20000 - 0x7fff63f77ff7 libc++.1.dylib (400.9.4) /usr/lib/libc++.1.dylib", +# CHECK: 0x7fff63f20000 +# CHECK: 0x7fff63f77ff7 +# CHECK: libc++.1.dylib +# CHECK: ({{.*}} +# CHECK: 400.9.4 +# CHECK: None +# CHECK: None +# CHECK: /usr/lib/libc++.1.dylib + +"0x1047b8000 - 0x10481ffff dyld arm64e /usr/lib/dyld" +# CHECK: 0x1047b8000 +# CHECK: 0x10481ffff +# CHECK: dyld +# CHECK: {{.*}} +# CHECK: arm64e +# CHECK: <{{.*}} +# CHECK: cfa789d10da63f9a8996daf84ed9d04f +# CHECK: /usr/lib/dyld +] +# CHECK-LABEL: FRAMES +frames = [ +"0 libsystem_kernel.dylib 0x00007fff684b78a6 read + 10", +# CHECK: 0 +# CHECK: libsystem_kernel.dylib +# CHECK: 0x00007fff684b78a6 +# CHECK: read + 10 +"1 com.apple.LLDB.framework 0x000000010f7954af lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*) + 105", +# CHECK: 1 +# CHECK: com.apple.LLDB.framework +# CHECK: 0x000000010f7954af +# CHECK: lldb_private{{.*}} + 105 +"2 MyApp Pro arm64 0x000000019b0db3a8 foo + 72", +# CHECK: 2 +# CHECK: MyApp Pro +# CHECK: a +# CHECK: arm64 +# CHECK: a +# CHECK: 0x000000019b0db3a8 +# CHECK: foo + 72 +"3 He 0x1 0x000000019b0db3a8 foo + 72" +# CHECK: 3 +# CHECK: He 0x1 +# CHECK: 0x000000019b0db3a8 +# CHECK: foo + 72 +] + + +# Avoid matching the text inside the input. +print("SKIP BEYOND CHECKS") +for image in images: + print('"%s"'%image) + print("--------------") + match = crash_log_parser.image_regex_uuid.search(image) + for group in match.groups(): + print(group) + +print("FRAMES") +for frame in frames: + print('"%s"'%frame) + print("--------------") + match = crash_log_parser.frame_regex.search(frame) + for group in match.groups(): + print(group) + +exit() +quit diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/patch-crashlog.py b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/patch-crashlog.py new file mode 100644 index 0000000..ba69547 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/patch-crashlog.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +import json +import os +import re +import subprocess +import sys + + +class CrashLogPatcher: + + SYMBOL_REGEX = re.compile(r'^([0-9a-fA-F]+) T _(.*)$') + UUID_REGEX = re.compile(r'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*') + + def __init__(self, data, binary, offsets): + self.data = data + self.binary = binary + self.offsets = offsets + + def patch_executable(self): + self.data = self.data.replace("@EXEC@", self.binary) + self.data = self.data.replace("@NAME@", os.path.basename(self.binary)) + + def patch_uuid(self): + output = subprocess.check_output(['dwarfdump', '--uuid', self.binary]) + m = self.UUID_REGEX.match(output) + if m: + self.data = self.data.replace("@UUID@", m.group(1)) + + def patch_addresses(self): + if not self.offsets: + return + output = subprocess.check_output(['nm', self.binary]) + for line in output.splitlines(): + m = self.SYMBOL_REGEX.match(line) + if m: + address = m.group(1) + symbol = m.group(2) + if symbol in self.offsets: + patch_addr = int(m.group(1), 16) + int( + self.offsets[symbol]) + self.data = self.data.replace("@{}@".format(symbol), + str(hex(patch_addr))) + + +if __name__ == '__main__': + binary = sys.argv[1] + crashlog = sys.argv[2] + offsets = json.loads(sys.argv[3]) if len(sys.argv) > 3 else None + + with open(crashlog, 'r') as file: + data = file.read() + + p = CrashLogPatcher(data, binary, offsets) + p.patch_executable() + p.patch_uuid() + p.patch_addresses() + + with open(crashlog, 'w') as file: + file.write(p.data) diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/text.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/text.test new file mode 100644 index 0000000..1375784 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/text.test @@ -0,0 +1,10 @@ +# RUN: %clang_host -g %S/Inputs/test.c -o %t.out +# RUN: cp %S/Inputs/a.out.crash %t.crash +# RUN: python %S/patch-crashlog.py %t.out %t.crash '{"main":20, "bar":9, "foo":16}' +# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog %t.crash' 2>&1 | FileCheck %s + +# CHECK: Thread[0] EXC_BAD_ACCESS (SIGSEGV) (KERN_INVALID_ADDRESS at 0x0000000000000000) +# CHECK: [ 0] {{.*}}out`foo + 16 at test.c +# CHECK: [ 1] {{.*}}out`bar + 8 at test.c +# CHECK: [ 2] {{.*}}out`main + 19 at test.c +# CHECK: [ 3] {{.*}}start + 1 -- cgit v1.1