运行lldb
lldb main.out
或者直接lldb,进入后 使用file main.out指定要调试的文件
注意:运行之前要clang++ -g
,一定要有-g
参数才能用lldb调试。
另一种执行:lldb main.out example1
假设可执行程序名为 main.out,参数为 example1
qquit
离开lldb
tab键
支持tab键联想,输入br然后按下tab就会联想出breakpoint
然后再次按下tab会联想出子命令:
(lldb) breakpoint
Available completions:
clear
command
delete
disable
enable
list
modify
name
read
set
write
(lldb) breakpoint
help
查看帮助,支持help b查看b命令的帮助:
_regexp-break <filename>:<linenum>
main.c:12 // Break at line 12 of main.c
_regexp-break <linenum>
12 // Break at line 12 of current file
_regexp-break 0x<address>
0x1234000 // Break at address 0x1234000
_regexp-break <name>
main // Break in 'main' after the prologue
_regexp-break &<name>
&main // Break at first instruction in 'main'
_regexp-break <module>`<name>
libc.so`malloc // Break in 'malloc' from 'libc.so'
_regexp-break /<source-regex>/
/break here/ // Break on source lines in current file
// containing text 'break here'.
'b' is an abbreviation for '_regexp-break'
help breakpoint list //查看breakpoint list的帮助
run/r
执行程序
breakporint 断点
help breakpoint 查看命令
_regexp-break <filename>:<linenum>
main.c:12 // Break at line 12 of main.c main.c文件的12行
_regexp-break <linenum>
12 // Break at line 12 of current file当前文件12行
_regexp-break 0x<address>
0x1234000 // Break at address 0x1234000 地址断点
_regexp-break <name>
main // Break in 'main' after the prologue
_regexp-break &<name>
&main // Break at first instruction in 'main'
_regexp-break <module>`<name>
libc.so`malloc // Break in 'malloc' from 'libc.so'
_regexp-break /<source-regex>/
/break here/ // Break on source lines in current file
// containing text 'break here'.
'b' is an abbreviation for '_regexp-break'
删除断点
l/list
查看当前文件代码
看某个函数的代码:直接输入某个函数的名字即可
(lldb) help list
List relevant source code using one of several shorthand formats. Expects 'raw' input (see 'help raw-input'.)
Syntax:
_regexp-list <file>:<line> // List around specific file/line
_regexp-list <line> // List current file around specified line
_regexp-list <function-name> // List specified function
_regexp-list 0x<address> // List around specified address
_regexp-list -[<count>] // List previous <count> lines
_regexp-list // List subsequent lines
如果程序编译的时候是由很多文件组成的,那么就可以使用list 文件名
看其他文件的代码, 以后再执行 list 3 的时候,看的就是你前面设置的文件名的第三行。
c 、n、 s、 finsh
c/continue,继续执行
n/next,单步调试
s/step,进入一个函数
finsh,执行完当前函数
查看变量、跳帧查看变量
使用po或p,po一般用来输出指针指向的那个对象,p一般用来输出基础变量。普通数组两者都可用
(lldb) po result_array
查看所有帧(bt)
(lldb) bt
函数调用栈由连续的栈帧组成。每个栈帧记录一个函数调用的信息,这些信息包括函数参数,函数变量,函数运行地址。
当程序启动后,栈中只有一个帧,这个帧就是main函数的帧。我们把这个帧叫做初始化帧或者叫做最外层帧。每当一
个函数被调用,一个新帧将被建立,每当一个函数返回时,函数帧将被剔除。如果函数是个递归函数,栈中将有很多帧是
记录同一个函数的。但前执行的函数的帧被称作最深帧,这个帧是现存栈中最近被创建的帧。
在程序内部,函数栈帧用函数的地址来标记。一个帧由一定字节的内存组成,每个字节都有自己的地址 。每种类型的计
算机有个约定,用一个特殊字节的地址存放函数帧的地址。通常函数帧的地址存放在一个称作帧指针的寄存器中--$fp.
gdb 为所有存活的栈帧分配一个数字编号,最深帧的编号是0,被它调用的内个帧的编号就是1。这些编号子程序中是不
存在的,只不过时调试的时候被gdb用的。
关于函数帧的两个指令:
frame args
移动到args指定的栈帧中去,并打印选中的栈的信息。args可以时帧编号或者时帧的地址。如果没有args,则打印当前帧的信息。
select-frame args
移动到指定的帧中去,不打印信息。
跳帧(frame select)
(lldb) frame select 1
查看当前帧中所有变量的值(frame variable)
(lldb) frame variable