使用lldb调试bitcoin

ubuntu 16.04 安装 LLDB

sudo apt-get install LLDB

如果提示缺少 six 包,需要使用 python 安装一下

// install pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
pip install six

注意 docker 里面使用的时候,需要使用 –privileged 参数创建容器

config file 默认配置文件

放入喜欢的命令,会在启动的时候执行

~/.lldbinit
type format add --format hex int
type format add --format hex "char"
type format add --format hex "unsigned char"
set set stop-line-count-before 20
set set stop-line-count-after 15
settings set target.max-string-summary-length 16384
command alias brpos breakpoint set -f %1 -l %2
settings set target.process.thread.step-in-avoid-nodebug false
settings set target.skip-prologue false
settings set target.x86-disassembly-flavor intel
settings set stop-disassembly-count 8

lldb 使用样例

命令格式:
命令、命令操作、options命令选项、argument参数。命令各个元素之间用空格隔开,如果参数之中有空格则需要加上双引号。如果参数中带有反斜杠和双引号,则需要在其前面加上反斜杠。

<noun> <verb> [-options [option-value]] [argument [argument...]]

options命令选项可以放在命令行的任何地方,但是如果argument参数以“-”开头,那么必须在option后面添加“–”结束标志进行区分,从而确定option的正确位置。例如你想启动一程序,“process launch”命令的option为“–stop-at-entry”,同时希望命令的argument为“-program_arg value”,你应该输入的命令为:

(lldb) process launch --stop-at-entry -- -program_arg value

macos 使用 lldb 调试 bitoin

// 如果有下面的错误提示
ImportError: cannot import name _remove_dead_weakref
// 切回系统自带python
export PATH=/usr/bin:$PATH

获取帮助

lldb -h

载入程序

启动时载入

lldb ./src/primecoind

动态栽入

$ lldb
(lldb) file /Projects/Sketch/build/Debug/Sketch.app

运行前设置环境变量

(lldb) settings set target.env-vars DEBUG=1
(lldb) set se target.env-vars DEBUG=1
(lldb) env DEBUG=1

设置断点

函数名 foo

(lldb) breakpoint set -n foo
breakpoint 简写 br

// 可以一次指定多个函数
(lldb) br set --name foo --name bar

文件 foo.c 行数 12

(lldb) br set -f foo.c -l 12

条件断点

(lldb) breakpoint set --name foo --condition '(int)strcmp(y,"hello") == 0'
(lldb) br s -n foo -c '(int)strcmp(y,"hello") == 0'

查看断点信息

(lldb) br list
(lldb) br l

禁用断点

# 禁用断点
# 根据上面查看断点列表的时候的序号来操作断点
(lldb) breakpoint disable 2

启用断点

(lldb) breakpoint enable 2

删除断点

(lldb) br del 1

执行到指定行数

thread until linenum

运行程序

下面的命令都是一样的

(lldb) process launch
(lldb) run
(lldb) r

运行时设置环境变量

(lldb) r -v DEBUG=1

指定参数运行

例如你想启动一程序,“process launch”命令的option为“–stop-at-entry”,同时希望命令的argument为“-program_arg value”,你应该输入的命令为:

(lldb) process launch --stop-at-entry -- -program_arg value
(lldb) process launch -- <args>
(lldb) r <args>

附加在已经运行的程序

waitfor 参数,会在下次程序运行时自动附加上

(lldb) process attach --pid 123
(lldb) process attach --name Sketch
(lldb) process attach --name Sketch --waitfor

继续运行

(lldb) thread continue // "c"
(lldb) thread step-in // The same as gdb's "step" or "s"
(lldb) thread step-over // The same as gdb's "next" or "n"
(lldb) thread step-out // The same as gdb's "finish" or "f"

// 按指令步进
(lldb) thread step-inst // The same as gdb's "stepi" / "si"
(lldb) thread step-over-inst // The same as gdb's "nexti" / "ni"

停止程序

Stop your process.

(lldb) exit

查看当前代码

(lldb) f
//显示前 10 行
(lldb) l -
list 1就回到第一行了。l 13就是从第13行开始往下看10行。
list 文件名看其他文件的代码
(lldb) list ArrayUtils.c
看某个函数的代码
(lldb) list main

查看变量

print(简写p)如果打印的是基础数据类型,则会列出基础数据类型的类型和值。如果是对象,还会打印出对象指针地址
print的打印信息较多,如果只想查看对象的值,则可以使用po(printobject)命令
对于基础数据类型,还可以指定格式打印,如用16进制的格式打印:
po一般用来输出指针指向的那个对象,p一般用来输出基础变量。普通数组两者都可用

(lldb) p str
(lldb) po str
(lldb) p/x 16
0x10

查看本地变量

frame variable 简称 fr v

列出所有变量
(lldb) fr v

指定变量 self
(lldb) fr v self

指定变量 self 的子元素
(lldb) fr v self.isa

设置显示代码行数

(lldb) set set stop-line-count-before 10
(lldb) set set stop-line-count-after 10

设置查看类型

下面会把 int,unsigned char 类型的数据显示成 16 进制形式

(lldb) type format add --format hex int
(lldb) type format add --format hex "unsigned char"

设置别名

# 比如下面的这条命令
(lldb) breakpoint set --file DebugDemo.c --line 10

# 你就可以写这样的别名
(lldb) command alias brpos breakpoint set -f %1 -l %2

# 使用的时候就像这样就好了
(lldb) brpos DebugDemo.c 10

修改变量

expression表达式(expr),expr常用于调试时修改变量的值

(lldb) expr self.productId = @"A0000001076"

它的作用不仅仅是修改变量的值,你加其他功能的代码也是可以的,只要是和上下文相关的一句代码就OK
注意:表达式之后不需要加分号,加了分号之后会报错

(lldb) expr self.superNavBarView.backgroundColor = [UIColor redColor]
(UICachedDeviceRGBColor *) $3 = 0x00007ffc783d0290

查看线程状态

thread backtrace 简称 bt
thread backtrace [-c <count>] [-s <frame-index>] [-e <boolean>]
thread backtrace后面跟的都是命令选项:
-c:设置打印堆栈的帧数(frame)
-s:设置从哪个帧(frame)开始打印
-e:是否显示额外的回溯

查看当前线程信息,* 号表示当前线程
(lldb) thread list
// 查看调用栈
(lldb) bt
(lldb) bt all
// 选择线程2
(lldb) thread select 2
thread info: 输出当前线程的信息

列出主应用和依赖的动态库

(lldb) image list

命令行参数

Usage:

lldb -h
lldb -v [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]
lldb -a <arch> -f <filename> [-c <filename>] [-s <filename>] [-o <none>] [-S <filename>] [-O <none>] [-k <none>] [-K <filename>] [-Q] [-b] [-e] [-x] [-X] [-l <script-language>] [-d] [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]
lldb -n <process-name> -w [-s <filename>] [-o <none>] [-S <filename>] [-O <none>] [-k <none>] [-K <filename>] [-Q] [-b] [-e] [-x] [-X] [-l <script-language>] [-d]
lldb -p <pid> [-s <filename>] [-o <none>] [-S <filename>] [-O <none>] [-k <none>] [-K <filename>] [-Q] [-b] [-e] [-x] [-X] [-l <script-language>] [-d]
lldb -P
lldb -r [<none>] -R <none>

-h
--help
Prints out the usage information for the LLDB debugger.

-v
--version
Prints out the current version number of the LLDB debugger.

-a <arch>
--arch <arch>
Tells the debugger to use the specified architecture when starting
and running the program. <architecture> must be one of the
architectures for which the program was compiled.

-f <filename>
--file <filename>
Tells the debugger to use the file <filename> as the program to be
debugged.

-c <filename>
--core <filename>
Tells the debugger to use the fullpath to <path> as the core file.

-p <pid>
--attach-pid <pid>
Tells the debugger to attach to a process with the given pid.

-n <process-name>
--attach-name <process-name>
Tells the debugger to attach to a process with the given name.

-w
--wait-for
Tells the debugger to wait for a process with the given pid or name
to launch before attaching.

-s <filename>
--source <filename>
Tells the debugger to read in and execute the lldb commands in the
given file, after any file provided on the command line has been
loaded.

-o
--one-line
Tells the debugger to execute this one-line lldb command after any
file provided on the command line has been loaded.

-S <filename>
--source-before-file <filename>
Tells the debugger to read in and execute the lldb commands in the
given file, before any file provided on the command line has been
loaded.

-O
--one-line-before-file
Tells the debugger to execute this one-line lldb command before any
file provided on the command line has been loaded.

-k
--one-line-on-crash
When in batch mode, tells the debugger to execute this one-line
lldb command if the target crashes.

-K <filename>
--source-on-crash <filename>
When in batch mode, tells the debugger to source this file of lldb
commands if the target crashes.

-Q
--source-quietly
Tells the debugger to execute this one-line lldb command before any
file provided on the command line has been loaded.

-b
--batch
Tells the debugger to running the commands from -s, -S, -o & -O,
and then quit. However if any run command stopped due to a signal
or crash, the debugger will return to the interactive prompt at the
place of the crash.

-e
--editor
Tells the debugger to open source files using the host's "external
editor" mechanism.

-x
--no-lldbinit
Do not automatically parse any '.lldbinit' files.

-X
--no-use-colors
Do not use colors.

-P
--python-path
Prints out the path to the lldb.py file for this version of lldb.

-l <script-language>
--script-language <script-language>
Tells the debugger to use the specified scripting language for
user-defined scripts, rather than the default. Valid scripting
languages that can be specified include Python, Perl, Ruby and Tcl.
Currently only the Python extensions have been implemented.

-d
--debug
Tells the debugger to print out extra information for debugging
itself.

-r
--repl
Runs lldb in REPL mode with a stub process.

-R
--repl-language
Chooses the language for the REPL.


Notes:

Multiple "-s" and "-o" options can be provided. They will be processed
from left to right in order, with the source files and commands
interleaved. The same is true of the "-S" and "-O" options. The before
file and after file sets can intermixed freely, the command parser will
sort them out. The order of the file specifiers ("-c", "-f", etc.) is
not significant in this regard.


If you don't provide -f then the first argument will be the file to be
debugged which means that 'lldb -- <filename> [<ARG1> [<ARG2>]]' also
works. But remember to end the options with "--" if any of your
arguments have a "-" in them.