lldb reproducers - llvm

51
Jonas Devlieghere, Apple LLVM Developers’ Meeting, Brussels, Belgium, April 2019 LLDB Reproducers

Upload: others

Post on 04-Apr-2022

17 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: lldb reproducers - LLVM

Jonas Devlieghere, Apple LLVM Developers’ Meeting, Brussels, Belgium, April 2019

• LLDB Reproducers •

Page 2: lldb reproducers - LLVM

"The debugger doesn't work"• — Somebody on the internet

Page 3: lldb reproducers - LLVM

LLDB Bugs

$ lldb ./a.out(lldb) target create "a.out"(lldb) b main.cpp:12...(lldb) run...(lldb) expr @import Foo(lldb) expr Barcannot materialize variable

Page 4: lldb reproducers - LLVM

LLDB Bug Reports

Bob Alice

"Hey this doesn't work..."! "

Page 5: lldb reproducers - LLVM

LLDB Bug Reports

"Can you attach the expr log?"! "Bob Alice

Page 6: lldb reproducers - LLVM

LLDB Bug Reports

Expression log! "Bob Alice

Page 7: lldb reproducers - LLVM

LLDB Bug Reports

"Can you attach the type log?"! "Bob Alice

Page 8: lldb reproducers - LLVM

LLDB Bug Reports

Type log! "Bob Alice

Page 9: lldb reproducers - LLVM

LLDB Bug Reports

! ""How do I reproduce?"

Bob Alice

Page 10: lldb reproducers - LLVM

LLDB Bug Reports

Steps to reproduce! "Bob Alice

Page 11: lldb reproducers - LLVM

LLDB Bug Reports

🤬 ""It doesn't reproduce..."

Bob Alice

Page 12: lldb reproducers - LLVM

Reproducers

• Automate the process • Everything needed to reproduce • Inspired by clang

Page 13: lldb reproducers - LLVM

Reproducers

"Hey this doesn't work..."! "📦

Bob Alice

Page 14: lldb reproducers - LLVM

Reproducers

$ lldb ./a.out --capture(lldb) target create "a.out"(lldb) b main.cpp:12...(lldb) run...(lldb) expr @import Foo(lldb) expr Barcannot materialize variable(lldb) reproducer generate

$ lldb --replay reproducer(lldb) target create "a.out"(lldb) b main.cpp:12...(lldb) run...(lldb) expr @import Foo(lldb) expr Barcannot materialize variable

! "📦

Page 15: lldb reproducers - LLVM

LLDB Reproducers

Page 16: lldb reproducers - LLVM

Reconstruct the debugger's state

• How we get there is more important than the final result • Capture data • Debug during replay

Page 17: lldb reproducers - LLVM

Information

User interaction

• Commands typed in the command line interpreter • Use of the public API

System interaction

• Data from the (file) system • Data from the process being debugged

Page 18: lldb reproducers - LLVM

Minimize impact

• Don't hide or introduce bugs • Reuse existing infrastructure • Transparency and abstraction

Page 19: lldb reproducers - LLVM

Components

Page 20: lldb reproducers - LLVM

User Interaction

•Command Line Interpreter •Public API (Scripting Bridge)

•Files •GDB Remote Protocol

Page 21: lldb reproducers - LLVM

Command Interpreter

$ lldb ./a.out (lldb) target create "a.out"(lldb) b main.cpp:12...(lldb) run...(lldb) expr @import Foo(lldb) expr Bar

Page 22: lldb reproducers - LLVM

User Interaction

•Command Line Interpreter •Public API (Scripting Bridge)

•Files •GDB Remote Protocol

Page 23: lldb reproducers - LLVM

Stable C++ API

• Accessible through Python wrappers • Used by IDEs such as Xcode, Eclipse, Visual Studio Code • How the command line driver is implemented

Page 24: lldb reproducers - LLVM

Python Example

import lldb

debugger = lldb.SBDebugger.Create()target = debugger.CreateTarget("/path/to/a.out")target.BreakpointCreateByName("foo")process = target.LaunchSimple(...)

Page 25: lldb reproducers - LLVM

Capture and replay API calls

• Capture the call and its argument values • Capture the return value

Page 26: lldb reproducers - LLVM

API Boundary

API boundary

Python SBDebugger SBTarget

CreateTarget()GetByteOrder()

Page 27: lldb reproducers - LLVM

API Boundary

API boundary

Python SBDebugger SBTarget

GetByteOrder()

CreateTarget()GetByteOrder()

Page 28: lldb reproducers - LLVM

Detecting API Boundaries

• RAII object consisting of two booleans • Static boolean toggles when crossing the API boundary • Non-static boolean tracks if boundary needs to be reset

Page 29: lldb reproducers - LLVM

Capturing Calls

• Toggles the API boundary • Captures the call and its arguments • More than 2000 instances

lldb::SBThread SBValue::GetThread() { LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBValue, GetThread); ... return LLDB_RECORD_RESULT(sb_thread);}

Page 30: lldb reproducers - LLVM

Capturing Calls

• Maps functions to unique identifier • Type safe • Synthesizes deserialization logic

LLDB_REGISTER_METHOD(void, SBDebugger, SetAsync, (bool));LLDB_REGISTER_METHOD(bool, SBDebugger, GetAsync, ());LLDB_REGISTER_METHOD(void, SBDebugger, SkipAppInitFiles, (bool));LLDB_REGISTER_METHOD(void, SBDebugger, SkipAppInitFiles,(bool));

Page 31: lldb reproducers - LLVM

lldb-instr

• Utility on top of libTooling • Traverses the clang AST • Inserts the record and register macros

Page 32: lldb reproducers - LLVM

Capturing Arguments

• Stream values to file • Look at underlying value for pointers and references

Page 33: lldb reproducers - LLVM

Capturing Objects

• Index based on object address • Table keeps mapping between object and index

SBDebugger debugger = SBDebugger::Create();SBTarget target = debugger.createTarget();SBLaunchInfo info("--arguments");target.Launch(info);

Object Index

debugger 1

target 2

info 3

Page 34: lldb reproducers - LLVM

ReplayPublic API

while (deserializer.HasData(1)) { unsigned id = deserializer.Deserialize<unsigned>(); GetReplayer(id)->operator()(deserializer);}

Page 35: lldb reproducers - LLVM

Components

•Command Line Interpreter •Public API (Scripting Bridge)

•Files •GDB Remote Protocol

System Interaction

Page 36: lldb reproducers - LLVM

Files

$ lldb ./a.out (lldb) target create "a.out" (binary)(lldb) b main.cpp:12 (debug information)...(lldb) run (shared libraries)...(lldb) expr @import Foo (headers)(lldb) expr Bar

Page 37: lldb reproducers - LLVM

Virtual File System

• Use files from the reproducer • YAML mapping between virtual and real paths • Lifted from clang to LLVM • Devirtualize to support FILE* and file descriptors

Page 38: lldb reproducers - LLVM

Filesystem Class

• Wrapper around the VFS • All file system access must go through this class • FileCollector used for recording files used by LLDB & clang

Page 39: lldb reproducers - LLVM

Components

•Command Line Interpreter •Public API (Scripting Bridge)

•Files •GDB Remote Protocol

System Interaction

Page 40: lldb reproducers - LLVM

GDB Remote Protocol

LLDB debugserver a.outGDB

Remote ProtocolImplementation

Defined

• Simple command and response protocol • Read and write memory, registers and to start/stop the process • Designed for remote debugging but also used locally

Page 41: lldb reproducers - LLVM

Capture

LLDB debugserver a.outGDB

Remote ProtocolImplementation

Defined

Reply #1

Reply #2

Reply #3

Reply #4

Reply #5

...

Page 42: lldb reproducers - LLVM

Replay

LLDB replay serverGDB

Remote Protocol

• Responds with recorded reply (in order) • Fully transparent to the debugger • Replay remote debug sessions

Reply #1

Reply #2

Reply #3

Reply #4

Reply #5

...

Page 43: lldb reproducers - LLVM

Limitations and future work

Page 44: lldb reproducers - LLVM

API Arguments

• Function pointers • Void & data pointers

ID 10

Data 0xFF ... 0x00

Length 56

void Foo(char* data, size_t length);

Page 45: lldb reproducers - LLVM

Memory Management

• No lifetime tracking for now • Pointer addresses can be reused • Objects created during replay are never deallocated

Page 46: lldb reproducers - LLVM

Swift

• Virtual File System • FileCollector callback

Page 47: lldb reproducers - LLVM

Reproducer Size

• Large files • Many files • Do we need all of them?

Page 48: lldb reproducers - LLVM

Crashes

• No guarantees in the signal handler • Do something smart like clang

Page 49: lldb reproducers - LLVM

Privacy

• Reproducers contain a lot of potentially sensitive information • Need to be clear and upfront about this to the user

Page 50: lldb reproducers - LLVM

• Please try it out!

• bugs.llvm.org

Page 51: lldb reproducers - LLVM

LLDB ReproducersJonas Devlieghere, LLVM Developers’ Meeting, Brussels, Belgium, April 2019

• Questions?