Skip to content

[lldb/crashlog] Load inlined symbol into crashlog scripted process #7010

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
277 changes: 201 additions & 76 deletions lldb/examples/python/crashlog.py

Large diffs are not rendered by default.

31 changes: 19 additions & 12 deletions lldb/examples/python/scripted_process/crashlog_scripted_process.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os,json,struct,signal,uuid
import os, json, struct, signal, uuid, tempfile

from typing import Any, Dict

Expand All @@ -11,7 +11,13 @@
class CrashLogScriptedProcess(ScriptedProcess):
def set_crashlog(self, crashlog):
self.crashlog = crashlog
self.pid = self.crashlog.process_id
if self.crashlog.process_id:
if type(self.crashlog.process_id) is int:
self.pid = self.crashlog.process_id
elif type(self.crashlog.process_id) is str:
self.pid = int(self.crashlog.process_id, 0)
else:
self.pid = super().get_process_id()
self.addr_mask = self.crashlog.addr_mask
self.crashed_thread_idx = self.crashlog.crashed_thread_idx
self.loaded_images = []
Expand All @@ -32,16 +38,17 @@ def set_crashlog(self, crashlog):
for image in self.crashlog.find_images_with_identifier(ident):
image.resolve = True

for image in self.crashlog.images:
if image not in self.loaded_images:
if image.uuid == uuid.UUID(int=0):
continue
err = image.add_module(self.target)
if err:
# Append to SBCommandReturnObject
print(err)
else:
self.loaded_images.append(image)
with tempfile.TemporaryDirectory() as obj_dir:
for image in self.crashlog.images:
if image not in self.loaded_images:
if image.uuid == uuid.UUID(int=0):
continue
err = image.add_module(self.target, obj_dir)
if err:
# Append to SBCommandReturnObject
print(err)
else:
self.loaded_images.append(image)

for thread in self.crashlog.threads:
if hasattr(thread, 'app_specific_backtrace') and thread.app_specific_backtrace:
Expand Down
28 changes: 16 additions & 12 deletions lldb/examples/python/symbolication.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,8 @@ def load_module(self, target):
else:
return "error: no section infos"

def add_module(self, target):
"""Add the Image described in this object to "target" and load the sections if "load" is True."""
def add_module(self, target, obj_dir=None):
'''Add the Image described in this object to "target" and load the sections if "load" is True.'''
if target:
# Try and find using UUID only first so that paths need not match
# up
Expand All @@ -411,7 +411,7 @@ def add_module(self, target):
)
if not self.module and self.section_infos:
name = os.path.basename(self.path)
with tempfile.NamedTemporaryFile(suffix="." + name) as tf:
if obj_dir and os.path.isdir(obj_dir):
data = {
"triple": target.triple,
"uuid": uuid_str,
Expand All @@ -420,16 +420,20 @@ def add_module(self, target):
"symbols": list(),
}
for section in self.section_infos:
data["sections"].append(
{
"name": section.name,
"size": section.end_addr - section.start_addr,
}
)
data["symbols"] = list(self.symbols.values())
with open(tf.name, "w") as f:
data['sections'].append({
'name' : section.name,
'size': section.end_addr - section.start_addr
})
data['symbols'] = list(self.symbols.values())
obj_file = os.path.join(obj_dir, name)
with open(obj_file, "w") as f:
f.write(json.dumps(data, indent=4))
self.module = target.AddModule(tf.name, None, uuid_str)
self.module = target.AddModule(obj_file, None, uuid_str)
if self.module:
# If we were able to add the module with inlined
# symbols, we should mark it as available so load_module
# does not exit early.
self.unavailable = False
if not self.module and not self.unavailable:
return 'error: unable to get module for (%s) "%s"' % (
self.arch,
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Target/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2669,7 +2669,7 @@ Status Process::LaunchPrivate(ProcessLaunchInfo &launch_info, StateType &state,

FileSpec exe_spec_to_use;
if (!exe_module) {
if (!launch_info.GetExecutableFile()) {
if (!launch_info.GetExecutableFile() && !launch_info.IsScriptedProcess()) {
error.SetErrorString("executable module does not exist");
return error;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
Process: multithread-test [22511]
Path: /Users/USER/*/multithread-test
Identifier: multithread-test
Version: ???
Code Type: ARM-64 (Native)
Parent Process: zsh [59146]
Responsible: Terminal [1640]
User ID: 501

Date/Time: 2022-07-28 11:10:19.4194 -0700
OS Version: macOS 13.0 ()
Report Version: 12
Anonymous UUID: CDC11418-EDBF-2A49-0D83-8B441A5004B0

Sleep/Wake UUID: 7B2A0D73-8966-4B8D-98E9-CC6EC1B44967

Time Awake Since Boot: 110000 seconds
Time Since Wake: 214 seconds

System Integrity Protection: disabled

Crashed Thread: 2

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Codes: 0x0000000000000001, 0x0000000000000000

Termination Reason: Namespace SIGNAL, Code 11 Segmentation fault: 11
Terminating Process: exc handler [22511]

VM Region Info: 0 is not in any region. Bytes before following region: 4310450176
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
__TEXT 100ec4000-100ec8000 [ 16K] r-x/r-x SM=COW ...tithread-test

Thread 0:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x19cc40b84 __ulock_wait + 8
1 libsystem_pthread.dylib 0x19cc80394 _pthread_join + 444
2 libc++.1.dylib 0x19cbd8274 std::__1::thread::join() + 36
3 multithread-test 0x100ec5b3c main + 160 (multithread-test.cpp:31)
4 dyld 0x2230f8da8 start + 2376

Thread 1:
0 libsystem_kernel.dylib 0x19cc42c9c __write_nocancel + 8
1 libsystem_c.dylib 0x19cb719a8 __swrite + 24
2 libsystem_c.dylib 0x19cb50ac8 _swrite + 108
3 libsystem_c.dylib 0x19cb4ec2c __sflush + 232
4 libsystem_c.dylib 0x19cb42f20 __sfvwrite + 792
5 libsystem_c.dylib 0x19cb61f64 fwrite + 152
6 libc++.1.dylib 0x19cbed084 std::__1::__stdoutbuf<char>::overflow(int) + 96
7 libc++.1.dylib 0x19cbe06b4 std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >::operator=(char) + 96
8 libc++.1.dylib 0x19cbe0798 std::__1::basic_ostream<char, std::__1::char_traits<char> >::put(char) + 200
9 multithread-test 0x100ec5a54 std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) + 64 (ostream:994)
10 multithread-test 0x100ec5a08 std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >& (*)(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)) + 32 (ostream:189)
11 multithread-test 0x100ec5958 call_and_wait(int&) + 48 (multithread-test.cpp:14)
12 multithread-test 0x100ec7684 decltype(static_cast<void (*>(fp)(static_cast<std::__1::reference_wrapper<int>>(fp0))) std::__1::__invoke<void (*)(int&), std::__1::reference_wrapper<int> >(void (*&&)(int&), std::__1::reference_wrapper<int>&&) + 48 (type_traits:3918)
13 multithread-test 0x100ec7608 void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(int&), std::__1::reference_wrapper<int>, 2ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(int&), std::__1::reference_wrapper<int> >&, std::__1::__tuple_indices<2ul>) + 56 (thread:287)
14 multithread-test 0x100ec6d58 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(int&), std::__1::reference_wrapper<int> > >(void*) + 84 (thread:298)
15 libsystem_pthread.dylib 0x19cc7e06c _pthread_start + 148
16 libsystem_pthread.dylib 0x19cc78e2c thread_start + 8

Thread 2 Crashed:
0 multithread-test 0x100ec58f4 bar(int) + 20 (multithread-test.cpp:7)
1 multithread-test 0x100ec591c foo(int) + 24 (multithread-test.cpp:11)
2 multithread-test 0x100ec5a88 compute_pow(int&) + 28 (multithread-test.cpp:20)
3 multithread-test 0x100ec7684 decltype(static_cast<void (*>(fp)(static_cast<std::__1::reference_wrapper<int>>(fp0))) std::__1::__invoke<void (*)(int&), std::__1::reference_wrapper<int> >(void (*&&)(int&), std::__1::reference_wrapper<int>&&) + 48 (type_traits:3918)
4 multithread-test 0x100ec7608 void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(int&), std::__1::reference_wrapper<int>, 2ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(int&), std::__1::reference_wrapper<int> >&, std::__1::__tuple_indices<2ul>) + 56 (thread:287)
5 multithread-test 0x100ec6d58 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(int&), std::__1::reference_wrapper<int> > >(void*) + 84 (thread:298)
6 libsystem_pthread.dylib 0x19cc7e06c _pthread_start + 148
7 libsystem_pthread.dylib 0x19cc78e2c thread_start + 8


Thread 2 crashed with ARM Thread State (64-bit):
x0: 0x000000000000002a x1: 0x0000600001d291b0 x2: 0x000000019cbbf000 x3: 0x0000000000000000
x4: 0x00000000000030a0 x5: 0x00000000190008ff x6: 0x0000000000000000 x7: 0x0000000000000000
x8: 0x0000000000000001 x9: 0x0000000000000000 x10: 0xfffffffe634277cf x11: 0x0000010000000102
x12: 0x0000010000000102 x13: 0x0000010000000100 x14: 0x0000010000000000 x15: 0x0000000000000001
x16: 0x000000019cc78ea8 x17: 0x00000001fd0a7698 x18: 0x0000000000000000 x19: 0x000000016f04f000
x20: 0x0000000000000000 x21: 0x0000000000000000 x22: 0x0000000000000000 x23: 0x0000000000000000
x24: 0x0000000000000000 x25: 0x0000000000000000 x26: 0x0000000000000000 x27: 0x0000000000000000
x28: 0x0000000000000000 fp: 0x000000016f04ef00 lr: 0x0000000100ec591c
sp: 0x000000016f04eee0 pc: 0x0000000100ec58f4 cpsr: 0x80001000
far: 0x0000000000000000 esr: 0x92000046 (Data Abort) byte write Translation fault

Binary Images:
0x19cc3e000 - 0x19cc76feb libsystem_kernel.dylib (*) <b8898079-5424-3e89-92b0-33022c3be1bb> /usr/lib/system/libsystem_kernel.dylib
0x19cc77000 - 0x19cc83ffb libsystem_pthread.dylib (*) <ffd36328-45f2-31c5-9240-9f76f26a1a2b> /usr/lib/system/libsystem_pthread.dylib
0x19cbbf000 - 0x19cc25ff3 libc++.1.dylib (*) <da619b87-2723-3731-919a-bb3467eab9e1> /usr/lib/libc++.1.dylib
0x100ec4000 - 0x100ec7fff multithread-test (*) <ab9b94f9-6cdf-3b8e-b140-fae3cb13d327> /Users/USER/*/multithread-test
0x2230f3000 - 0x22317be4b dyld (*) <e81312a0-f3e5-3c60-8c25-4599b62b8b4a> /usr/lib/dyld
0x19cb3e000 - 0x19cbbefff libsystem_c.dylib (*) <b8f1c3ed-9048-34a6-8070-6c18d4ade541> /usr/lib/system/libsystem_c.dylib
0x0 - 0xffffffffffffffff ??? (*) <00000000-0000-0000-0000-000000000000> ???
0x3039 - 0x3420 bogus.dylib (*) <11111111-2222-3333-4444-555555555555> /usr/lib/system/bogus.dylib

External Modification Summary:
Calls made by other processes targeting this process:
task_for_pid: 0
thread_create: 0
thread_set_state: 0
Calls made by this process:
task_for_pid: 0
thread_create: 0
thread_set_state: 0
Calls made by all processes on this machine:
task_for_pid: 23
thread_create: 0
thread_set_state: 812

VM Region Summary:
ReadOnly portion of Libraries: Total=762.9M resident=0K(0%) swapped_out_or_unallocated=762.9M(100%)
Writable regions: Total=538.2M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=538.2M(100%)

VIRTUAL REGION
REGION TYPE SIZE COUNT (non-coalesced)
=========== ======= =======
Kernel Alloc Once 32K 1
MALLOC 145.2M 12
MALLOC guard page 96K 5
MALLOC_NANO (reserved) 384.0M 1 reserved VM address space (unallocated)
STACK GUARD 56.0M 3
Stack 9264K 3
__AUTH 46K 11
__AUTH_CONST 70K 38
__DATA 169K 36
__DATA_CONST 187K 40
__DATA_DIRTY 78K 22
__LINKEDIT 758.0M 2
__OBJC_CONST 11K 5
__OBJC_RO 64.7M 1
__OBJC_RW 1971K 1
__TEXT 5076K 42
dyld private memory 256K 1
shared memory 64K 3
=========== ======= =======
TOTAL 1.4G 227
TOTAL, minus reserved VM space 1.0G 227



Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# REQUIRES: python, native && target-aarch64 && system-darwin

# RUN: mkdir -p %t.dir
# RUN: yaml2obj %S/Inputs/interactive_crashlog/multithread-test.yaml > %t.dir/multithread-test
# RUN: %lldb -o 'command script import lldb.macosx.crashlog' \
# RUN: -o 'crashlog -a -i -t %t.dir/multithread-test %S/Inputs/interactive_crashlog/multithread-test.crash' \
# RUN: -o "thread list" -o "bt all" 2>&1 | FileCheck %s

# CHECK: "crashlog" {{.*}} commands have been installed, use the "--help" options on these commands

# CHECK: (lldb) process status
# CHECK-NEXT: Process 22511 stopped
# CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
# CHECK-NEXT: frame #0: 0x0000000100ec58f4 multithread-test`bar

# CHECK: (lldb) thread backtrace
# CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial]
# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial]
# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial]

# CHECK: (lldb) thread list
# CHECK-NEXT: Process 22511 stopped
# CHECK-NEXT: thread #1: tid = 0x0000, 0x000000019cc40b84{{.*}}
# CHECK-NEXT: thread #2: tid = 0x0001, 0x000000019cc42c9c{{.*}}
# CHECK-NEXT: * thread #3: tid = 0x0002, 0x0000000100ec58f4 multithread-test`bar{{.*}}, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)

# CHECK: (lldb) bt all
# CHECK: thread #1
# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial]
# CHECK-NEXT: thread #2
# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial]
# CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial]
# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial]
# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial]