使用核心转储文件 + gdb 定位程序BUG
以下是一个简单的演示代码
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
struct Box{
int used;
char stuff[64];
};
struct Box g_Boxes[100];
void PrintBox(uint32_t index){
printf("Box %d: %s\n", index, g_Boxes[index].stuff);
return;
}
void EditBox(uint32_t index){
if(g_Boxes[index].used == 0){
printf("WHATS IN THE BOX?!:");
scanf("%64s", g_Boxes[index].stuff);
g_Boxes[index].used = 1;
}
else{
printf("Box %d is already used!\n", index);
}
return;
}
int read_int(uint32_t* out){
uint32_t i = 0;
int n_parsed = scanf("%d", &i);
if(n_parsed > 0){
*out = i;
}
return n_parsed;
}
void PrintMenu(){
printf("INVENTORY MANAGEMENT SYSTEM\n");
printf("\tp: print a box\n");
printf("\te: edit a box\n");
printf("\tq: quit\n");
return;
}
int main(int argc, char* argv[]){
char selection = 'a';
PrintMenu();
while (selection != 'q')
{
selection = getchar();
if(selection == '\n'){
continue;
}
uint32_t box = 0;
switch(selection){
case 'p':
box = 0;
printf("BOX ID: ");
if(!read_int(&box)){
printf("Please input an integer for the box ID\n");
continue;
}
PrintBox(box);
break;
case 'e':
box = 0;
printf("BOX ID: ");
if(!read_int(&box)){
printf("Please input an integer for the box ID\n");
continue;
}
EditBox(box);
break;
case '\n':
break;
case 'q':
break;
}
}
}
编译代码
gcc -o inventory invectory.c -g
我们输入一个很大的index来触发这个code dump
我们遇到了核心转储,这意味着计算机输出了核心文件.(核心文件是一个ELF文件,包含程序崩溃时的完整状态信息。
如果你当前目录没有生成。可以执行以下命令:
echo "./core" > /proc/sys/kernel/core_pattern
ulimit -c unlimited
这样我们就得到了core文件
接下来使用gdb进行加载调试
gdb ./inventory ./core.4018912
如下图:
其明确的给出了详细的错误信息
(gdb) x/i $pc
=> 0x4011b5 <EditBox+34>: mov (%rax),%eax
(gdb) info registers
rax 0x31613170 828453232
rbx 0x0 0
rcx 0x0 0
rdx 0xb8f47c 12121212
rsi 0x0 0
rdi 0xb8f47c 12121212
rbp 0x7fff53f5ea90 0x7fff53f5ea90
rsp 0x7fff53f5ea80 0x7fff53f5ea80
r8 0x1999999999999999 1844674407370955161
r9 0x0 0
r10 0x7fb151d66ac0 140399558945472
r11 0x7fb151d673c0 140399558947776
r12 0x401070 4198512
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x4011b5 0x4011b5 <EditBox+34>
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
k0 0x700 1792
k1 0x2 2
k2 0x0 0
k3 0x0 0
k4 0x0 0
k5 0x0 0
k6 0x0 0
k7 0x0 0
(gdb)