31
Life of breakpoint or an introduction to LLDB internal 2010/07/25 MORITA Hajime

A Life of breakpoint

  • View
    1.838

  • Download
    3

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: A Life of breakpoint

Life of breakpointor an introduction to LLDB internal

2010/07/25MORITA Hajime

Page 2: A Life of breakpoint

LLDB?

http://lldb.llvm.org/

• An open-source debugger, developed by Apple.• Announced at WWDC2010.• Will be used by XCode 4.0.• An LLVM subproject,

as the domain name implies.

Page 3: A Life of breakpoint

Features and Highlights

• Written in C++ (to be LLVM family)• Scripting aware SWIG API.• Designed as a library,not as a CLI program.

(It has one, though.)• Using Clang in some parts.

o Clang is C/C++/Obj-C Frontend for LLVM• Has pluggable parts

Page 4: A Life of breakpoint

Interesting facts

• Code size 200k lines (vs. 1000k lines for gdb)• Has LLDB.framework (vs. *.a for LLVM)• Currently 13 different commiters found

o Some are gdb-apple folkso Others from llvm, clang, llvm-gcco 2 external contributors, 1 ex-intern 

• Focused on iOS (SpringBoard)o Many #idef __arm__ codepaths.o API classes are named as "SBXxx"

• Does not have unit-tests. o some scripting-based tests.

• Looks far from 1.0 release.o Missing features, frequent crashes....

Page 5: A Life of breakpoint

How far from 1.0What isn't there yet:• Regression test suite• Operating system support hasn't been fully modularized yet• Blocks support• Calling functions in expressions• Objective-C 2.0 Support: Printing properties, synthetic

properties, Objective-C expressions, KVO, dynamic types, dot syntax, runtime data

• C++ support: Method access, handling demangled names, dynamic types

• Exception support: Breaking by name, thrown object, thrower

http://lldb.llvm.org/status.html

Page 6: A Life of breakpoint

How far from 1.0ProcessMacOSX::EnableBreakpoint (BreakpointSite *bp_site){    ....    if (bp_site->HardwarePreferred())    {        // FIXME: This code doesn't make sense.  ...       //        ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(bp_site->GetThreadID()).get();//        if (thread)//        {//            bp_site->SetHardwareIndex (thread->SetHardwareBreakpoint(bp_site));//            if (bp_site->IsHardware())//            {//                bp_site->SetEnabled(true);//                return error;//            }//        }    }    // Just let lldb::Process::EnableSoftwareBreakpoint() handle everything...    return EnableSoftwareBreakpoint (bp_site);}

Page 7: A Life of breakpoint

Questions arise

• What is Clang used for?• What part is scriptable?• What part is pluggable? 

But before these....

• How we can play with it?• How code is organized?• How debugger works so far?

Page 8: A Life of breakpoint

Questions arise

• What is Clang used for?• What part is scriptable?• What part is pluggable?

But before these....

• How we can play with it?• How code is organized?• How debugger works so far?

Page 9: A Life of breakpoint

Play with LLDB

$ svn co http://llvm.org/svn/llvm-project/lldb/trunk$ cd trunk ... setup code signing ... see docs/code-signing.txt$ xcodebuild -project lldb.xcodeproj -configuration Debug

$ ./build/Debug/lldb # invoking CLI clientCAUTION: Will checkout and build LLVM!

Page 10: A Life of breakpoint

Questions arise

• What is Clang used for?• What part is scriptable?• What part is pluggable?

But before these....

• How we can play with it?• How code is organized?• How debugger works so far?

Page 11: A Life of breakpoint

Architecture

Page 12: A Life of breakpoint

Architecture (contd.)

• Pluggable parts:o Target: {Process, Thread, ...} for Mac OS, Linux, gdbo Symbol: for DWARF, SYMTABo ObjectFile: for ELF, Mach-O

• API:o SWIG compatible headerso Pimpl-style separation from internal 

• Don't have CPU simulators (gdb has it.)• Modules are heavily Iter-dependent.

Page 13: A Life of breakpoint

Questions arise

• What is Clang used for?• What part is scriptable?• What part is pluggable?

But before these....

• How we can play with it?• How code is organized?• How debugger works so far?

Page 14: A Life of breakpoint

Questions arise

• What is Clang used for?• What part is scriptable?• What part is pluggable?

But before these....

• How we can play with it?• How code is organized?• How debugger works so far?

o Breakpointo Eval/Print

Page 15: A Life of breakpoint

To set a breakpoint, we should ...• Before process launch:

o Read Symbols from object files to launch• ....• Suspend a target process

o Using special system calls• Find function locations from Symbols.

o Symbol informations are from object files• Map that locations to addresses

in target process• Set breakpoints there

o Rewrite the code to 0xcc (sw bp)o Set the address to the special register (hw bp)

• Resume suspended

Page 16: A Life of breakpoint

LLDB representation of breakpoints

Page 17: A Life of breakpoint

System-calls around breakpoint

• Launching/stopping a process: posix_spawnp(), kill()

• Suspending/Resuming:task_suspend(), task_resume() 

• Writing breakpoint bytes:mach_vm_write()

See:• tools/debugserver/source/MacOSX/MachTask.cpp• tools/debugserver/source/MacOSX/MachVMMemory.cpp• The book.

Page 18: A Life of breakpoint

Questions arise

• What is Clang used for?• What part is scriptable?• What part is pluggable?

But before these....

• How we can play with it?• How code is organized?• How debugger works so far?

o Breakpointo Eval/Print

Page 19: A Life of breakpoint

Questions arise

• What is Clang used for?• What part is scriptable?• What part is pluggable?

But before these....

• How we can play with it?• How code is organized?• How debugger works so far?

o Breakpointo Eval/Print

Page 20: A Life of breakpoint

Evaluating Expression

It's just a yet another interpreter, except:

• Data and code stay in the target process.• Type definitions are in the object files.

Page 21: A Life of breakpoint

Evaluating expression: 2 Paths

"void ___clang_expr(void *___clang_arg) {" + text + "}"

@target @host

Page 22: A Life of breakpoint

DWARF Expression

• An virtual instruction set (stack machine style)• Defined in DWARF3 standard or later

• LLDB implementingo An interpreter for DWARF expression.o Clang AST to DWARF expression conversion.

(not LLVM backend.)• Using LLVM to invoke target functions.

In DWARF Version 2, all DWARF expressions were called "location expressions", whether they computed a location (address, register) or not. 

(from Dwarf3.pdf)

Page 23: A Life of breakpoint

Evaluating Expr: some questions

• How to lookup variables in the exp?o Clang provides hooks, LLDB takes them.

• How to run a compiled function?o Write the code to the target memory.o Troubles around linking. 

• How to get the result of expression?o Modify the AST to store the last stmt.

• Works well?o No. It crashes early and often.

Page 24: A Life of breakpoint

Printing structured variables• Reconstruct Clang's type representations

from DWARF entrieso Recursively traverses the object with it.

• Doesn't looks to work yet. But code is there...

Page 25: A Life of breakpoint

Questions arise

• What is Clang used for?• What part is scriptable?• What part is pluggable?

But before these....

• How we can play with it?• How code is organized?• How debugger works so far?

Page 26: A Life of breakpoint

Scriptability• via SWIG•  Process, Thread, Symbol, Type, Value, Debugger

 ...• 2 entry points:

o From a standalone program.o From the CLI interpreter.o Integrations is not enough yet.

(cannot print WTF::Vector from CLI side.)

Page 27: A Life of breakpoint

Other topics

• Testing• External contribution

Page 28: A Life of breakpoint

Testing

• ~20 test cases (publicly available)• Written over Python binding

Page 29: A Life of breakpoint

class TestClassTypes(lldbtest.TestBase):    ...    def test_function_types(self):        """Test 'callback' has function ptr type, then ..."""        res = self.res        exe = os.path.join(os.getcwd(), "a.out")        self.ci.HandleCommand("file " + exe, res)        self.assertTrue(res.Succeeded())

        # Break inside the main.        self.ci.HandleCommand("breakpoint set -f main.c -l 21", res)        self.assertTrue(res.Succeeded())        self.assertTrue(res.GetOutput().startswith(            "Breakpoint created: 1: file ='main.c', line = 21, ..."))

        self.ci.HandleCommand("run", res)        time.sleep(0.1)        self.assertTrue(res.Succeeded())    ...        # The stop reason of the thread should be breakpoint.        self.ci.HandleCommand("thread list", res)        print "thread list ->", res.GetOutput()        self.assertTrue(res.Succeeded())        self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and                        ...)    ...

Page 30: A Life of breakpoint

External Contribution

• Linux porting has been started.• Huge space to contribution:

o Testing!!!o CLI improvement (What Apple folks has little interest)o Reporting crashes

• Looks better to avoido Digging in the internal structures (will change fast)

• What I'd like to have as an (imaginary) contributoro Non-mail-based Review processo Buildbotso Coding convention (currently scattered.)

Page 31: A Life of breakpoint

Questions?