每天学点GDB(一)

<一>简单示例——Hello World

在Linux环境下进行C或是C++编程,调试工具首选GDB。

GDB的功能很多,一下子全弄明白似乎不太可能。那么就从最简单的使用说起吧。一谈起简单,Helloworld就成了最佳的选择了。

#include <stdio.h>
#include <stdlib.h>
4 int main(int argc, char** argv) {
    printf("hello,world\n");
    return 0;
}

编译链接

gcc -o hello -g helloworld.c

 好了,现在可执行目标文件hello已经生成,接下来的事情就是用gdb将其载入并运行。

gdb ./hello

接下来的会看到如下的信息。

gdb hello

GNU gdb (GDB) 7.5.1

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 "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/hello...done.

(gdb)

显示源代码

(gdb)list 1,10

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
    printf("hello,world\n");
    return 0;
}

设置断点有多种方法,如通过函数名,通过指定源码行数,下面的例子通过指定文件中的行数来设置断点

(gdb)break 7

运行程序

(gdb)run

当检查完相关的变量后,继续运行程序

(gdb)continue

最终,退出gdb

(gdb)quit

ok,重新回到bash shell.

至此一个简单的调试例子完整的过了一遍,是的,平淡的如白开水一般。

<二>如何让GDB在断点处打印一下诊断信息

在一中提到GDB最最基本的用法,在本节主要讲述一下如何让GDB在断点处打印一下诊断信息,但程序执行本身不会中断。

先稍微改一改源程序

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
  int i = 0;
  printf("hello,world\n");
  for ( i = 0; i < 20; i++ ) {
    printf("now, the seq is %d\n",i);
  }
  return 0;
}

假设要在执行期间查看i值的变化。如果是step by step的办法,具体步骤如下。

设置断点

gdb)break 8

执行程序

gdb)run

在断点处停止执行,执行如下指令显示i的值

gdb)p i

继续程序执行

gdb)continue

上述步骤会一直重复出现,如果想一次性设定后,让程序执行不因断点设置而中断,可采用下述办法。

gdb)commands

Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>p i
>conti
>end

输入end表示在断点处的批处理结束,再次回到gdb。

p i 表示指印i的值

conti 表示继续程序执行

gdb)run

这样每次在断点处会自动打印变量i的值,并继续执行剩下的程序。

时间: 2024-12-27 13:40:00

每天学点GDB(一)的相关文章

每天学点GDB(六)

<一>如何利用gdb对coredump进行分析 本篇主要讲解如何利用gdb对coredump进行分析 gdb ./demo core 查看调用堆栈 gdb)bt 查看更为完整的信息 gdb) bt full 如果是多线程,想看每个线程的调用堆栈 gdb) thread apply all bt 至于如何分析内存变量之类的,在本一系列前面的章节有专门论述,可以参考. 想调试已经在运行的程序 gdb ./demo 假设当前运行着的demo进程为1234,则在gdb中运行attach进行关联 gdb

每天学点GDB(五)

使用GDB来进行STL容器的调试 现代C++中STL使用的越来越普遍,较之其它类型,stl容器类的调试显得复杂度更好.本篇以map为例说明如何利用gdb来遍历map中的各成员变量. 源码如下: #include <map> #include <iostream> #include <string> using namespace std; int main(int arg, char** argv) { map<int, string> mapExample

每天学点GDB(二)

<一>如何让将调试的内容保存到外部文件里面 在上一篇提及如何在断点处打印调试信息后,程序自动继续执行.本节主要讲述如何让将调试的内容保存到外部文件里面. 默认情况下,日志是没有打开的,所有的调试信息都会在屏幕中显示,即默认是输出到stdout中的.那么有没有可能将输出到屏幕中的内容保存到文件里呢.答案自然是肯定的,这里面有个地方遇要注意一下子,具体会在下面的示例中提及. 将日志文件打开,不指定文件名的话,默认的文件名是gdb.txt. gdb)set logging on 查看更多有关logg

每天学点GDB(三)

<一>强大的反汇编能力 GDB提供了强大的反汇编能力,本节就围绕于该主题而展开. 继续以Hello.c为例. 1 2 3 4 5 6 7 #include <stdlib.h> #include <stdio.h>   int main(int argc, char** argv) {   printf("hello,world\n");   return 0; } 编译生成可执行文件 gcc -o hello -g hello.c 用gdb载入进行

每天学点GDB(四)

使用GDB进行多线程调试,查看互斥变量. 演示源码如下: #include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> static void* thread_func(void* args); pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; int sum = 0; #define MAX_NUM 10

每天学点GDB(八)

<一>A really simple tracing debugger 在上一篇文章中讲到了ptrace,那么我们完全可以用ptrace来写一个非常简单的trace工具,用以trace程序的具体运行过程. 用它可以很清楚的回答,使用glibc编译后的hello world是从什么地方开始运行的. (注:本文内容根据"A really simple tracing debugger"翻译而来,具体链接见参考资料一节) itrace.c #include <stdio.h

每天学点GDB(七)

近两周在做一个trouble shooting,需要对函数调用栈进行分析以找出入参和局部变量.因为在编译生成可执行程序的时候,用gcc进行了O2的优化,许多假设的函数调用栈模型都不成立了.花了一番周折,终于正确的翻译出入参和局部变量,此一旅程中的一些经验还是值得记录下来. 在32位x86系统上,函数调用栈的布局如下图所示. 栈底在高地址段,栈顶在低地址段. 从栈底到栈顶的内容分别为: 函数入参 返回地址 保存的寄存器值 被调用函数的局部变量 如果带有调试信息,则要获取上述4个部分的值很容易,对应

统计学生成绩的c,编译没报错,运行错误

问题描述 统计学生成绩的c,编译没报错,运行错误 #include /*这是一个查询学生成绩的程序,查询数学,英语,语文,计算并算出总成绩*/ /*首先,显示输入学生人数,然后显示输入各科成绩,最后按照学号排序输出各科 成绩.最后计算并显示出各科成绩的平均值,最大值,最小值*/ /*在main函数中既有printf1函数,scanf函数,printf2函数,arg函数,min函数 max函数*/ void input(double s[][4],int n); void output(doubl

一步一步学ROP之linux_x86篇

一步一步学ROP之linux_x86篇 作者:蒸米@阿里聚安全 一.序 ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等).虽然现在大家都在用64位的操作系统,但是想要扎实的学好ROP还是得从基础的x86系统开始,但看官请不要着急,在随后的教程中我们还会带来linux_x64以及android (arm)方面的ROP利用方法,欢迎大家继续学习. 小编备注:文中涉及代