最小化的lldb使用方法
写代码难免出错,以前都是print的方式调试。但发现不是很方便,于是想了解一下lldb的使用。
1. 载入并运行
lldb test
(lldb) target create "test"
Current executable set to '/data/data/com.termux/files/home/src/chong/llvm-src/002_Kaleidoscope/my/bb/test' (aarch64).
(lldb) run
Process 28856 launched: '/data/data/com.termux/files/home/src/chong/llvm-src/002_Kaleidoscope/my/bb/test' (aarch64)
ready> 89+90;
ready> Process 28856 stopped
* thread #1, name = 'test', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
frame #0: 0x0000007fbd756654 libc++_shared.so`std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>>::basic_string(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>> const&) + 20
libc++_shared.so`std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>>::basic_string:
-> 0x7fbd756654 <+20>: ldrb w8, [x1]
0x7fbd756658 <+24>: mov x19, x0
0x7fbd75665c <+28>: tbnz w8, #0x0, 0x7fbd756684 ; <+68>
0x7fbd756660 <+32>: ldr x8, [x1, #0x10]
已经出现异常了。
2. 查看函数调用栈
(lldb) thread backtrace
* thread #1, name = 'test', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
* frame #0: 0x0000007fbd756654 libc++_shared.so`std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>>::basic_string(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>> const&) + 20
frame #1: 0x0000005555d63ba4 test`FunctionAST::codegen(this=0xb400007dbd62c330) at ast.cpp:159:48
frame #2: 0x0000005555d6699c test`Parser::HandleTopLevelExpression() at parse.cpp:254:29
frame #3: 0x0000005555d66e3c test`Parser::MainLoop() at parse.cpp:301:7
frame #4: 0x0000005555d60e2c test`main at main.cpp:36:3
frame #5: 0x0000007fbd9645e0 libc.so`__libc_init + 100
(lldb)
frame #0 表示出现异常的位置,但那是一个库函数,我自己写的代码是在frame #1那里。
3. 切换frame到我的代码
(lldb) frame select 1
frame #1: 0x0000005555d63ba4 test`FunctionAST::codegen(this=0xb400007dbd62c330) at ast.cpp:159:48
156
157 // First, check for an existing function from a previous 'extern' declaration.
158 // Function *TheFunction = ExprAST::getFunction(P.getName());
-> 159 Function *TheFunction = ExprAST::getFunction(Proto->getName());
160
161 if (!TheFunction)
162 TheFunction = Proto->codegen();
(lldb)
已经有我的源码了。
4. 检查变量
(lldb) var
Available completions:
this
TheFunction
BB
P
__begin1
__end1
__range1
Arg
RetVal
llvm::VerifyDisableABIBreakingChecks
std::__ndk1::piecewise_construct
ExprAST::TheContext
ExprAST::ExitOnErr
ExprAST::TheJIT
ExprAST::TheModule
ExprAST::TheFPM
ExprAST::Builder
ExprAST::FunctionProtos
ExprAST::NamedValues
(lldb) frame variable
(FunctionAST *) this = 0xb400007dbd62c330
(llvm::Function *) TheFunction = <variable not available>
(llvm::BasicBlock *) BB = <variable not available>
(PrototypeAST &) P = <no location, value may have been optimized out>
(lldb)
到这里已经基本上能解决问题了。
5. 学会使用help
我觉得调试和游泳差不多,并不需要记住什么,而是应该多用多练。
help是一个不错的命令。
6. 查看源码
如果你想了解lldb的底层原理,只能通过看源码了。