lldb reproducers
play

LLDB Reproducers Jonas Devlieghere, Apple LLVM Developers - PowerPoint PPT Presentation

LLDB Reproducers Jonas Devlieghere, Apple LLVM Developers Meeting, Brussels, Belgium, April 2019 "The debugger doesn't work" Somebody on the internet LLDB Bugs $ lldb ./a.out (lldb) target create


  1. LLDB Reproducers • • Jonas Devlieghere, Apple LLVM Developers’ Meeting, Brussels, Belgium, April 2019

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

  3. LLDB Bugs $ lldb ./a.out (lldb) target create "a.out" (lldb) b main.cpp:12 ... (lldb) run ... (lldb) expr @import Foo (lldb) expr Bar cannot materialize variable

  4. LLDB Bug Reports   "Hey this doesn't work..." Bob Alice

  5. LLDB Bug Reports   "Can you attach the expr log?" Bob Alice

  6. LLDB Bug Reports   Expression log Bob Alice

  7. LLDB Bug Reports   "Can you attach the type log?" Bob Alice

  8. LLDB Bug Reports   Type log Bob Alice

  9. LLDB Bug Reports   "How do I reproduce?" Bob Alice

  10. LLDB Bug Reports   Steps to reproduce Bob Alice

  11. LLDB Bug Reports 🤭  "It doesn't reproduce..." Bob Alice

  12. Reproducers • Automate the process • Everything needed to reproduce • Inspired by clang

  13. Reproducers   "Hey this doesn't work..." 📧 Bob Alice

  14. Reproducers 📧   $ lldb ./a.out --capture $ lldb --replay reproducer (lldb) target create "a.out" (lldb) target create "a.out" (lldb) b main.cpp:12 (lldb) b main.cpp:12 ... ... (lldb) run (lldb) run ... ... (lldb) expr @import Foo (lldb) expr @import Foo (lldb) expr Bar (lldb) expr Bar cannot materialize variable cannot materialize variable (lldb) reproducer generate

  15. LLDB Reproducers

  16. Reconstruct the debugger's state • How we get there is more important than the final result • Capture data • Debug during replay

  17. 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

  18. Minimize impact • Don't hide or introduce bugs • Reuse existing infrastructure • Transparency and abstraction

  19. Components

  20. User Interaction • Command Line Interpreter • Public API (Scripting Bridge) • Files • GDB Remote Protocol

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

  22. User Interaction • Command Line Interpreter • Public API (Scripting Bridge) • Files • GDB Remote Protocol

  23. Stable C++ API • Accessible through Python wrappers • Used by IDEs such as Xcode, Eclipse, Visual Studio Code • How the command line driver is implemented

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

  25. Capture and replay API calls • Capture the call and its argument values • Capture the return value

  26. API Boundary Python SBTarget SBDebugger CreateTarget() GetByteOrder() API boundary

  27. API Boundary Python SBTarget SBDebugger CreateTarget() GetByteOrder() GetByteOrder() API boundary

  28. 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

  29. 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); }

  30. 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));

  31. lldb-instr • Utility on top of libTooling • Traverses the clang AST • Inserts the record and register macros

  32. Capturing Arguments • Stream values to file • Look at underlying value for pointers and references

  33. Capturing Objects • Index based on object address • Table keeps mapping between object and index Object Index SBDebugger debugger = SBDebugger::Create(); debugger 1 SBTarget target = debugger.createTarget(); SBLaunchInfo info("--arguments"); target 2 target.Launch(info); info 3

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

  35. Components System Interaction • Command Line Interpreter • Public API (Scripting Bridge) • Files • GDB Remote Protocol

  36. 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

  37. 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

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

  39. Components System Interaction • Command Line Interpreter • Public API (Scripting Bridge) • Files • GDB Remote Protocol

  40. GDB Remote Protocol • Simple command and response protocol • Read and write memory, registers and to start/stop the process • Designed for remote debugging but also used locally GDB Implementation Remote Protocol Defined LLDB debugserver a.out

  41. Capture GDB Implementation Remote Protocol Defined LLDB debugserver a.out Reply #1 Reply #2 Reply #3 Reply #4 Reply #5 ...

  42. Replay • Responds with recorded reply (in order) • Fully transparent to the debugger • Replay remote debug sessions Reply #1 GDB Reply #2 Remote Protocol Reply #3 LLDB replay server Reply #4 Reply #5 ...

  43. Limitations and future work

  44. API Arguments • Function pointers • Void & data pointers void Foo(char* data, size_t length); ID Data Length 10 0xFF ... 0x00 56

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

  46. Swift • Virtual File System • FileCollector callback

  47. Reproducer Size • Large files • Many files • Do we need all of them?

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

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

  50. Please try it out! • bugs.llvm.org •

  51. Questions? • LLDB Reproducers 
 Jonas Devlieghere, LLVM Developers’ Meeting, Brussels, Belgium, April 2019

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend