GDB arm-linux交叉编译移植和使用方法(特别是对于正在运行的程序或者段错误的程序进行分析)

目录(?)[+]

1、ncurse库的移植

    (1)下载:ncurses-5.6.tar.gz 
    (2)解压和cd ncurses-5.6
    (3)配置生成 makefile
        ./configure --host=arm-linux  --prefix=$PWD/output/arm --without-ada --enable-termcap --with-shared
        host是交叉编译工具链,可能不同平台会有所不同
        --enable-termcap比较关键gdb需要这个库   
    (4)编译 make
    (5)安装 make install

          libncurses.so放在ncurses-5.6/output/arm/lib路径下。

2、gdb库的编译和移植

    (1)下载:gdb-7.1a.tar.gz   官网:http://www.gnu.org/software/gdb/download/
    (2)解压和cd gdb-7.1
    (3)配置生成 makefile
        ./configure --host=arm-unknown-linux-gnu --enable-shared --prefix=$PWD/output/arm --without-x 
       --disable-gdbtk --disable-tui --without-included-regex --without-included-gettext 
     LDFLAGS="-L$PWD/../ncurses-5.6/output/arm/lib" CPPFLAGS="-I$PWD/../output/arm/include/ncurses"
脚本含义下:
--enable-shared    动态编译
--host=arm-linux  用arm-linux-gcc编译
--prefix="$PWD/../output/arm-linux" 安装目录
--without-x     取消x windows 支持 
--disable-gdbtk  取消gdbtk,应该也是图形界面相关的
--disable-tui   取消tui 界面
--without-included-regex 关闭正则表达式库
--without-included-gettext  去掉用于多语言处理的 gettext库
   正则表达式/gettext,暂时不需要,先去掉
CPPFLAGS/LDFLAGS是确保能找到ARM版的ncurses库

    (4)编译 make
    (5)安装 make install

 最终进程放在gdb-7.1/output/arm/bin/下的gdb进程

3、gdb移植到arm上

rz gdb进程到/home/user0上,或者其它的目录下,随自己的喜好。chmod +x gdb便可运行gdb进程了。

4、测试程序
#include
#include
#include


int func(int n)
{
int sum = 0, i;
for(i = 0; i < n; i++)
{
sum += i;
}


return sum;
}




void f2(char * str)
{
   char buf[1024];
   strcpy(buf,(const char *)str); 
}


void f1(void)
{
  int x = 0;
  f2((char *)x);
}


void test1(void)

   f1();
}




static int Delay(unsigned int uiTimeS)
{
struct timeval timeout;

timeout.tv_sec= uiTimeS;
timeout.tv_usec = 0;


select(0, NULL, NULL, NULL, &timeout);


return 0;
}

int  main(void)
{


int i;
int result = 0;
for(i = 1; i <= 100; i++)
{
result += i;
}
test1();
Delay(10000);

printf("result[1-100] = %d\n", result);
printf("result[1-250] = %d\n", func(250));


return 0;
}

测试代码中的test1是用来定位堆栈段错误,Delay函数是用来定位程序阻塞,都可以用gdb定位出来,如下:

 (1)测试程序运行时首先会有个段错误:./gdbtest &
[user0@ user0]$ [65334.020000] pgd = c3e14000
[65334.020000] [00000000] *pgd=43b87031, *pte=00000000, *ppte=00000000
用移植好的gdb来测试运行如下:

 ./gdb gdbtest
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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 "arm-unknown-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /home/user0/gdbtest...done.
(gdb) r
Starting program: /home/user0/gdbtest 
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
[65352.710000] pgd = c1cbc000read_db matching inferior's thread library, thread debugging will not be available.


[65352.710000] [00000000] *pgd=41c9c031, *pte=00000000, *ppte=00000000


Program received signal SIGSEGV, Segmentation fault.
0x400ca048 in strcpy () from /lib/libc.so.6
(gdb) bt
#0  0x400ca048 in strcpy () from /lib/libc.so.6
#1  0x00008540 in f2 (str=0x0) at src/gdbtest.c:45
#2  0x0000855c in main () at src/gdbtest.c:73
(gdb) 

[1]+  Segmentation fault         ./gdbtest

可以看出代码段错误问题出在strcpy上。

(2)测试程序中把

Delay(10000);

test1();
D
elay放到test1之前,这样程序会阻塞,阻塞的时候用gdb定位正在运行的进程非常好用:

./gdb gdbtest 1865     第一是运行gdb 第二个进程名称 第三个进程pid,顺序这样子来要
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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 "arm-unknown-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /home/user0/gdbtest...done.
Attaching to program: /home/user0/gdbtest, process 1865
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.


warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/libdl.so.2...(no debugging symbols found)...done.


warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.


warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.


warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
Loaded symbols for /lib/ld-linux.so.2
0x401198dc in select () from /lib/libc.so.6
(gdb) bt
#0  0x401198dc in select () from /lib/libc.so.6
#1  0x000086e0 in Delay (uiTimeS=) at src/gdbtest.c:67
#2  0x00008598 in _start ()

(gdb) q
A debugging session is active.

bt用来查看堆栈信息,发现阻塞在select函数中,和我们的代码一致。



你可能感兴趣的:(linux程序调试工具)