gdb怎样修改gdb 多进程调试内存的,用C怎样实现

14:59 提问
pwntools如何用利用Pwnlib.gdb进行远程调试?
这几天在学习pwn,在调试一些交互程序的时候,需要输入信息,可是无法在调试过程中输入内存地址,无法观察输入字符串是否覆盖到了栈地址(比如在测试栈溢出的到时候,利用python可以python -c "print 'A'*123 +‘\x12\x12\x12.......’")
因此想进行远程调试,从网上找到pwntools,其中pwnlib.gdb的gdb.debug可以用来远程调试,就是用gdb.debug()可以开启一个gdbserver,可是没有成功...求各路大神解答。如下图:
用gdb.debug打开程序,开启一个gdbserver
在gdbserver中看到这句提示,不知道什么意思
没有找到main函数,无法下断点
TAB键找到的时malloc,说明程序没有停到正常入口处,为何?
按赞数排序
在进行嵌入式系统开发中,受到嵌入式系统资源的限制,调试环境和通用桌面系统的调试环境有差别,引入了远程调试技术。这时,调试器运行于通过桌面系统,被调试的程序则运行于基于特定硬件平台的嵌入式系统(目标系统)。因此,要求调试器和被调试程序之间进行通信,调试器还需要能够处理某些特定硬件平台的信息。
插桩(stub)方案是在目标系统和调试器内分别加入某些功能模块,二......答案就在这里:----------------------Hi,地球人,我是问答机器人小S,上面的内容就是我狂拽酷炫叼炸天的答案,除了赞同,你还有别的选择吗?
用利用Pwnlib.gdb进行远程调试? 1C
这几天在学习pwn,在调试一些交互程序的时候,需要输入信息,可是无法在调试过程中输入内存地址,无法观察输入字符串是否覆盖到了栈地址(比如在测试栈溢出的到时候,利用python可以python -c "print 'A'*123 +‘\x12\x12\x12.......’")
因此想进行远程调试,从网上找到pwn
很简单,能下malloc断点,不能下main断点而且出现“Function main not defined”证明程序没有main这个符号
可以IDA中查看main地址,然后b *0x下断点
其他相关推荐让分享融入生活
评论- 375&
  今天介绍一下gdb,如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。
  GDB主要帮忙你完成下面四个方面的功能:
&&& 1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。&&& 2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)&&& 3、当程序被停住时,可以检查此时你的程序中所发生的事。&&& 4、动态的改变你程序的执行环境。
  一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如:
&&& & cc -g hello.c -o hello&&& & g++ -g hello.cpp -o hello
  如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他。  
  启动GDB的方法有以下几种:
&&& 1、gdb &program& &&&&&& program也就是你的执行文件,一般在当前目录下。
&&& 2、gdb &program& core&&&&&& 用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。
&&& 3、gdb &program& &PID&&&&&&& 如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。
  在启动了gdb后,就可以开始使用gdb中命令了。如果希望查看都有哪些命令,可以输入help进行查询。
  下面简单演示几个小例子:
  示例一:在进入函数func时,设置一个断点。可以敲入break func,或是直接就是b func&&& (gdb) b func&&& Breakpoint 1 at 0x8048458: file hello.c, line 10.
  示例二:敲入b按两次TAB键,你会看到所有b打头的命令:&&& (gdb) b&&& backtrace& break&&&&& bt
  示例三:l(l命令相当于list,从第一行开始例出原码)
  示例四:r(运行程序) n(下一步) c(Continuing)
  示例五:p i 查看变量i的值
  示例六:bt 查看函数堆栈
  需要特别说明的是,在gdb中运行程序时,使用run命令,可能需要做以下的操作。
  1、程序运行参数。&&& set args 可指定运行时参数。(如:set args 10 20 30 40 50)&&& show args 命令可以查看设置好的运行参数。
  2、运行环境。&&& path &dir& 可设定程序的运行路径。&&& show paths 查看程序的运行路径。&&& set environment varname [=value] 设置环境变量。如:set env USER=hchen&&& show environment [varname] 查看环境变量。  
  3、工作目录。&&& cd &dir& 相当于shell的cd命令。&&& pwd 显示当前的所在目录。
  4、程序的输入输出。&&& info terminal 显示你程序用到的终端的模式。&&& 使用重定向控制程序输出。如:run & outfile&&& tty命令可以指写输入输出的终端设备。如:tty /dev/ttyb
  以上就是对gdb简单的一个介绍,以后如果有机会会更详细的介绍各种功能。请大家多多指教。
  注:如果希望了解更多关于gdb的知识,请看http://blog.csdn.net/haoel/article/details/2879。
阅读(...) 评论()用户名:laokaddk
文章数:983
评论数:108
访问量:2720303
注册日期:
阅读量:1297
阅读量:3317
阅读量:585668
阅读量:471540
51CTO推荐博文
先废话两句,这篇文章可能有所缺陷,因为我并没有条件去测试动态库的调试。(主要是因为是自己的手机不想乱放各种so)
所以我只能说有空的话我会去进行下测试,这里就先这样了。
1、测试代码gdb-test.c
#include &stdio.h&
int main() {
& printf(&this is gdb test !!!\n&);
2、Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := gdb-test.cpp
LOCAL_MODULE&& &&& &:= gdb-test
include $(BUILD_EXECUTABLE)
3、 shell中输入
# $NDK/ndk-build NDK_DEBUG=1
强制生成debug版的代码,这里$NDK为ndk根目录。
这时候你会发现有 gdb-test& gdbserver gdb.setup这几个文件生成。
4、拷贝gdb-test gdbserver到device的data目录下(这里只是为了简单)
5、在shell中输入
# adb shell
进入到device中的shell中
# ./gdbserver 192.168.0.235:2000 ./gdb-test
这里假设device的ip地址为192.168.0.235,我们给gdbserver使用的端口为2000
成功的话你会看到
# Listening on port 2000
说明成功开启了服务
6、在pc上使用ndk中toolchain提供的gdb,具体路径为
$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb
# $NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb ./gdb-test
注意,这里的gdb-test的位置非常重要,因为你可以看到在libs下有个gdb-test,在obj下也有,为了保证符号表
能成功进行加载,这里必须使用在obj下的gdb-test,因为libs中生成的始终是去掉符号表的,只有objs中的才是真正可调试的。
成功后进入gdb中,输入
# (gdb)target remote 192.168.0.235:2000
如果一切正常的话那么应该就可以正常进行调试了。
了这篇文章
类别:┆阅读(0)┆评论(0)GDB中应该知道的几个调试方法
时间: 19:23:34
&&&& 阅读:318
&&&& 评论:
&&&& 收藏:0
标签:GDB中应该知道的几个调试方法
七、八年前写过一篇《》,于是,从那以后,很多朋友在MSN上以及给我发邮件询问我关于GDB的问题,一直到今天,还有人在问GDB的相关问题。这么多年来,有一些问题是大家反复在问的,一方面,我觉得我以前的文章可能没有说清楚,另一方面,我觉得大家常问的问题正是最有用的,所以,在这里罗列出来。希望大家补充。
一、多线程调试
多线程调试可能是问得最多的。其实,重要就是下面几个命令:
info thread 查看当前进程的线程。
thread &ID& 切换调试的线程为指定ID的线程。
break file.c:100 thread all &在file.c文件第100行处为所有经过这里的线程设置断点。
set scheduler-locking off|on|step,这个是问得最多的。在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。
二、调试宏
这个问题超多。在GDB下,我们无法print宏定义,因为宏是预编译的。但是我们还是有办法来调试宏,这个需要GCC的配合。
在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了。
另外,你可以使用下述的GDB的宏调试命令&来查看相关的宏。
info macro & 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。
macro & 你可以查看宏展开的样子。
三、源文件
这个问题问的也是很多的,太多的朋友都说找不到源文件。在这里我想提醒大家做下面的检查:
编译程序员是否加上了-g参数以包含debug信息。
路径是否设置正确了。使用GDB的directory命令来设置源文件的目录。
下面给一个调试/bin/ls的示例(ubuntu下)
$ apt-get source coreutils
$ sudo apt-get install coreutils-dbgsym
$ gdb /bin/ls
GNU gdb (GDB) 7.1-ubuntu
(gdb) list main
1192&&& ls.c: No such file or directory.
(gdb) directory ~/src/coreutils-7.4/src/
Source directories searched: /home/hchen/src/coreutils-7.4:$cdir:$cwd
(gdb) list main
1192&&&&&&& }
1195&&& int
1196&&& main (int argc, char **argv)
1199&&&&& struct pending *
1200&&&&& int n_
四、条件断点
条件断点是语法是:break &[where] if [condition],这种断点真是非常管用。尤其是在一个循环或递归中,或是要监视某个变量。注意,这个设置是在GDB中的,只不过每经过那个断点时GDB会帮你检查一下条件是否满足。
五、命令行参数
有时候,我们需要调试的程序需要有命令行参数,很多朋友都不知道怎么设置调试的程序的命令行参数。其实,有两种方法:
gdb命令行的 &args 参数
gdb环境中 set args命令。
六、gdb的变量
有时候,在调试程序时,我们不单单只是查看运行时的变量,我们还可以直接设置程序中的变量,以模拟一些很难在测试中出现的情况,比较一些出错,或是switch的分支语句。使用set命令可以修改程序中的变量。
另外,你知道gdb中也可以有变量吗?就像shell一样,gdb中的变量以$开头,比如你想打印一个数组中的个个元素,你可以这样:
(gdb) set $i = 0
(gdb) p a[$i++]
当然,这里只是给一个示例,表示程序的变量和gdb的变量是可以交互的。
也许,你很喜欢用p命令。所以,当你不知道变量名的时候,你可能会手足无措,因为p命令总是需要一个变量名的。x命令是用来查看内存的,在gdb中 &help x& 你可以查看其帮助。
x/x 以十六进制输出
x/d 以十进制输出
x/c 以单字符输出
x/i &反汇编 & 通常,我们会使用&x/10i $ip-20 来查看当前的汇编($ip是指令寄存器)
x/s 以字符串输出
八、command命令
有一些朋友问我如何自动化调试。这里向大家介绍command命令,简单的理解一下,其就是把一组gdb的命令打包,有点像字处理软件的&宏&。下面是一个示例:
(gdb) break func
Breakpoint 1 at 0x3475678: file test.c, line 12.
(gdb) command 1
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
&print arg1
&print arg2
&print arg3
当我们的断点到达时,自动执行command中的三个命令,把func的三个参数值打出来。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/hcq11/blog/item/9f5bfc6ecb4a25.html&
/litto/blog/item/dd1e.html&
http://blogold.chinaunix.net/u3/94700/showart_2389432.html& &&推荐阅读&
先介绍一下GDB多线程调试的基本命令。
info threads&显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程。
thread ID&切换当前调试的线程为指定ID的线程。
break thread_test.c:123 thread all&在所有线程中相应的行上设置断点
thread apply ID1 ID2 command&让一个或者多个线程执行GDB命令command。&
thread apply all command&让所有被调试线程执行GDB命令command。
set scheduler-locking off|on|step&估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。
gdb对于多线程程序的调试有如下的支持:
线程产生通知:在产生新的线程时, gdb会给出提示信息
(gdb) rStarting program: /root/thread&[New Thread
(LWP&12900)]&[New Thread
(LWP 12907)]---以下三个为新产生的线程[New Thread
(LWP 12908)][New Thread
(LWP 12909)]
查看线程:使用info threads可以查看运行的线程。
(gdb) info threads&&4&Thread
(LWP 12940)&& 0xffffe002 in ?? ()&&3&Thread
(LWP 12939)&& 0xffffe002 in ?? ()&&2&Thread
(LWP 12938)&& 0xffffe002 in ?? ()*&1&Thread
(LWP 12931)&& main (argc=1, argv=0xbfffda04) at thread.c:21(gdb)
注意,行首的蓝色文字为gdb分配的线程号,对线程进行切换时,使用该该号码,而不是上文标出的绿色数字。
另外,行首的红色星号标识了当前活动的线程
切换线程:使用&thread THREADNUMBER&进行切换,THREADNUMBER&为上文提到的线程号。下例显示将活动线程从 1 切换至 4。
(gdb) info threads&& 4 Thread
(LWP 12940)&& 0xffffe002 in ?? ()&& 3 Thread
(LWP 12939)&& 0xffffe002 in ?? ()&& 2 Thread
(LWP 12938)&& 0xffffe002 in ?? ()* 1 Thread
(LWP 12931)&& main (argc=1, argv=0xbfffda04) at thread.c:21(gdb)&thread 4[Switching to thread 4 (Thread
(LWP 12940))]#0&& 0xffffe002 in ?? ()(gdb) info threads* 4 Thread
(LWP 12940)&& 0xffffe002 in ?? ()&& 3 Thread
(LWP 12939)&& 0xffffe002 in ?? ()&& 2 Thread
(LWP 12938)&& 0xffffe002 in ?? ()&& 1 Thread
(LWP 12931)&& main (argc=1, argv=0xbfffda04) at thread.c:21(gdb)
后面就是直接在你的线程函数里面设置断点,然后continue到那个断点,一般情况下多线程的时候,由于是同时运行的,最好设置&set scheduler-locking on
这样的话,只调试当前线程&
&&国之画&&&& &&&&chrome插件&&
版权所有 京ICP备号-2
迷上了代码!GDB使用记录 - 简书
GDB使用记录
本文来自个人博客 。博客的文章保持更新,此文可能不是最新状态。
GDB,GNU Debugger,如下:
GDB具备各种调试功效,可对计算机程序的运行进行追踪、警告。使用者可以监控及修改程序内部变量的值,甚至可在程序的正常运行之外调用函数。
GDB支持多数处理器架构
持续开发中
支持远程调试
支持内核调试,KGDB
从事嵌入式软件开发两年来,主要在以下几方面使用GDB:
查看、修改运行时变量;
多线程调试,查看当前线程运行状态(以确定当前线程是不是因为等锁等原因挂起);
查看文件;
碰到难缠的内存非法改写问题,用GDB的断点、物理watch功能查看内存变化以定位改写者;
引用公司一个技术牛人的话:在大型的项目中,使用GDB的单步调试、软件watch是不现实的,因为会运行得实在太慢。
命令小记:
linux提示符
1. GDB进入正在运行的进程
gdb 可执行文件 core文件
gdb -p pid
1. 查看调用栈信息
bt / backtrace / bt full
info locals
2. 查看、设置变量
p 变量 = 新值
set 变量 = 新值
3. 查看内存
x/&n/f/u& &addr&
4. 线程调试
info thread
想用GDB调试,则在GCC编译的时候要加上-g选项。
启动GDB的方法主要有以下几种:
gdb executable_file
gdb executable_file corefile:查看coredump文件信息,定位coredump产生原因、触发源。
gdb attach pid:调度运行时的进程或线程,同gdb -p pid。
在GDB提示符下输入help或help 命令,能够查看命令的帮助说明。
(gdb) help
List of classes of commands:
aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands
Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
查看调用栈
写一个简单的例子(仅为样例,并不严谨):
#include &stdbool.h&
#include &stdio.h&
#include &unistd.h&
#include &pthread.h&
#include &assert.h&
#include &sys/prctl.h&
typedef struct {
int member_a;
int member_b;
char *g_str[] = {
"Hello, GDB!",
"It's funny."
void stay_here(int arg, test_t *test)
local = 100;
while (true) {
if (local % 200 == 0) {
local = 0;
void *thread_process(void *arg)
char name[64];
in = (int)
(void)snprintf(name, 64, "test-%d", in + 1);
prctl(PR_SET_NAME, (unsigned long)name);
/* set thread name */
while (true) {
return NULL;
void create_thread(void)
for (i = 0; i & 5; i++) {
rv = pthread_create(&tid, NULL, thread_process, (void *)i);
assert(rv == 0);
int main(int argc, char **argv)
local = 999;
test.member_a = 10;
test.member_b = 11;
create_thread();
stay_here(local, &test);
编译并运行起来,注意gcc的-g选项,这里使用&让程序运行到后台,[1] 8043指刚刚这个程序运行时的进程号,也可用ps命令查看。
sunnogo@a3e420:~/test/gdb$ gcc -o prt_mod_var prt_mod_var.c -g -Wall -lpthread
sunnogo@a3e420:~/test/gdb$
sunnogo@a3e420:~/test/gdb$ ls
prt_mod_var
prt_mod_var.c
sunnogo@a3e420:~/test/gdb$ ./prt_mod_var &
sunnogo@a3e420:~/test/gdb$
sunnogo@a3e420:~/test/gdb$ ps -e | grep prt_mod_var
8043 pts/1
00:00:00 prt_mod_var
接下来使用gdb -p 8043连入正在运行的进程中。还不明白为什么我的计算机中要求使用root权限才能让GDB attach到对应进程。
sunnogo@a3e420:~/test/gdb$ gdb -p 8043
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
&http://www.gnu.org/software/gdb/bugs/&.
Attaching to process 8043
Could not attach to process.
If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user.
For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
(gdb) quit
重新sudo gdb -p pid进入进程。
使用bt查看当前调用栈信息(call stack,即函数调用层次信息),当前进程的是由main() -& sleep() -& nanosleep() -& __kernel_vsyscall()一层一层调入。注意“#数字”,在GDB中这叫stack frames,或直接称为frame,运行栈由一个或多个连续的frame组成,数字越小代表调用层次越深。
使用bt full查看详细调用栈信息,会把各个frame的入参和局部变量信息显示出来。这里bt是backtrace的缩写,GDB的全命令经常有其简短的写法。
注意:GDB中,按回车默认是执行上一次命令。先MARK下面的“No symbol table info available.”
sunnogo@a3e420:~/test/gdb$ sudo gdb -p 8043
[sudo] password for sunnogo:
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
&http://www.gnu.org/software/gdb/bugs/&.
Attaching to process 8043
Reading symbols from /home/sunnogo/test/gdb/prt_mod_var...done.
Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0xb7751424 in __kernel_vsyscall ()
0xb7751424 in __kernel_vsyscall ()
0xb7640ce0 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
0xb7640aff in sleep () from /lib/i386-linux-gnu/libc.so.6
0x0804845b in stay_here (arg=999, test=0xbf8e5118) at prt_mod_var.c:26
0x in main (argc=1, argv=0xbf8e51c4) at prt_mod_var.c:41
(gdb) bt full
0xb7751424 in __kernel_vsyscall ()
No symbol table info available.
0xb7640ce0 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
0xb7640aff in sleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
0x0804845b in stay_here (arg=999, test=0xbf8e5118) at prt_mod_var.c:26
local = 113
0x in main (argc=1, argv=0xbf8e51c4) at prt_mod_var.c:41
local = 999
test = {member_a = 10, member_b = 11}
使用frame n进入“#n”的frame。默认显示当前函数名、函数入参、当前运行处所在源文件的代码行位置,并显示当前行代码。
使用info命令查看frame详细信息,info命令不是全命令,后面还有子命令。info有很多子命令,除本frame外,还可以查看本进程信息、系统信息,这里仅仅是冰山一角。
info frame 显示当前frame信息
info args 显示入参信息
info local 显示局部变量信息
(gdb) frame 3
0x0804845b in stay_here (arg=999, test=0xbf8e5118) at prt_mod_var.c:26
(gdb) info frame
Stack level 3, frame at 0xbf8e5100:
eip = 0x804845b in stay_here (prt_mod_var.c:26); saved eip 0x8048492
called by frame at 0xbf8e5130, caller of frame at 0xbf8e50d0
source language c.
Arglist at 0xbf8e50f8, args: arg=999, test=0xbf8e5118
Locals at 0xbf8e50f8, Previous frame's sp is 0xbf8e5100
Saved registers:
ebx at 0xbf8e50f4, ebp at 0xbf8e50f8, eip at 0xbf8e50fc
(gdb) info args
test = 0xbf8e5118
(gdb) info local
local = 113
查看、修改变量
p var查看变量信息,p是print的缩写。
p *(指针类型)地址
p *结构体指针
# 打印变量
(gdb) p g_int
(gdb) p g_bool
$4 = false
# 打印特定类型指针
(gdb) info local
local = 113
(gdb) p &local
$11 = (int *) 0xbf8e50ec
(gdb) p *(int *) 0xbf8e50ec
# 打印结构体指针
(gdb) p test
$1 = (test_t *) 0xbf8e5118
(gdb) p *test
$2 = {member_a = 10, member_b = 11}
# 打印数组名
(gdb) p g_str
$5 = {0x8048538 "Hello, GDB!", 0x8048544 "It's funny."}
(gdb) p g_str[0]
$6 = 0x8048538 "Hello, GDB!"
print不仅可以用来查看变量,还可用于设置变量。print var=value。设置变量值的命令还有set,set var=value。
(gdb) print local
(gdb) print local=20
(gdb) print local
(gdb) set local=30
(gdb) print local
# set bool
(gdb) print g_bool
$5 = false
(gdb) set g_bool=true
No symbol "true" in current context.
(gdb) set g_bool=1
(gdb) print g_bool
# set pointer
(gdb) print g_str
$7 = {0x8048538 "Hello, GDB!", 0x8048544 "It's funny."}
(gdb) set g_str[0]="SETTING VAR"
(gdb) print g_str
$8 = {0x8e05008 "SETTING VAR", 0x8048544 "It's funny."}
examine查看内存,缩写是x。命令格式:
x/&n/f/u& &addr&
n、f、u是可选参数,说明如下:
(gdb) help x
Examine memory: x/FMT ADDRESS.
ADDRESS is an expression for the memory address to examine.
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format.
Defaults for format and size letters are those previously used.
Default count is 1.
Default address is following last thing printed
with this command or "print".
n表示要打印的多少个单位的内存,默认是1,单位由u定义;
f表示打印的格式,格式有:
o,octal,八进制;
x,hex,十六进制;
d,decimal,十进制;
u,unsigned decimal,无符号十进制;
t,binary,二进制;
f,float;
a,address;
i,instruction,指令;
c,char,字符;
s,string,字符串。
u定义单位,b表示1字节,h表示2字节,w表示4字节,g表示8字节。
# 当前CPU是intel i3,小端
# 以十进制形式打印
(gdb) x/8db test
0xbf8e5118:
(gdb) x/4dh test
0xbf8e5118:
(gdb) x/2dw test
0xbf8e5118:
(gdb) x/2d test
0xbf8e5118:
(gdb) x/1dg test
0xbf8e5118:
# 注意和x/1xg test的结果比较
# 以二进制形式打印
(gdb) x/1tg test
0xbf8e5118:
(gdb) x/2tw test
0xbf8e5118:
(gdb) x/4th test
0xbf8e5118:
(gdb) x/8tb test
0xbf8e5118:
# 以十六进制形式打印
(gdb) x/8xb test
0xbf8e5118:
(gdb) x/4xh test
0xbf8e5118:
(gdb) x/2xw test
0xbf8e5118:
0x0000000a
0x0000000b
(gdb) x/1xg test
0xbf8e5118:
# 打印字符或字符串
(gdb) x/30cb g_str[0]
0x8048538:
101 'e' 108 'l' 108 'l' 111 'o' 44 ','
0x8048540:
116 't' 39 '\'' 115 's'
0x8048548:
102 'f' 117 'u' 110 'n' 110 'n' 121 'y' 46 '.'
0x8048550:
(gdb) x/s g_str[0]
0x8048538:
"Hello, GDB!"
查看线程信息
有两种方法可以进入线程调试:
设置线程名,用ps查看母进程的线程信息,获取tid,再启动GDB进入;
直接启动GDB调试母进程,info thread查看所有线程信息,获取到想要的线程的GDB内部编号n,thread n进入线程的调用栈。
直接获取、调试线程
上面样例中创建5条线程,并使用prctl函数为每条线程命名为"test-n"。这样可以通过ps -eL | grep test(或者test进程的pid)来查看刚创建的线程的tid。然后gdb -p tid进入线程调度。这里进入编号为4的线程。
sunnogo@a3e420:~/test/gdb$ gcc -o test test.c -g -Wall -lpthread
sunnogo@a3e420:~/test/gdb$ ./test &
sunnogo@a3e420:~/test/gdb$ ps -eL | grep test
00:00:00 test
00:00:00 test-1
00:00:00 test-2
00:00:00 test-3
00:00:00 test-4
00:00:00 test-5
sunnogo@a3e420:~/test/gdb$ sudo gdb -p 16431
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
&http://www.gnu.org/software/gdb/bugs/&.
Attaching to process 16431
warning: process 16431 is a cloned process
Reading symbols from /home/sunnogo/test/gdb/test...done.
Reading symbols from /lib/i386-linux-gnu/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Loaded symbols for /lib/i386-linux-gnu/libpthread.so.0
Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0xb774f424 in __kernel_vsyscall ()
(gdb) bt full
0xb774f424 in __kernel_vsyscall ()
No symbol table info available.
0xb7623d06 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
0xb7623aff in sleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
0x080485ee in thread_process (arg=0x3) at test.c:46
name = "test-4", '\000' &repeats 57 times&
0xb771cd4c in start_thread () from /lib/i386-linux-gnu/libpthread.so.0
No symbol table info available.
0xb765abae in clone () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
间接获取、调试线程
注意和上一种方法的对比,相比起来,第一种方法要方便得多。也从侧面看出为每个线程命名的重要性。
sunnogo@a3e420:~/test/gdb$
nnogo@a3e420:~/test/gdb$ sudo gdb attach 16427
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
&http://www.gnu.org/software/gdb/bugs/&...
attach: No such file or directory.
Attaching to process 16427
Reading symbols from /home/sunnogo/test/gdb/test...done.
Reading symbols from /lib/i386-linux-gnu/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 16432]
[New LWP 16431]
[New LWP 16430]
[New LWP 16429]
[New LWP 16428]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Loaded symbols for /lib/i386-linux-gnu/libpthread.so.0
Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0xb774f424 in __kernel_vsyscall ()
(gdb) info thread
Thread 0xb7568b40 (LWP 16428) "test-1" 0xb774f424 in __kernel_vsyscall ()
Thread 0xb6d67b40 (LWP 16429) "test-2" 0xb774f424 in __kernel_vsyscall ()
Thread 0xb6566b40 (LWP 16430) "test-3" 0xb774f424 in __kernel_vsyscall ()
Thread 0xb5d65b40 (LWP 16431) "test-4" 0xb774f424 in __kernel_vsyscall ()
Thread 0xb5564b40 (LWP 16432) "test-5" 0xb774f424 in __kernel_vsyscall ()
Thread 0xb75696c0 (LWP 16427) "test" 0xb774f424 in __kernel_vsyscall ()
(gdb) thread 3
[Switching to thread 3 (Thread 0xb5d65b40 (LWP 16431))]
0xb774f424 in __kernel_vsyscall ()
(gdb) bt full
0xb774f424 in __kernel_vsyscall ()
No symbol table info available.
0xb7623d06 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
0xb7623aff in sleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
0x080485ee in thread_process (arg=0x3) at test.c:46
name = "test-4", '\000' &repeats 57 times&
0xb771cd4c in start_thread () from /lib/i386-linux-gnu/libpthread.so.0
No symbol table info available.
0xb765abae in clone () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
A debugging session is active.
Inferior 1 [process 16427] will be detached.
Quit anyway? (y or n) y
Detaching from program: /home/sunnogo/test/gdb/test, process 16427
sunnogo@a3e420:~/test/gdb$
sunnogo@a3e420:~/test/gdb$
gdb中调用调用函数
call func_name(param1, param2, ...),目前还没有明白如果参数是结构体要怎么整。注意,只能在进程上下文中才能使用,coredump中无法使用。
gdb中申请内存
p malloc(size),结果会返回一个指针,即可正常使用这个指针。注意,只能在进程上下文中才能使用,coredump中无法使用。如下例:
(gdb) p malloc(4)
[New Thread 0x693ff460 (LWP 2033)]
[Switching to Thread 0xb6101000 (LWP 1456)]
$1 = (void *) 0xb58d01e0
&----使用这个返回的指针。
查看寄存器信息
GCC选项对GDB的影响
GCC -g选项的影响
注意上面的,如果gcc编译的时候不加-g选项,那么frame 3也会显示“No symbol table info available.”,无符号表信息可用,全局变量g_str也打不出来。
(gdb) bt full
0xb77a3424 in __kernel_vsyscall ()
No symbol table info available.
0xb7692ce0 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
0xb7692aff in sleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
0x in main ()
No symbol table info available.
(gdb) p g_str
(gdb) p g_str[0]
cannot subscript something of type `&data variable, no debug info&'
(gdb) p g_bool
GCC -fomit-frame-pointer选项的影响

我要回帖

更多关于 gdb 跟踪子进程 的文章

 

随机推荐