首页 > 系统相关 >Linux下的gdb日常使用

Linux下的gdb日常使用

时间:2024-08-15 16:58:36浏览次数:9  
标签:x86 lib gnu linux gdb 64 日常 Linux Yes

100个GDB小技巧

0. 常用

0.1 获取源代码行与程序地址之间的对应关系

(1)显示当前执行指令所在的源代码行:

info line

(2)显示特定函数或源代码行的地址信息:

info line <function-name> | <source-file>:<line-number>

例如,要查看函数myFunction的起始地址,可以使用:

info line myFunction

或者要查看文件myfile.cpp中的第10行对应的地址,可以使用:

info line myfile.cpp:10

(3)显示包含特定地址的源代码行信息:

info line *<address>

例如,要查看地址0x400567所在的源代码行,可以使用:

info line *0x400567

0.2 查看C++对象的虚函数表

在GDB中,info vtbl命令用于查看C++对象的虚函数表(Virtual Table,简称vtable)信息。虚函数表是一个数据结构,它包含了类的所有虚函数的地址。这个命令对于调试涉及多态性和虚函数调用的问题非常有用。

pwndbg> info vtbl cat_object
vtable for 'Cat' @ 0x555555557d10 (subobject @ 0x7fffffffe910):
[0]: 0x55555555536c <Cat::speak()>
[1]: 0x555555555330 <Animal::run()>
pwndbg> info vtbl dog_object
vtable for 'Dog' @ 0x555555557cf0 (subobject @ 0x7fffffffe918):
[0]: 0x5555555552f4 <Animal::speak()>
[1]: 0x5555555553a8 <Dog::run()>

0.3 反汇编指定的函数或内存地址范围

(1)反汇编特定函数:

disassemble <function-name>

这里,<function-name>是你想要反汇编的函数的名称。这将显示该函数的机器指令。

(2)反汇编当前程序停止执行的位置周围的代码:

disassemble

如果不提供任何参数,GDB将默认反汇编当前程序计数器(Program Counter,PC)指向的指令及其周围的代码。

(3)反汇编特定内存地址范围内的指令:

disassemble <start-address> , <end-address>

这里,<start-address><end-address>是你想要反汇编的内存地址范围的开始和结束地址。

(4)显示指定数量的指令:

disassemble <address> , +<count>

这里,<address>是起始地址,<count>是要显示的指令数量。

例如,如果你想反汇编从地址0x55555555536c开始的10条指令,可以使用以下命令:

disassemble 0x55555555536c , +10

(5)查看当前函数的反汇编输出

disassemble /m

0.4 打印多个变量的值

对于局部变量和全局变量的查看:

  • 查看全局变量和静态变量:info variables
  • 查看当前栈帧中的局部变量:info locals

如果想在特定函数上下文查看全局变量或者其他函数内部的变量,则可能需要切换到对应的栈帧(使用 framef 命令)后再进行操作。

1. 信息显示

1.1 显示gdb版本信息

show version

1.2 显示gdb版权相关信息

show copying

1.3 启动时不显示提示信息

gdb -q

2. 函数

2.1 列出函数的名字

命令:

info functions

示例:

#include<stdio.h>
#include<stdlib.h>

int add(int a, int b) {
    return a + b;
}

int sum(int a, int b) {
    return a - b;
}

int main()
{
    int a = 10;
    int b =3;
    int c = add(a, b);
    int d = sum(a, b);
}
pwndbg> info functions
All defined functions:

File test1.c:
4:	int add(int, int);
12:	int main();
8:	int sum(int, int);

Non-debugging symbols:
0x0000000000001000  _init
0x0000000000001030  __cxa_finalize@plt
0x0000000000001040  _start
0x0000000000001070  deregister_tm_clones
0x00000000000010a0  register_tm_clones
0x00000000000010e0  __do_global_dtors_aux
0x0000000000001120  frame_dummy
0x00000000000011a0  __libc_csu_init
0x0000000000001210  __libc_csu_fini
0x0000000000001218  _fini
pwndbg>

2.2 退出正在调试的函数

命令:

finish

2.3 打印函数堆栈帧信息

打印函数栈帧:

i frame

打印寄存器信息:

i registers

展示函数汇编代码:

disassemble func

示例:

#include<stdio.h>
#include<stdlib.h>

int func(void) {
    int i = 0;
    i += 2;
    i *= 10;
    return i;
}

int main()
{
    func();
    int a = 0;
    int b = 0;
}
pwndbg> i frame
Stack level 0, frame at 0x7fffffffe960:
 rip = 0x555555555150 in main (test3.c:12); saved rip = 0x7ffff7deb083
 called by frame at 0x7fffffffea30
 source language c.
 Arglist at 0x7fffffffe950, args:
 Locals at 0x7fffffffe950, Previous frame's sp is 0x7fffffffe960
 Saved registers:
  rip at 0x7fffffffe958
pwndbg> i registers
rax            0x555555555150      93824992235856
rbx            0x555555555180      93824992235904
rcx            0x555555555180      93824992235904
rdx            0x7fffffffea58      140737488349784
rsi            0x7fffffffea48      140737488349768
rdi            0x1                 1
rbp            0x7fffffffe950      0x7fffffffe950
rsp            0x7fffffffe940      0x7fffffffe940
r8             0x0                 0
r9             0x7ffff7fe0d60      140737354009952
r10            0xffffffff          4294967295
r11            0x0                 0
r12            0x555555555040      93824992235584
r13            0x7fffffffea40      140737488349760
r14            0x0                 0
r15            0x0                 0
rip            0x55555555515c      0x55555555515c <main+12>
eflags         0x202               [ IF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
pwndbg> disassemble func
Dump of assembler code for function func:
   0x0000555555555129 <+0>:	endbr64
   0x000055555555512d <+4>:	push   rbp
   0x000055555555512e <+5>:	mov    rbp,rsp
   0x0000555555555131 <+8>:	mov    DWORD PTR [rbp-0x4],0x0
   0x0000555555555138 <+15>:	add    DWORD PTR [rbp-0x4],0x2
   0x000055555555513c <+19>:	mov    edx,DWORD PTR [rbp-0x4]
   0x000055555555513f <+22>:	mov    eax,edx
   0x0000555555555141 <+24>:	shl    eax,0x2
   0x0000555555555144 <+27>:	add    eax,edx
   0x0000555555555146 <+29>:	add    eax,eax
   0x0000555555555148 <+31>:	mov    DWORD PTR [rbp-0x4],eax
   0x000055555555514b <+34>:	mov    eax,DWORD PTR [rbp-0x4]
   0x000055555555514e <+37>:	pop    rbp
   0x000055555555514f <+38>:	ret
End of assembler dump.

3. 断点

3.1 在程序地址上打断点

0x55555555518f <main>                 endbr64
0x555555555193 <main+4>               push   rbp
0x555555555194 <main+5>               mov    rbp, rsp
0x555555555197 <main+8>               mov    edi, 4
0x55555555519c <main+13>              call   func3
b *0x55555555519c

3.2 在程序入口处打断点

获取程序入口:

方法一:

ubuntu@niu0217:~/Dev/testGDB$ strip test4
ubuntu@niu0217:~/Dev/testGDB$ readelf -h test4
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1040
  Start of program headers:          64 (bytes into file)
  Start of section headers:          12600 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         27
  Section header string table index: 26
ubuntu@niu0217:~/Dev/testGDB$

得到入口处地址为0x1040

方法二:

pwndbg> info files
Symbols from "/home/ubuntu/Dev/testGDB/test4".
Local exec file:
	`/home/ubuntu/Dev/testGDB/test4', file type elf64-x86-64.
	Entry point: 0x1040
	0x0000000000000318 - 0x0000000000000334 is .interp
	0x0000000000000338 - 0x0000000000000358 is .note.gnu.property
	0x0000000000000358 - 0x000000000000037c is .note.gnu.build-id
	0x000000000000037c - 0x000000000000039c is .note.ABI-tag
	0x00000000000003a0 - 0x00000000000003c4 is .gnu.hash
	0x00000000000003c8 - 0x0000000000000458 is .dynsym
	0x0000000000000458 - 0x00000000000004d5 is .dynstr
	0x00000000000004d6 - 0x00000000000004e2 is .gnu.version
	0x00000000000004e8 - 0x0000000000000508 is .gnu.version_r
	0x0000000000000508 - 0x00000000000005c8 is .rela.dyn
	0x0000000000001000 - 0x000000000000101b is .init
	0x0000000000001020 - 0x0000000000001030 is .plt
	0x0000000000001030 - 0x0000000000001040 is .plt.got
	0x0000000000001040 - 0x0000000000001225 is .text
	0x0000000000001228 - 0x0000000000001235 is .fini
	0x0000000000002000 - 0x0000000000002004 is .rodata
	0x0000000000002004 - 0x0000000000002058 is .eh_frame_hdr
	0x0000000000002058 - 0x00000000000021a8 is .eh_frame
	0x0000000000003df0 - 0x0000000000003df8 is .init_array
	0x0000000000003df8 - 0x0000000000003e00 is .fini_array
	0x0000000000003e00 - 0x0000000000003fc0 is .dynamic
	0x0000000000003fc0 - 0x0000000000004000 is .got
	0x0000000000004000 - 0x0000000000004010 is .data
	0x0000000000004010 - 0x0000000000004018 is .bss

得到入口处地址为:0x1040

在获得的入口处地址打断点:

pwndbg> b *0x1040
Breakpoint 1 at 0x1040

3.3 保存已经设置的断点

将设置的断点保存起来:

save breakpoints file-name-to-save

批量设置保存的断点:

source file-name-to-save

示例:

保存设置的断点:

pwndbg> i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000000118f in main at test4.c:20
2       breakpoint     keep y   0x0000000000001129 in func1 at test4.c:3
3       breakpoint     keep y   0x000000000000113b in func2 at test4.c:7
pwndbg> save breakpoints file-name-to-save
Saved to file 'file-name-to-save'.
pwndbg>

加载:

pwndbg> source file-name-to-save
Breakpoint 1 at 0x118f: file test4.c, line 20.
Breakpoint 2 at 0x1129: file test4.c, line 3.
Breakpoint 3 at 0x113b: file test4.c, line 7.
pwndbg> i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000000118f in main at test4.c:20
2       breakpoint     keep y   0x0000000000001129 in func1 at test4.c:3
3       breakpoint     keep y   0x000000000000113b in func2 at test4.c:7
pwndbg>

3.4 设置临时断点

tb a.c:15

注解:tbreak的简称为tb

临时断点的意思就是下次不会命中了。

3.5 设置条件断点

#include<stdio.h>

int main()
{
    int i;
    int sum = 0;

    for(i = 0; i < 10; i++) {
        sum += i;
    }
    printf("%d\n", sum);
}
pwndbg> b 9 if i==2
Breakpoint 1 at 0x1165: file test5.c, line 9.

3.6 禁用和启用断点

在GDB中,你可以使用以下命令让一个断点暂时失效:

disable breakpoint-number

breakpoint-number 替换为你想要禁用的断点编号。例如,如果你想要禁用编号为1的断点,可以使用以下命令:

disable 1

如果你想一次性禁用所有断点,可以使用:

disable breakpoints

当你想要重新启用一个被禁用的断点时,可以使用 enable 命令:

enable breakpoint-number

或者启用所有断点:

enable breakpoints

请注意,禁用断点并不会删除它,只是使其在当前调试会话中暂时失效。当你重新启用断点后,它将再次生效。

4. 观察点

设置watchpoints:

  • watch expr: 设置写watchpoint,当应用程序写expr, 修改其值时,程序停止运行
  • rwatch expr: 设置读watchpoint,当应用程序读表达式expr时,程序停止运行
  • awatch expr: 设置读写watchpoint, 当应用程序读或者写表达式expr时,程序都会停止运行

info watchpoints:查看当前调试的程序中设置的watchpoints相关信息

4.1 设置观察点

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>

int a = 0;

void* thread1_func(void *p_arg) {
    while(1) {
        a++;
        sleep(10);
    }
}

int main()
{
    pthread_t t1;

    pthread_create(&t1, NULL, thread1_func, "Thread 1");

    sleep(1000);
    return 0;
}
pwndbg> watch a
Hardware watchpoint 1: a
pwndbg> info watchpoints
Num     Type           Disp Enb Address    What
1       hw watchpoint  keep y              a
pwndbg>

4.2 设置读观察点

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>

int a = 0;

void* thread1_func(void *p_arg) {
    while(1) {
        printf("%d\n", a);
        sleep(10);
    }
}

int main()
{
    pthread_t t1;

    pthread_create(&t1, NULL, thread1_func, "Thread 1");

    sleep(1000);
    return 0;
}
pwndbg> rwatch a
Hardware read watchpoint 2: a

注解:

  • rwatch也可以缩写为rw
  • 每次访问a都会让程序停下来,rwatch命令只对硬件观察点才生效

4.3 设置读写观察点

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>

int a = 0;

void* thread1_func(void *p_arg) {
    while(1) {
        a++;
        sleep(10);
    }
}

void* thread2_func(void *p_arg) {
    while(1) {
        printf("%d\n", a);
        sleep(10);
    }
}

int main()
{
    pthread_t t1;
    pthread_t t2;

    pthread_create(&t1, NULL, thread1_func, "Thread 1");
    pthread_create(&t2, NULL, thread2_func, "Thread 2");

    sleep(1000);
    return 0;
}
pwndbg> awatch a
Hardware access (read/write) watchpoint 2: a

注解:

  • awatch可以缩写为aw
  • 每次读取或改变a的值都会让程序停下来

5. Catchpoint

什么是catchpoint

catch event: 当事件event发生的时候,程序停止运行,这里event的取值有:

1)throw: C++抛出异常
2)catch: C++捕捉到异常
3)exec: exec被调用
4)fork: fork被调用
5)vfork: vfork被调用
6)load: 加载动态库
7)load libname: 加载名为libname的动态库
8)unload: 卸载动态库
9)unload libname: 卸载名为libname的动态库
10)syscall [args]: 调用系统调用,args可以指定系统调用号,或者系统名称

tcatch event: 设置只停一次的catchpoint,第一次生效后,该catchpoint被自动删除

5.1 让catchpoint只触发一次

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
    pid_t pid;
    int i = 0;;

    for(; i < 2; i++) {
        pid = fork();
        if(pid < 0) {
            exit(1);
        }
        else if(pid == 0) {
            exit(0);
        }
    }
    printf("Hello world\n");
    return 0;
}
pwndbg> tcatch fork
Catchpoint 2 (fork)
pwndbg> i b
Num     Type           Disp Enb Address            What
2       catchpoint     del  y                      fork

5.2 为fork设置catchpoint

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
    pid_t pid;

    pid = fork();
    if(pid < 0) {
        exit(1);
    }
    else if(pid > 0) {
        exit(0);
    }
    printf("Hello World\n");
}

pwndbg> catch fork
Catchpoint 1 (fork)
pwndbg> i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      fork

5.3 为exec调用设置catchpoint

#include<unistd.h>

int main()
{
    execl("/bin/ls", "ls", NULL);
    return 0;
}
pwndbg> catch exec
Catchpoint 1 (exec)
pwndbg> i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      exec

使用gdb调试程序时,可以用“catch exec”命令为exec系列系统调用设置catchpoint

5.4 为系统调用设置catchpoint

#include<stdio.h>

int main()
{
    char p1[] = "Sam";
    char *p2 = "Bob";

    printf("p1 is %s, p2 is %s\n", p1, p2);
    return 0;
}
pwndbg> catch syscall mmap
Catchpoint 1 (syscall 'mmap' [9])
pwndbg> i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      syscall "mmap"
pwndbg> catch syscall 9
Catchpoint 2 (syscall 'mmap' [9])
pwndbg> i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000555555555169 in main at test11.c:4
	breakpoint already hit 1 time
2       catchpoint     keep y                      syscall "mmap"

使用gdb调试程序时,可以使用catch syscall [name | number]为关注的系统调用设置catchpoint

5.5 通过为ptrace调用设置catchpoint破解anti-debugging的程序

#include <sys/ptrace.h>
#include <stdio.h>

int main()
{
    if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0 ) {
            printf("Gdb is debugging me, exit.\n");
            return 1;
    }
    printf("No debugger, continuing\n");
    return 0;
}
pwndbg> catch syscall ptrace
Catchpoint 1 (syscall 'ptrace' [101])
pwndbg> i b
Num     Type           Disp Enb Address            What
1       catchpoint     keep y                      syscall "ptrace"
pwndbg> r
Starting program: /home/ubuntu/Dev/testGDB/test12

Catchpoint 1 (call to syscall ptrace), ptrace (request=PTRACE_TRACEME) at ../sysdeps/unix/sysv/linux/ptrace.c:45
45	../sysdeps/unix/sysv/linux/ptrace.c: No such file or directory.

pwndbg> c
Continuing.

Catchpoint 1 (returned from syscall ptrace), ptrace (request=PTRACE_TRACEME) at ../sysdeps/unix/sysv/linux/ptrace.c:45
45	in ../sysdeps/unix/sysv/linux/ptrace.c

pwndbg> set $rax = 0
pwndbg> c
Continuing.
No debugger, continuing
[Inferior 1 (process 1835002) exited normally]

通过修改rax寄存器的值,达到修改返回值的目的,从而让gdb可以继续调试程序(打印“No debugger, continuing”)。

6. 打印

6.1 打印ASCII和宽字符字符串

x/s str1
x/ws str2

6.2 打印大数组中的内容

#include<iostream>

int main()
{
  int array[201];
  int i;

  for (i = 0; i < 201; i++)
    array[i] = i;

  return 0;
}
pwndbg> p *array@10
$2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
#设置最大限制
pwndbg> set print elements 10
pwndbg> p array
$3 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9...}
pwndbg>

6.3 打印数组中任意连续元素值

#include<iostream>

int main()
{
  int array[201];
  int i;

  for (i = 0; i < 201; i++)
    array[i] = i;

  return 0;
}
#打印60~69号元素
pwndbg> p array[60]@10
$1 = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69}
#打印0~9号元素
pwndbg> p *array@10
$2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

在gdb中,如果要打印数组中任意连续元素的值,可以使用“p array[index]@num”命令(pprint命令的缩写)。其中index是数组索引(从0开始计数),num是连续多少个元素

6.4 打印数组的索引下标

#include<stdio.h>
#include<iostream>

int num[10] = {
  1 << 0,
  1 << 1,
  1 << 2,
  1 << 3,
  1 << 4,
  1 << 5,
  1 << 6,
  1 << 7,
  1 << 8,
  1 << 9
};

int main (void)
{
  int i;

  for (i = 0; i < 10; i++)
    printf ("num[%d] = %d\n", i, num[i]);

  return 0;
}
pwndbg> p num
$1 = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}
pwndbg> set print array-indexes on
pwndbg> p num
$2 = {[0] = 1, [1] = 2, [2] = 4, [3] = 8, [4] = 16, [5] = 32, [6] = 64, [7] = 128, [8] = 256, [9] = 512}
pwndbg>

在gdb中默认不打印下标,我们可以通过命令set print array-indexes on,来让其打印下标。

6.5 打印函数局部变量的值

#include<stdio.h>
#include<iostream>

void fun_a(void)
{
    int a = 0;
    printf("%d\n", a);
}

void fun_b(void)
{
    int b = 1;
    fun_a();
    printf("%d\n", b);
}

void fun_c(void)
{
    int c = 2;
    fun_b();
    printf("%d\n", c);
}

void fun_d(void)
{
    int d = 3;
    fun_c();
    printf("%d\n", d);
}

int main(void)
{
    int var = -1;
    fun_d();
    return 0;
}
pwndbg> bt
#0  fun_a () at test16.cpp:5
#1  0x00005555555551cd in fun_b () at test16.cpp:13
#2  0x00005555555551fe in fun_c () at test16.cpp:20
#3  0x000055555555522f in fun_d () at test16.cpp:27
#4  0x0000555555555260 in main () at test16.cpp:34
#5  0x00007ffff7c09083 in __libc_start_main (main=0x555555555248 <main()>, argc=1, argv=0x7fffffffea48, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffea38) at ../csu/libc-start.c:308
#6  0x00005555555550ce in _start ()

显示各个函数的局部变量值:

pwndbg> bt full
#0  fun_a () at test16.cpp:5
        a = 21845
#1  0x00005555555551cd in fun_b () at test16.cpp:13
        b = 1
#2  0x00005555555551fe in fun_c () at test16.cpp:20
        c = 2
#3  0x000055555555522f in fun_d () at test16.cpp:27
        d = 3
#4  0x0000555555555260 in main () at test16.cpp:34
        var = -1
#5  0x00007ffff7c09083 in __libc_start_main (main=0x555555555248 <main()>, argc=1, argv=0x7fffffffea48, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffea38) at ../csu/libc-start.c:308
        self = <optimized out>
        result = <optimized out>
        unwind_buf = {
          cancel_jmp_buf = {{
              jmp_buf = {93824992236240, 7416317012288219881, 93824992235680, 140737488349760, 0, 0, -7416317013009618199, -7416335093455770903},
              mask_was_saved = 0
            }},
          priv = {
            pad = {0x0, 0x0, 0x1, 0x7fffffffea48},
            data = {
              prev = 0x0,
              cleanup = 0x0,
              canceltype = 1
            }
          }
        }
        not_first_call = <optimized out>
#6  0x00005555555550ce in _start ()
No symbol table info available.

从内向外显示n个栈桢,及其局部变量:

pwndbg> bt full 2
#0  fun_a () at test16.cpp:5
        a = 21845
#1  0x00005555555551cd in fun_b () at test16.cpp:13
        b = 1
(More stack frames follow...)

从外向内显示n个栈桢,及其局部变量:

pwndbg> bt full -4
#3  0x000055555555522f in fun_d () at test16.cpp:27
        d = 3
#4  0x0000555555555260 in main () at test16.cpp:34
        var = -1
#5  0x00007ffff7c09083 in __libc_start_main (main=0x555555555248 <main()>, argc=1, argv=0x7fffffffea48, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffea38) at ../csu/libc-start.c:308
        self = <optimized out>
        result = <optimized out>
        unwind_buf = {
          cancel_jmp_buf = {{
              jmp_buf = {93824992236240, 7416317012288219881, 93824992235680, 140737488349760, 0, 0, -7416317013009618199, -7416335093455770903},
              mask_was_saved = 0
            }},
          priv = {
            pad = {0x0, 0x0, 0x1, 0x7fffffffea48},
            data = {
              prev = 0x0,
              cleanup = 0x0,
              canceltype = 1
            }
          }
        }
        not_first_call = <optimized out>
#6  0x00005555555550ce in _start ()
No symbol table info available.

打印当前函数局部变量的值:

pwndbg> info locals
a = 21845

6.6 打印进程内存信息

查看进程的内存映射信息:

pwndbg> i proc mappings
process 1844032
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
      0x555555554000     0x555555555000     0x1000        0x0 /home/ubuntu/Dev/testGDB/test16
      0x555555555000     0x555555556000     0x1000     0x1000 /home/ubuntu/Dev/testGDB/test16
      0x555555556000     0x555555557000     0x1000     0x2000 /home/ubuntu/Dev/testGDB/test16
      0x555555557000     0x555555558000     0x1000     0x2000 /home/ubuntu/Dev/testGDB/test16
      0x555555558000     0x555555559000     0x1000     0x3000 /home/ubuntu/Dev/testGDB/test16
      0x555555559000     0x55555557a000    0x21000        0x0 [heap]
      0x7ffff7a77000     0x7ffff7a7b000     0x4000        0x0
      0x7ffff7a7b000     0x7ffff7a7e000     0x3000        0x0 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7a7e000     0x7ffff7a90000    0x12000     0x3000 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7a90000     0x7ffff7a94000     0x4000    0x15000 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7a94000     0x7ffff7a95000     0x1000    0x18000 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7a95000     0x7ffff7a96000     0x1000    0x19000 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7a96000     0x7ffff7aa3000     0xd000        0x0 /usr/lib/x86_64-linux-gnu/libm-2.31.so
      0x7ffff7aa3000     0x7ffff7b4a000    0xa7000     0xd000 /usr/lib/x86_64-linux-gnu/libm-2.31.so
      0x7ffff7b4a000     0x7ffff7be3000    0x99000    0xb4000 /usr/lib/x86_64-linux-gnu/libm-2.31.so
      0x7ffff7be3000     0x7ffff7be4000     0x1000   0x14c000 /usr/lib/x86_64-linux-gnu/libm-2.31.so
      0x7ffff7be4000     0x7ffff7be5000     0x1000   0x14d000 /usr/lib/x86_64-linux-gnu/libm-2.31.so
      0x7ffff7be5000     0x7ffff7c07000    0x22000        0x0 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7c07000     0x7ffff7d7f000   0x178000    0x22000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7d7f000     0x7ffff7dcd000    0x4e000   0x19a000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7dcd000     0x7ffff7dd1000     0x4000   0x1e7000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7dd1000     0x7ffff7dd3000     0x2000   0x1eb000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7dd3000     0x7ffff7dd7000     0x4000        0x0
      0x7ffff7dd7000     0x7ffff7e6d000    0x96000        0x0 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
      0x7ffff7e6d000     0x7ffff7f5e000    0xf1000    0x96000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
      0x7ffff7f5e000     0x7ffff7fa7000    0x49000   0x187000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
      0x7ffff7fa7000     0x7ffff7fa8000     0x1000   0x1d0000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
      0x7ffff7fa8000     0x7ffff7fb3000     0xb000   0x1d0000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
      0x7ffff7fb3000     0x7ffff7fb6000     0x3000   0x1db000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
      0x7ffff7fb6000     0x7ffff7fbb000     0x5000        0x0
      0x7ffff7fcb000     0x7ffff7fce000     0x3000        0x0 [vvar]
      0x7ffff7fce000     0x7ffff7fcf000     0x1000        0x0 [vdso]
      0x7ffff7fcf000     0x7ffff7fd0000     0x1000        0x0 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7fd0000     0x7ffff7ff3000    0x23000     0x1000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7ff3000     0x7ffff7ffb000     0x8000    0x24000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7ffc000     0x7ffff7ffd000     0x1000    0x2c000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7ffd000     0x7ffff7ffe000     0x1000    0x2d000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0
      0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]
  0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]
pwndbg>

更详细地输出进程的内存信息,包括引用的动态链接库:

pwndbg> i files
Symbols from "/home/ubuntu/Dev/testGDB/test16".
Native process:
	Using the running image of child process 1844032.
	While running this, GDB does not access memory from...
Local exec file:
	`/home/ubuntu/Dev/testGDB/test16', file type elf64-x86-64.
	Entry point: 0x5555555550a0
	0x0000555555554318 - 0x0000555555554334 is .interp
	0x0000555555554338 - 0x0000555555554358 is .note.gnu.property
	0x0000555555554358 - 0x000055555555437c is .note.gnu.build-id
	0x000055555555437c - 0x000055555555439c is .note.ABI-tag
	0x00005555555543a0 - 0x00005555555543c4 is .gnu.hash
	0x00005555555543c8 - 0x00005555555544b8 is .dynsym
	0x00005555555544b8 - 0x0000555555554594 is .dynstr
	0x0000555555554594 - 0x00005555555545a8 is .gnu.version
	0x00005555555545a8 - 0x00005555555545e8 is .gnu.version_r
	0x00005555555545e8 - 0x00005555555546d8 is .rela.dyn
	0x00005555555546d8 - 0x0000555555554720 is .rela.plt
	0x0000555555555000 - 0x000055555555501b is .init
	0x0000555555555020 - 0x0000555555555060 is .plt
	0x0000555555555060 - 0x0000555555555070 is .plt.got
	0x0000555555555070 - 0x00005555555550a0 is .plt.sec
	0x00005555555550a0 - 0x0000555555555345 is .text
	0x0000555555555348 - 0x0000555555555355 is .fini
	0x0000555555556000 - 0x0000555555556009 is .rodata
	0x000055555555600c - 0x0000555555556080 is .eh_frame_hdr
	0x0000555555556080 - 0x0000555555556248 is .eh_frame
	0x0000555555557d88 - 0x0000555555557d98 is .init_array
	0x0000555555557d98 - 0x0000555555557da0 is .fini_array
	0x0000555555557da0 - 0x0000555555557fa0 is .dynamic
	0x0000555555557fa0 - 0x0000555555558000 is .got
	0x0000555555558000 - 0x0000555555558010 is .data
	0x0000555555558010 - 0x0000555555558018 is .bss
	0x00007ffff7fcf2a8 - 0x00007ffff7fcf2c8 is .note.gnu.property in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcf2c8 - 0x00007ffff7fcf2ec is .note.gnu.build-id in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcf2f0 - 0x00007ffff7fcf3c4 is .hash in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcf3c8 - 0x00007ffff7fcf4c0 is .gnu.hash in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcf4c0 - 0x00007ffff7fcf7f0 is .dynsym in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcf7f0 - 0x00007ffff7fcfa14 is .dynstr in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcfa14 - 0x00007ffff7fcfa58 is .gnu.version in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcfa58 - 0x00007ffff7fcfafc is .gnu.version_d in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcfb00 - 0x00007ffff7fcff20 is .rela.dyn in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fcff20 - 0x00007ffff7fcffc8 is .rela.plt in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fd0000 - 0x00007ffff7fd0080 is .plt in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fd0080 - 0x00007ffff7fd0090 is .plt.got in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fd0090 - 0x00007ffff7fd0100 is .plt.sec in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fd0100 - 0x00007ffff7ff2684 is .text in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ff3000 - 0x00007ffff7ff7dbb is .rodata in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ff7dbb - 0x00007ffff7ff7dbc is .stapsdt.base in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ff7dbc - 0x00007ffff7ff84e0 is .eh_frame_hdr in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ff84e0 - 0x00007ffff7ffaccc is .eh_frame in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ffc520 - 0x00007ffff7ffce64 is .data.rel.ro in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ffce68 - 0x00007ffff7ffcfd8 is .dynamic in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ffcfd8 - 0x00007ffff7ffcfe8 is .got in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ffd000 - 0x00007ffff7ffd050 is .got.plt in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ffd060 - 0x00007ffff7ffdff8 is .data in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7ffe000 - 0x00007ffff7ffe190 is .bss in /lib64/ld-linux-x86-64.so.2
	0x00007ffff7fce120 - 0x00007ffff7fce164 is .hash in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce168 - 0x00007ffff7fce1b8 is .gnu.hash in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce1b8 - 0x00007ffff7fce2d8 is .dynsym in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce2d8 - 0x00007ffff7fce34a is .dynstr in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce34a - 0x00007ffff7fce362 is .gnu.version in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce368 - 0x00007ffff7fce3a0 is .gnu.version_d in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce3a0 - 0x00007ffff7fce4c0 is .dynamic in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce4c0 - 0x00007ffff7fce514 is .note in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce514 - 0x00007ffff7fce558 is .eh_frame_hdr in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce558 - 0x00007ffff7fce674 is .eh_frame in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce680 - 0x00007ffff7fce9c5 is .text in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fce9c5 - 0x00007ffff7fcea20 is .altinstructions in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7fcea20 - 0x00007ffff7fcea3c is .altinstr_replacement in system-supplied DSO at 0x7ffff7fce000
	0x00007ffff7dd72e0 - 0x00007ffff7dd7300 is .note.gnu.property in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7dd7300 - 0x00007ffff7dd7324 is .note.gnu.build-id in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7dd7328 - 0x00007ffff7ddfedc is .gnu.hash in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7ddfee0 - 0x00007ffff7e034c0 is .dynsym in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e034c0 - 0x00007ffff7e4b0c5 is .dynstr in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e4b0c6 - 0x00007ffff7e4dfee is .gnu.version in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e4dff0 - 0x00007ffff7e4e61c is .gnu.version_d in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e4e620 - 0x00007ffff7e4e760 is .gnu.version_r in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e4e760 - 0x00007ffff7e66b38 is .rela.dyn in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e66b38 - 0x00007ffff7e6cac0 is .rela.plt in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e6d000 - 0x00007ffff7e6d01b is .init in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e6d020 - 0x00007ffff7e70fe0 is .plt in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e70fe0 - 0x00007ffff7e71170 is .plt.got in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e71170 - 0x00007ffff7e75120 is .plt.sec in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7e75120 - 0x00007ffff7f5d332 is .text in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7f5d334 - 0x00007ffff7f5d341 is .fini in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7f5e000 - 0x00007ffff7f672b3 is .rodata in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7f672b3 - 0x00007ffff7f672b4 is .stapsdt.base in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7f672b4 - 0x00007ffff7f705f0 is .eh_frame_hdr in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7f705f0 - 0x00007ffff7f9e8c0 is .eh_frame in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7f9e8c0 - 0x00007ffff7fa6e6b is .gcc_except_table in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fa8978 - 0x00007ffff7fa8998 is .tbss in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fa8978 - 0x00007ffff7fa89d8 is .init_array in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fa89d8 - 0x00007ffff7fa89e0 is .fini_array in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fa89e0 - 0x00007ffff7fb1c68 is .data.rel.ro in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fb1c68 - 0x00007ffff7fb1e88 is .dynamic in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fb1e88 - 0x00007ffff7fb2ff0 is .got in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fb3000 - 0x00007ffff7fb4ff0 is .got.plt in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fb5000 - 0x00007ffff7fb5190 is .data in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7fb51c0 - 0x00007ffff7fb8800 is .bss in /lib/x86_64-linux-gnu/libstdc++.so.6
	0x00007ffff7be5350 - 0x00007ffff7be5370 is .note.gnu.property in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7be5370 - 0x00007ffff7be5394 is .note.gnu.build-id in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7be5394 - 0x00007ffff7be53b4 is .note.ABI-tag in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7be53b8 - 0x00007ffff7be906c is .gnu.hash in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7be9070 - 0x00007ffff7bf6ea0 is .dynsym in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7bf6ea0 - 0x00007ffff7bfcf61 is .dynstr in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7bfcf62 - 0x00007ffff7bfe1e6 is .gnu.version in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7bfe1e8 - 0x00007ffff7bfe658 is .gnu.version_d in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7bfe658 - 0x00007ffff7bfe688 is .gnu.version_r in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7bfe688 - 0x00007ffff7c06080 is .rela.dyn in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7c06080 - 0x00007ffff7c064e8 is .rela.plt in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7c07000 - 0x00007ffff7c07300 is .plt in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7c07300 - 0x00007ffff7c07340 is .plt.got in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7c07340 - 0x00007ffff7c07630 is .plt.sec in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7c07630 - 0x00007ffff7d7c27d is .text in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7d7c280 - 0x00007ffff7d7e624 is __libc_freeres_fn in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7d7f000 - 0x00007ffff7da3698 is .rodata in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7da3698 - 0x00007ffff7da3699 is .stapsdt.base in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7da36a0 - 0x00007ffff7da36bc is .interp in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7da36bc - 0x00007ffff7da9590 is .eh_frame_hdr in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7da9590 - 0x00007ffff7dc89a8 is .eh_frame in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dc89a8 - 0x00007ffff7dc8dcd is .gcc_except_table in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dc8dd0 - 0x00007ffff7dcc2c4 is .hash in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dcd788 - 0x00007ffff7dcd798 is .tdata in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dcd798 - 0x00007ffff7dcd818 is .tbss in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dcd798 - 0x00007ffff7dcd7a8 is .init_array in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dcd7a8 - 0x00007ffff7dcd898 is __libc_subfreeres in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dcd898 - 0x00007ffff7dcd8a0 is __libc_atexit in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dcd8a0 - 0x00007ffff7dce608 is __libc_IO_vtables in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dce620 - 0x00007ffff7dd0b80 is .data.rel.ro in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dd0b80 - 0x00007ffff7dd0d60 is .dynamic in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dd0d60 - 0x00007ffff7dd0ff8 is .got in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dd1000 - 0x00007ffff7dd1190 is .got.plt in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dd11a0 - 0x00007ffff7dd27a0 is .data in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7dd27a0 - 0x00007ffff7dd6660 is .bss in /lib/x86_64-linux-gnu/libc.so.6
	0x00007ffff7a962a8 - 0x00007ffff7a962c8 is .note.gnu.property in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7a962c8 - 0x00007ffff7a962ec is .note.gnu.build-id in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7a962ec - 0x00007ffff7a9630c is .note.ABI-tag in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7a96310 - 0x00007ffff7a987dc is .gnu.hash in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7a987e0 - 0x00007ffff7a9f0e0 is .dynsym in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7a9f0e0 - 0x00007ffff7aa1446 is .dynstr in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa1446 - 0x00007ffff7aa1d06 is .gnu.version in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa1d08 - 0x00007ffff7aa1ecc is .gnu.version_d in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa1ed0 - 0x00007ffff7aa1f30 is .gnu.version_r in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa1f30 - 0x00007ffff7aa2068 is .rela.dyn in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa2068 - 0x00007ffff7aa2308 is .rela.plt in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa3000 - 0x00007ffff7aa301b is .init in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa3020 - 0x00007ffff7aa31f0 is .plt in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa31f0 - 0x00007ffff7aa3200 is .plt.got in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa3200 - 0x00007ffff7aa33c0 is .plt.sec in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7aa33c0 - 0x00007ffff7b49fa8 is .text in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7b49fa8 - 0x00007ffff7b49fb5 is .fini in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7b4a000 - 0x00007ffff7bd58d4 is .rodata in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7bd58d4 - 0x00007ffff7bd58d5 is .stapsdt.base in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7bd58d8 - 0x00007ffff7bd753c is .eh_frame_hdr in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7bd7540 - 0x00007ffff7be09a4 is .eh_frame in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7be09a8 - 0x00007ffff7be2b14 is .hash in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7be3d80 - 0x00007ffff7be3d88 is .init_array in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7be3d88 - 0x00007ffff7be3d90 is .fini_array in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7be3d90 - 0x00007ffff7be3fb0 is .dynamic in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7be3fb0 - 0x00007ffff7be4000 is .got in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7be4000 - 0x00007ffff7be40f8 is .got.plt in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7be40f8 - 0x00007ffff7be4104 is .data in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7be4104 - 0x00007ffff7be4110 is .bss in /lib/x86_64-linux-gnu/libm.so.6
	0x00007ffff7a7b2a8 - 0x00007ffff7a7b2c8 is .note.gnu.property in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7b2c8 - 0x00007ffff7a7b2ec is .note.gnu.build-id in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7b2f0 - 0x00007ffff7a7b7e8 is .gnu.hash in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7b7e8 - 0x00007ffff7a7c808 is .dynsym in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7c808 - 0x00007ffff7a7d0b0 is .dynstr in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7d0b0 - 0x00007ffff7a7d208 is .gnu.version in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7d208 - 0x00007ffff7a7d3cc is .gnu.version_d in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7d3d0 - 0x00007ffff7a7d400 is .gnu.version_r in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7d400 - 0x00007ffff7a7d4f0 is .rela.dyn in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7d4f0 - 0x00007ffff7a7d928 is .rela.plt in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7e000 - 0x00007ffff7a7e01b is .init in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7e020 - 0x00007ffff7a7e300 is .plt in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7e300 - 0x00007ffff7a7e310 is .plt.got in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7e310 - 0x00007ffff7a7e5e0 is .plt.sec in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a7e5e0 - 0x00007ffff7a8f055 is .text in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a8f058 - 0x00007ffff7a8f065 is .fini in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a90000 - 0x00007ffff7a90cbc is .rodata in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a90cbc - 0x00007ffff7a91348 is .eh_frame_hdr in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a91348 - 0x00007ffff7a93364 is .eh_frame in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a94dc8 - 0x00007ffff7a94dd8 is .init_array in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a94dd8 - 0x00007ffff7a94de0 is .fini_array in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a94de0 - 0x00007ffff7a94fd0 is .dynamic in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a94fd0 - 0x00007ffff7a95000 is .got in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a95000 - 0x00007ffff7a95180 is .got.plt in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a95180 - 0x00007ffff7a95190 is .data in /lib/x86_64-linux-gnu/libgcc_s.so.1
	0x00007ffff7a951a0 - 0x00007ffff7a95448 is .bss in /lib/x86_64-linux-gnu/libgcc_s.so.1
pwndbg>

6.7 打印变量的类型和所在文件

#include<stdio.h>

struct child {
  char name[10];
  enum { boy, girl } gender;
};

struct child he = { "Tom", boy };

int main (void)
{
  static struct child she = { "Jerry", girl };
  printf ("Hello %s %s.\n", he.gender == boy ? "boy" : "girl", he.name);
  printf ("Hello %s %s.\n", she.gender == boy ? "boy" : "girl", she.name);
  return 0;
}

查看变量的类型:

pwndbg> whatis he
type = struct child

查看详细的类型信息:

pwndbg> ptype he
type = struct child {
    char name[10];
    enum {boy, girl} gender;
}

查看定义该变量的文件:

pwndbg> i variables ^he$
All variables matching regular expression "^he$":

File test17.c:
8:	struct child he;
pwndbg>

特别注意:需要用到正则表达式,不然会匹配很多he

6.8 打印内存的值

#include <stdio.h>

int main(void)
{
    int i = 0;
    char a[100];

    for (i = 0; i < sizeof(a); i++)
    {
            a[i] = i;
    }

    return 0;
}

gdb中使用“x”命令来打印内存的值,格式为“x/nfu addr”。含义为以f格式打印从addr开始的n个长度单元为u的内存值。参数具体含义如下:
a)n:输出单元的个数。
b)f:是输出格式。比如x是以16进制形式输出,o是以8进制形式输出,等等。
c)u:标明一个单元的长度。b是一个byteh是两个byte(halfword),w是四个byte(word),g是八个byte(giant word)

以16进制格式打印数组前a16个byte的值:

pwndbg> x/16xb a
0x7fffffffe8e0:	0x00	0x01	0x02	0x03	0x04	0x05	0x06	0x07
0x7fffffffe8e8:	0x08	0x09	0x0a	0x0b	0x0c	0x0d	0x0e	0x0f

以无符号10进制格式打印数组a前16个byte的值:

pwndbg> x/16ub a
0x7fffffffe8e0:	0	1	2	3	4	5	6	7
0x7fffffffe8e8:	8	9	10	11	12	13	14	15

以2进制格式打印数组前16个abyte的值::

pwndbg> x/16tb a
0x7fffffffe8e0:	00000000	00000001	00000010	00000011	00000100	00000101	00000110	00000111
0x7fffffffe8e8:	00001000	00001001	00001010	00001011	00001100	00001101	00001110	00001111

以16进制格式打印数组a前16个word(4个byte)的值::

pwndbg> x/16xw a
0x7fffffffe8e0:	0x03020100	0x07060504	0x0b0a0908	0x0f0e0d0c
0x7fffffffe8f0:	0x13121110	0x17161514	0x1b1a1918	0x1f1e1d1c
0x7fffffffe900:	0x23222120	0x27262524	0x2b2a2928	0x2f2e2d2c
0x7fffffffe910:	0x33323130	0x37363534	0x3b3a3938	0x3f3e3d3c

打印指定内存处的10条指令:

x/10i 0x55555555536c

使用x命令查看内存的内容:

  • 形式:x/FMT ADDRESS,其中FMT中三部分组成:count format size(format与size的参数位置可以互换)
  • format:
    • o:octal, 即八进制
    • x:hex, 十六进制
    • d:decimal, 十进制
    • u:unsigned decimal
    • t:binary, 二进制
    • f:float, 符号数
    • a:address, 地址的形式
    • c:char类型
    • s:string
    • z:hes, zero padded on the left
    • i:指令类型
  • size:
    • b:byte, 一个字节大小
    • h:2个字节
    • w:4个字节
    • g:giant, 8个字节

6.9 每行打印一个结构体成员

#include <stdio.h>
#include <pthread.h>

typedef struct
{
    int a;
    int b;
    int c;
    int d;
    pthread_mutex_t mutex;
}ex_st;

int main(void) {
    ex_st st = {1, 2, 3, 4, PTHREAD_MUTEX_INITIALIZER};
    printf("%d,%d,%d,%d\n", st.a, st.b, st.c, st.d);
    return 0;
}

默认情况下,gdb以一种“紧凑”的方式打印结构体。可以执set print pretty on命令,这样每行只会显示结构体的一名成员,而且还会根据成员的定义层次进行缩进:

pwndbg> set print pretty on
pwndbg> p st
$1 = {
  a = 1,
  b = 2,
  c = 3,
  d = 4,
  mutex = {
    __data = {
      __lock = 0,
      __count = 0,
      __owner = 0,
      __nusers = 0,
      __kind = 0,
      __spins = 0,
      __elision = 0,
      __list = {
        __prev = 0x0,
        __next = 0x0
      }
    },
    __size = '\000' <repeats 39 times>,
    __align = 0
  }
}

6.10 按照派生类型打印对象

#include <iostream>
using namespace std;

class Shape {
 public:
  virtual void draw () {}
};

class Circle : public Shape {
 int radius;
 public:
  Circle () { radius = 1; }
  void draw () { cout << "drawing a circle...\n"; }
};

class Square : public Shape {
 int height;
 public:
  Square () { height = 2; }
  void draw () { cout << "drawing a square...\n"; }
};

void drawShape (class Shape &p)
{
  p.draw ();
}

int main (void)
{
  Circle a;
  Square b;
  drawShape (a);
  drawShape (b);
  return 0;
}

在gdb中,当打印一个对象时,缺省是按照声明的类型进行打印:

   23 void drawShape (class Shape &p)
   24 {
 ► 25   p.draw ();
   26 }

pwndbg> p p
$1 = (Shape &) @0x7fffffffe920: {
  _vptr.Shape = 0x555555557d38 <vtable for Circle+16>
}
pwndbg> whatis p
type = Shape &
pwndbg> ptype p
type = class Shape {
  public:
    virtual void draw(void);
} &
pwndbg>

缺省按照派生类型进行打印:

  23 void drawShape (class Shape &p)
   24 {
 ► 25   p.draw ();
   26 }


pwndbg> set print object on
pwndbg> p p
$2 = (Circle &) @0x7fffffffe920: {
  <Shape> = {
    _vptr.Shape = 0x555555557d38 <vtable for Circle+16>
  },
  members of Circle:
  radius = 1
}
pwndbg> whatis p
type = /* real type = Circle & */
Shape &
pwndbg> ptype p
type = /* real type = Circle & */
class Shape {
  public:
    virtual void draw(void);
} &
pwndbg>

6.11 指定程序的输入输出设备

#include <stdio.h>

int main(void)
{
  int i;

  for (i = 0; i < 100; i++)
    {
      printf("i = %d\n", i);
    }

  return 0;
}

在gdb中,缺省情况下程序的输入输出是和gdb使用同一个终端。你也可以为程序指定一个单独的输入输出终端。

首先,打开一个新终端,使用如下命令获得设备文件名:

$ tty
/dev/pts/2

然后,通过命令行选项指定程序的输入输出设备:

$ gdb -tty /dev/pts/2 ./a.out
(gdb) r

或者,在gdb中,使用命令进行设置:

(gdb) tty /dev/pts/2

这样就实现了在一个终端输入,在另一个终端输出。

7. 多进程/线程

7.1 调试已经运行的进程

假设:

  • 运行的程序:hello
  • 进程号:65772

查看运行的程序的进程号:ps -aux | grep hello

切换到root用户:su

此时运行的程序会中断,等待你的调试;如果想要程序继续执行,那就退出gdb调试:gdb hello -p 65772

7.2 调试多进程

调试父进程:set follow-fork-mode parent (默认就是调试父进程)

调试子进程:set follow-fork-mode child

设置调试模式:

  • set detach-on-fork on (默认是on). 表示调试当前进程的时候,其它的进程继续运行
  • set detach-on-fork off。表示调试当前进程的时候,其它的进程被gdb挂起

查看调试的进程:info inferiors

切换当前调试的进程:inferior 进程id

7.3 调试多线程

查看线程:info threads

切换线程:thread 线程id

只运行当前线程:set scheduler-locking on

运行全部的线程:set scheduler-locking off

指定某线程执行某gdb命令:thread apply 线程id cmd

全部的线程执行某gdb命令:thread apply all cmd

8. 调试core

什么是core文件?

  • 在Linux下程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。

命令:

  • ulimit -a:检查生成core文件的选项是否打开
  • ulimit -c unlimited:程序会生成core文件
  • ulimit -c 0:程序不会生成core文件
  • gdb + 可执行程序 + core文件:显示出错的代码
  • sudo bash -c "echo core > /proc/sys/kernel/core_pattern ":指定core文件生成在当前目录下
  • bt:显示调用栈

9. 改变程序的执行

9.1 改变字符串的值

#include <stdio.h>

int main(void)
{
    char p1[] = "Sam";
    char *p2 = "Bob";

    printf("p1 is %s, p2 is %s\n", p1, p2);
    return 0;
}

使用gdb调试程序时,可以用“set”命令改变字符串的值:

pwndbg> set p1="Jil"
pwndbg> set p2="Bill"
pwndbg> p p1
$3 = "Jil"
pwndbg> p p2
$4 = 0x7ffff7fbaf80 "Bill"
pwndbg>

9.2 设置变量的值

在gdb中,可以用“set var variable=expr”命令设置变量的值:

set var i = 8

用“set {type}address=expr”的方式,含义是给存储地址在address,变量类型为type的变量赋值:

set {int}0x8047a54 = 8
set var $eax = 8

10. 信号

10.1 查看信号处理信息

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void handler(int sig);

void handler(int sig)
{
    signal(sig, handler);
    printf("Receive signal: %d\n", sig);
}

int main(void) {
    signal(SIGINT, handler);
    signal(SIGALRM, handler);

    while (1)
    {
        sleep(1);
    }
    return 0;
}

用gdb调试程序时,可以用“i signals”命令(或者“i handle”命令,iinfo命令缩写)查看gdb如何处理进程收到的信号:

pwndbg> i signals
Signal        Stop	Print	Pass to program	Description

SIGHUP        Yes	Yes	Yes		Hangup
SIGINT        Yes	Yes	No		Interrupt
SIGQUIT       Yes	Yes	Yes		Quit
SIGILL        Yes	Yes	Yes		Illegal instruction
SIGTRAP       Yes	Yes	No		Trace/breakpoint trap
SIGABRT       Yes	Yes	Yes		Aborted
SIGEMT        Yes	Yes	Yes		Emulation trap
SIGFPE        Yes	Yes	Yes		Arithmetic exception
SIGKILL       Yes	Yes	Yes		Killed
SIGBUS        Yes	Yes	No		Bus error
SIGSEGV       Yes	Yes	No		Segmentation fault
SIGSYS        Yes	Yes	Yes		Bad system call
SIGPIPE       No	Yes	No		Broken pipe
SIGALRM       No	Yes	No		Alarm clock
SIGTERM       Yes	Yes	Yes		Terminated
SIGURG        No	No	Yes		Urgent I/O condition
SIGSTOP       Yes	Yes	Yes		Stopped (signal)
SIGTSTP       Yes	Yes	Yes		Stopped (user)
SIGCONT       Yes	Yes	Yes		Continued
SIGCHLD       No	No	Yes		Child status changed
SIGTTIN       Yes	Yes	Yes		Stopped (tty input)
SIGTTOU       Yes	Yes	Yes		Stopped (tty output)
SIGIO         No	No	Yes		I/O possible
SIGXCPU       Yes	Yes	Yes		CPU time limit exceeded
SIGXFSZ       Yes	Yes	Yes		File size limit exceeded
SIGVTALRM     No	No	Yes		Virtual timer expired
SIGPROF       No	No	Yes		Profiling timer expired
SIGWINCH      No	No	Yes		Window size changed
SIGLOST       Yes	Yes	Yes		Resource lost
SIGUSR1       Yes	Yes	Yes		User defined signal 1
SIGUSR2       Yes	Yes	Yes		User defined signal 2
SIGPWR        Yes	Yes	Yes		Power fail/restart
SIGPOLL       No	No	Yes		Pollable event occurred
SIGWIND       Yes	Yes	Yes		SIGWIND
SIGPHONE      Yes	Yes	Yes		SIGPHONE
SIGWAITING    No	No	Yes		Process's LWPs are blocked
SIGLWP        No	No	Yes		Signal LWP
SIGDANGER     Yes	Yes	Yes		Swap space dangerously low
SIGGRANT      Yes	Yes	Yes		Monitor mode granted
SIGRETRACT    Yes	Yes	Yes		Need to relinquish monitor mode
SIGMSG        Yes	Yes	Yes		Monitor mode data available
SIGSOUND      Yes	Yes	Yes		Sound completed
SIGSAK        Yes	Yes	Yes		Secure attention
SIGPRIO       No	No	Yes		SIGPRIO
SIG33         Yes	Yes	Yes		Real-time event 33
SIG34         Yes	Yes	Yes		Real-time event 34
SIG35         Yes	Yes	Yes		Real-time event 35
SIG36         Yes	Yes	Yes		Real-time event 36
SIG37         Yes	Yes	Yes		Real-time event 37
SIG38         Yes	Yes	Yes		Real-time event 38
SIG39         Yes	Yes	Yes		Real-time event 39
SIG40         Yes	Yes	Yes		Real-time event 40
SIG41         Yes	Yes	Yes		Real-time event 41
SIG42         Yes	Yes	Yes		Real-time event 42
SIG43         Yes	Yes	Yes		Real-time event 43
SIG44         Yes	Yes	Yes		Real-time event 44
SIG45         Yes	Yes	Yes		Real-time event 45
SIG46         Yes	Yes	Yes		Real-time event 46
SIG47         Yes	Yes	Yes		Real-time event 47
SIG48         Yes	Yes	Yes		Real-time event 48
SIG49         Yes	Yes	Yes		Real-time event 49
SIG50         Yes	Yes	Yes		Real-time event 50
SIG51         Yes	Yes	Yes		Real-time event 51
SIG52         Yes	Yes	Yes		Real-time event 52
SIG53         Yes	Yes	Yes		Real-time event 53
SIG54         Yes	Yes	Yes		Real-time event 54
SIG55         Yes	Yes	Yes		Real-time event 55
SIG56         Yes	Yes	Yes		Real-time event 56
SIG57         Yes	Yes	Yes		Real-time event 57
SIG58         Yes	Yes	Yes		Real-time event 58
SIG59         Yes	Yes	Yes		Real-time event 59
SIG60         Yes	Yes	Yes		Real-time event 60
SIG61         Yes	Yes	Yes		Real-time event 61
SIG62         Yes	Yes	Yes		Real-time event 62
SIG63         Yes	Yes	Yes		Real-time event 63
SIGCANCEL     No	No	Yes		LWP internal signal
SIG32         Yes	Yes	Yes		Real-time event 32
SIG64         Yes	Yes	Yes		Real-time event 64
SIG65         Yes	Yes	Yes		Real-time event 65
SIG66         Yes	Yes	Yes		Real-time event 66
SIG67         Yes	Yes	Yes		Real-time event 67
SIG68         Yes	Yes	Yes		Real-time event 68
SIG69         Yes	Yes	Yes		Real-time event 69
SIG70         Yes	Yes	Yes		Real-time event 70
SIG71         Yes	Yes	Yes		Real-time event 71
SIG72         Yes	Yes	Yes		Real-time event 72
SIG73         Yes	Yes	Yes		Real-time event 73
SIG74         Yes	Yes	Yes		Real-time event 74
SIG75         Yes	Yes	Yes		Real-time event 75
SIG76         Yes	Yes	Yes		Real-time event 76
SIG77         Yes	Yes	Yes		Real-time event 77
SIG78         Yes	Yes	Yes		Real-time event 78
SIG79         Yes	Yes	Yes		Real-time event 79
SIG80         Yes	Yes	Yes		Real-time event 80
SIG81         Yes	Yes	Yes		Real-time event 81
SIG82         Yes	Yes	Yes		Real-time event 82
SIG83         Yes	Yes	Yes		Real-time event 83
SIG84         Yes	Yes	Yes		Real-time event 84
SIG85         Yes	Yes	Yes		Real-time event 85
SIG86         Yes	Yes	Yes		Real-time event 86
SIG87         Yes	Yes	Yes		Real-time event 87
SIG88         Yes	Yes	Yes		Real-time event 88
SIG89         Yes	Yes	Yes		Real-time event 89
SIG90         Yes	Yes	Yes		Real-time event 90
SIG91         Yes	Yes	Yes		Real-time event 91
SIG92         Yes	Yes	Yes		Real-time event 92
SIG93         Yes	Yes	Yes		Real-time event 93
SIG94         Yes	Yes	Yes		Real-time event 94
SIG95         Yes	Yes	Yes		Real-time event 95
SIG96         Yes	Yes	Yes		Real-time event 96
SIG97         Yes	Yes	Yes		Real-time event 97
SIG98         Yes	Yes	Yes		Real-time event 98
SIG99         Yes	Yes	Yes		Real-time event 99
SIG100        Yes	Yes	Yes		Real-time event 100
SIG101        Yes	Yes	Yes		Real-time event 101
SIG102        Yes	Yes	Yes		Real-time event 102
SIG103        Yes	Yes	Yes		Real-time event 103
SIG104        Yes	Yes	Yes		Real-time event 104
SIG105        Yes	Yes	Yes		Real-time event 105
SIG106        Yes	Yes	Yes		Real-time event 106
SIG107        Yes	Yes	Yes		Real-time event 107
SIG108        Yes	Yes	Yes		Real-time event 108
SIG109        Yes	Yes	Yes		Real-time event 109
SIG110        Yes	Yes	Yes		Real-time event 110
SIG111        Yes	Yes	Yes		Real-time event 111
SIG112        Yes	Yes	Yes		Real-time event 112
SIG113        Yes	Yes	Yes		Real-time event 113
SIG114        Yes	Yes	Yes		Real-time event 114
SIG115        Yes	Yes	Yes		Real-time event 115
SIG116        Yes	Yes	Yes		Real-time event 116
SIG117        Yes	Yes	Yes		Real-time event 117
SIG118        Yes	Yes	Yes		Real-time event 118
SIG119        Yes	Yes	Yes		Real-time event 119
SIG120        Yes	Yes	Yes		Real-time event 120
SIG121        Yes	Yes	Yes		Real-time event 121
SIG122        Yes	Yes	Yes		Real-time event 122
SIG123        Yes	Yes	Yes		Real-time event 123
SIG124        Yes	Yes	Yes		Real-time event 124
SIG125        Yes	Yes	Yes		Real-time event 125
SIG126        Yes	Yes	Yes		Real-time event 126
SIG127        Yes	Yes	Yes		Real-time event 127
SIGINFO       Yes	Yes	Yes		Information request
EXC_BAD_ACCESS Yes	Yes	Yes		Could not access memory
EXC_BAD_INSTRUCTION Yes	Yes	Yes		Illegal instruction/operand
EXC_ARITHMETIC Yes	Yes	Yes		Arithmetic exception
EXC_EMULATION Yes	Yes	Yes		Emulation instruction
EXC_SOFTWARE  Yes	Yes	Yes		Software generated exception
EXC_BREAKPOINT Yes	Yes	Yes		Breakpoint
SIGLIBRT      No	No	Yes		librt internal signal

Use the "handle" command to change these tables.
pwndbg>

第一项(Signal):标示每个信号。
第二项(Stop):表示被调试的程序有对应的信号发生时,gdb是否会暂停程序。
第三项(Print):表示被调试的程序有对应的信号发生时,gdb是否会打印相关信息。
第四项(Pass to program):gdb是否会把这个信号发给被调试的程序。
第五项(Description):信号的描述信息。

从上面的输出可以看到,当SIGINT信号发生时,gdb会暂停被调试的程序,并打印相关信息,但不会把这个信号发给被调试的程序。而当SIGALRM信号发生时,gdb不会暂停被调试的程序,也不打印相关信息,但会把这个信号发给被调试的程序。

启动gdb调试上面的程序,同时另起一个终端,先后发送SIGINTSIGALRM信号给被调试的进程,输出如下:

终端1:

ubuntu@niu0217:~/Dev/testGDB$ ./test25
Receive signal: 2
Receive signal: 14

终端2:

ubuntu@niu0217:~/Dev/testGDB$ ps -aux | grep test25
ubuntu   1932500  0.0  0.0   2356   572 pts/0    S+   20:02   0:00 ./test25
ubuntu   1932530  0.0  0.0  11276   656 pts/1    S+   20:02   0:00 grep test25
ubuntu@niu0217:~/Dev/testGDB$ /bin/kill -SIGINT 1932500
ubuntu@niu0217:~/Dev/testGDB$ /bin/kill -SIGALRM 1932500
ubuntu@niu0217:~/Dev/testGDB$

11. 共享库

11.1 显示共享链接库信息

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handler(int sig);

void handler(int sig)
{
    signal(sig, handler);
    printf("Receive signal: %d\n", sig);
}

int main(void) {
    signal(SIGHUP, handler);

    while (1)
    {
        sleep(1);
    }
    return 0;
}

使用"info sharedlibrary regex"命令可以显示程序加载的共享链接库信息,其中regex可以是正则表达式,意为显示名字符合regex的共享链接库。如果没有regex,则列出所有的库:

pwndbg> info sharedlibrary
From                To                  Syms Read   Shared Object Library
0x00007ffff7fd0100  0x00007ffff7ff2684  Yes         /lib64/ld-linux-x86-64.so.2
0x00007ffff7de9630  0x00007ffff7f5e27d  Yes         /lib/x86_64-linux-gnu/libc.so.6

12. 脚本

12.1 配置.gdbinit文件

当gdb启动时,会读取HOME目录和当前目录下的的配置文件,执行里面的命令。这个文件通常为“.gdbinit”。

# 保存历史命令
set history filename ~/.gdb_history
set history save on

# 退出时不显示提示信息
set confirm off

# 按照派生类型打印对象
set print object on

# 打印数组的索引下标
set print array-indexes on

# 每行打印一个结构体成员
set print pretty on

12.2 按何种方式解析脚本文件

gdb支持的脚本文件分为两种:

  • 一种是只包含gdb自身命令的脚本,例如.gdbinit文件,当gdb在启动时,就会执行.gdbinit文件中的命令
  • gdb还支持其它一些语言写的脚本文件(比如python)。gdb用set script-extension命令来决定按何种格式来解析脚本文件。它可以取3个值:
    • off:所有的脚本文件都解析成gdb的命令脚本;
    • soft:根据脚本文件扩展名决定如何解析脚本。如果gdb支持解析这种脚本语言(比如python),就按这种语言解析,否则就按命令脚本解析;
    • strict:根据脚本文件扩展名决定如何解析脚本。如果gdb支持解析这种脚本语言(比如python),就按这种语言解析,否则不解析

13. 其他

13.1 使用命令的缩写形式

在gdb中,你不用必须输入完整的命令,只需命令的(前)几个字母即可。规则是,只要这个缩写不会和其它命令有歧义(注,是否有歧义,这个规则从文档上看不出,看起来需要查看gdb的源代码,或者在实际使用中进行总结)。也可以使用tab键进行命令补全。

其中许多常用命令只使用第一个字母就可以,比如:

b -> break
c -> continue
d -> delete
f -> frame
i -> info
j -> jump
l -> list
n -> next
p -> print
r -> run
s -> step
u -> until

也有使用两个或几个字母的,比如:

aw -> awatch
bt -> backtrace
dir -> directory
disas -> disassemble
fin -> finish
ig -> ignore
ni -> nexti
rw -> rwatch
si -> stepi
tb -> tbreak
wa -> watch
win -> winheight

另外,如果直接按回车键,会重复执行上一次的命令。

13.2 在gdb中执行shell命令和make

(gdb) shell ls
(gdb) make CFLAGS="-g -O0"

13.3 设置被调试程序的参数

(gdb) set args a b c
(gdb) show args
Argument list to give program being debugged when it is started is "a b c".
(gdb) r a b
Starting program: /home/xmj/tmp/a.out a b
(gdb) show args
Argument list to give program being debugged when it is started is "a b".
(gdb) r
Starting program: /home/xmj/tmp/a.out a b 

13.4 记录执行gdb的过程

用gdb调试程序时,可以使用“set logging on”命令把执行gdb的过程记录下来,方便以后自己参考或是别人帮忙分析。默认的日志文件是“gdb.txt”,也可以用“set logging file file”改成别的名字

(gdb) set logging file log.txt
(gdb) set logging on

13.5 设置被调试程序的环境变量

在GDB中,你可以使用set environment命令来设置环境变量。以下是一个例子:

假设你有一个程序,它依赖于一个环境变量MY_VAR。你可以在GDB中设置这个环境变量,如下所示:

gdb your_program

然后在GDB命令行中:

(gdb) set environment MY_VAR=value

这里,value是你想要设置的环境变量MY_VAR的值。

例如,如果你想设置MY_VARhello,你可以这样做:

(gdb) set environment MY_VAR=hello

之后,当你运行你的程序时,它将看到这个环境变量已经设置好了。

如果你想删除一个环境变量,可以使用unset environment命令:

(gdb) unset environment MY_VAR

注意,这些环境变量的设置只在GDB会话期间有效,当GDB退出时,这些环境变量的更改不会影响到系统的环境变量。如果你想要永久地设置环境变量,你应该在你的shell配置文件(如.bashrc.bash_profile)中设置它们。

标签:x86,lib,gnu,linux,gdb,64,日常,Linux,Yes
From: https://blog.csdn.net/qq_43651585/article/details/141225786

相关文章

  • Linux 软件管理
    YUM仓库配置        默认的系统YUM源,需要连接国外的apache网站,网速比较慢,可以修改关联的网络YUM源为国内镜像的网站,比如网易,aliyu等替换yum源yuminstallwget 1.在/etc/yum.repos.d/目录下,备份repos文件cpCentOS-Base.repoCentOs-Base.repo.backup2.下......
  • 最完整版Linux安装mysql8.0(保姆教程)
    目录前言删除已安装的mysql通过yum源安装mysql前言安装mysql可以通过yum源和压缩包两种方式安装,压缩包安装的mysql通常使用的是旧的SysVinit脚本,使用命令如:servicemysqlstart。如果想要交给服务器的任务管理器管理需要进行额外配置,配置中可能会出现一些问题,推荐使......
  • 晋商银行携手云和恩墨MogDB重塑数据安全与业务创新新范式
    在信息技术飞速发展的今天,金融机构面临如何在保障数据安全与业务连续性的基础上推进技术创新与应用的重大挑战。晋商银行积极响应国家战略,通过实际行动给出了自己的答案……谋定而后动,晋商银行携手MogDB创新启程经过对国内数据库厂商及其产品进行严格筛选和审慎评估,晋商银行最终选......
  • linux 同时tail 多个文件并过滤多个关键字
    多个文件  过滤多个关键字或的关系tail-fcdc-adapter/err_cdc-adapter.logcdc-admin/err_cdc-adapter.logcdc-dpm/err_cdc-dpm.logcdc-extractor/err_cdc-extractor.log|grep-E'.log|ERROR'==>cdc-adapter/err_cdc-adapter.log<==[2024-08-1514:59:25.905......
  • Linux 的常用命令
    1.改变目录cd目录的表达方法:/根目录.当前目录..上一级目录~家目录cd/进入到系统根目录cd.进入当前目录cd..进入当前目录的父目录,返回上层目录cd/tmp进入指定目录/tmpcd~进入当前用户的家目录cd进入当前用户的家目录cd-回到刚才所在的目录2.......
  • Linux_开机_关机_重启_的时候执行脚本
    Linux_开机_关机_重启_的时候执行脚本转载注明来源:本文链接来自osnosn的博客,写于2024-08.参考Linux关机时执行指定脚本如何在Systemd下配置并运行关机前的脚本在Linux启动或重启时执行命令与脚本Centos7关机和重启前执行自定义脚本如何在重启或启动时执行命令或脚......
  • Linux 远程Debug JVM
    前言:    在我们的开发中由于部署环境的差异性,相信很多朋友都碰到过开发环境正常测试过的功能在测试环境甚至生产环境下出现bug的情况。一般情况下,生产环境可以采取的手段比较单一,即通过日志的方式获取运行中的环境上下文,分析日志文件并尝试重现bug。这会带来的问题还......
  • Linux系统性能监控工具Glances使用
    一Glances简介1.1glances介绍Glances是一个跨平台的监控工具,旨在通过curses或基于Web的界面呈现大量监控信息。该信息根据用户界面的大小动态调整。它也可以在客户端/服务器模式下工作。远程监控可以通过终端、Web界面或API(XML-RPC和RESTful)完成。统计数据也可以导出......
  • 嵌入式linux mkdir: cannot create directory 'test': Read-only file system
    这个错误表明你尝试在嵌入式Linux系统上创建一个名为'test'的目录时失败了,因为文件系统被挂载为只读模式。在只读模式下,你无法修改文件系统的内容,包括创建、删除文件或目录。解决方法:1.重新挂载文件系统为读写模式。你可以使用mount命令重新挂载文件系统,并指定读写权限。例如:......
  • 0233-Net-linux 收包流程
    环境Time2022-11-27WSL-Ubuntu22.04前言说明参考:https://github.com/leandromoreira/linux-network-performance-parameters目标了解linux系统接收网络数据包的具体流程。数据到达网卡网卡将光电信号还原成数据包。网卡校验如果不是在混杂模式下,网卡校验数据包中......