• gdb+qemu是用来追踪内核的


    转    https://www.cnblogs.com/linghuchong0605/p/4942120.html

    1、引言

       Linux内核是一个很大的模块,如果只是看源码有时会难以理解Linux内核的一些代码设计情况,如果可以结合Linux内核运行同时阅读源码再好不过,本文大致介绍Linux内核追踪方式,采用工具为qemu模拟器和gdb工具完成。

    2、先决条件

     (1)工具:需要使用qemu模拟器和gdb,在默认的Linux发行版中基本都有gdb工具;而对于qemu模拟器则需要自己下载安装,可以使用qemu源码安装,比较麻烦,不建议使用,可以使用Linux发行版中的包管理器进行下载安装,对于ubuntu和debian使用apt-get install命令,而对于centos和federa使用yum包管理器安装;在ubuntu下安装qemu模拟器,对应的包的名字可以在http://packages.ubuntu.com/搜索

     (2)Linux内核源码:为了追踪Linux内核,你需要自己编译一个新的Linux内核,Linux内核下载网站https://www.kernel.org/,内核的具体编译方式在Linux内核源码压缩包中README文件有介绍

     (3)镜像文件:下载一个ubuntu的iso文件(或者其它Linux发行版的iso文件),使用qemu创建一个ubuntu镜像,创建过程为

           a)qemu-img create -f qcow2 ubuntu.img 10G (详细各个参数的含义见qemu-img的手册)

           b)qemu-i386 -hda ubuntu.img -cdrom ~/Documents/ubuntu-14.10-desktop-i386.iso

    1. #include <stdio.h>  
    2. #include <string.h>  
    3.   
    4. int main()  
    5. {  
    6.   int i;  
    7.   printf("TK------>>>sizeof i is %d ",sizeof i);  
    8.   char *p = NULL;  
    9.   strcpy(p,"tankai");  
    10.   printf("p is %s ",p);  
    11.   return 0;  
    12. }  

    2.编译

    gcc -g -o 1 1.c

    3.运行

    ./1

    1. TK------>>>sizeof i is 4  
    2. 段错误  

    二、运行跟踪

    1.strace

    strace ./1

    1. execve("./1", ["./1"], [/* 45 vars */]) = 0  
    2. brk(0)                                  = 0x94b000  
    3. access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)  
    4. mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f5e285000  
    5. access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)  
    6. open("tls/x86_64/libc.so.6", O_RDONLY)  = -1 ENOENT (No such file or directory)  
    7. open("tls/libc.so.6", O_RDONLY)         = -1 ENOENT (No such file or directory)  
    8. open("x86_64/libc.so.6", O_RDONLY)      = -1 ENOENT (No such file or directory)  
    9. open("libc.so.6", O_RDONLY)             = -1 ENOENT (No such file or directory)  
    10. open("/home/lianxi/share/static/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)  
    11. stat("/home/lianxi/share/static/tls/x86_64", 0x7fff7bbb1770) = -1 ENOENT (No such file or directory)  
    12. open("/home/lianxi/share/static/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)  
    13. stat("/home/lianxi/share/static/tls", 0x7fff7bbb1770) = -1 ENOENT (No such file or directory)  
    14. open("/home/lianxi/share/static/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)  
    15. stat("/home/lianxi/share/static/x86_64", 0x7fff7bbb1770) = -1 ENOENT (No such file or directory)  
    16. open("/home/lianxi/share/static/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)  
    17. stat("/home/lianxi/share/static", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0  
    18. open("/usr/lib/libpython2.6.so.1.0/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOTDIR (Not a directory)  
    19. stat("/usr/lib/libpython2.6.so.1.0/tls/x86_64", 0x7fff7bbb1770) = -1 ENOTDIR (Not a directory)  
    20. open("/usr/lib/libpython2.6.so.1.0/tls/libc.so.6", O_RDONLY) = -1 ENOTDIR (Not a directory)  
    21. stat("/usr/lib/libpython2.6.so.1.0/tls", 0x7fff7bbb1770) = -1 ENOTDIR (Not a directory)  
    22. open("/usr/lib/libpython2.6.so.1.0/x86_64/libc.so.6", O_RDONLY) = -1 ENOTDIR (Not a directory)  
    23. stat("/usr/lib/libpython2.6.so.1.0/x86_64", 0x7fff7bbb1770) = -1 ENOTDIR (Not a directory)  
    24. open("/usr/lib/libpython2.6.so.1.0/libc.so.6", O_RDONLY) = -1 ENOTDIR (Not a directory)  
    25. stat("/usr/lib/libpython2.6.so.1.0", {st_mode=S_IFREG|0555, st_size=5255963, ...}) = 0  
    26. open("/etc/ld.so.cache", O_RDONLY)      = 3  
    27. fstat(3, {st_mode=S_IFREG|0644, st_size=148114, ...}) = 0  
    28. mmap(NULL, 148114, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5f5e260000  
    29. close(3)                                = 0  
    30. access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)  
    31. open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3  
    32. read(3, "177ELF2113>1 242"..., 832) = 832  
    33. fstat(3, {st_mode=S_IFREG|0755, st_size=1694008, ...}) = 0  
    34. mmap(NULL, 3810152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f5f5dcc4000  
    35. mprotect(0x7f5f5de5d000, 2093056, PROT_NONE) = 0  
    36. mmap(0x7f5f5e05c000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x198000) = 0x7f5f5e05c000  
    37. mmap(0x7f5f5e061000, 21352, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f5f5e061000  
    38. close(3)                                = 0  
    39. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f5e25f000  
    40. mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f5e25d000  
    41. arch_prctl(ARCH_SET_FS, 0x7f5f5e25d720) = 0  
    42. mprotect(0x7f5f5e05c000, 16384, PROT_READ) = 0  
    43. mprotect(0x600000, 4096, PROT_READ)     = 0  
    44. mprotect(0x7f5f5e287000, 4096, PROT_READ) = 0  
    45. munmap(0x7f5f5e260000, 148114)          = 0  
    46. fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0  
    47. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f5e284000  
    48. write(1, "TK------>>>sizeof i is 4 ", 25TK------>>>sizeof i is 4  
    49. ) = 25  
    50. --- SIGSEGV (Segmentation fault) @ 0 (0) ---  
    51. +++ killed by SIGSEGV +++  
    52. 段错误  

    2.ltrace

    ltrace ./1

    1. __libc_start_main(0x400544, 1, 0x7fff5acc0c88, 0x4005b0, 0x400640 <unfinished ...>  
    2. printf("TK------>>>sizeof i is %d ", 4TK------>>>sizeof i is 4  
    3. )                                                    = 25  
    4. memcpy(NULL, "tankai", 7 <unfinished ...>  
    5. --- SIGSEGV (Segmentation fault) ---  
    6. +++ killed by SIGSEGV +++  

    3.gdb

    gdb 1

    list

    b 5

    r

    n

      1. (gdb) list  
      2. 1   #include <stdio.h>  
      3. 2   #include <string.h>  
      4. 3     
      5. 4   int main()  
      6. 5   {  
      7. 6     int i;  
      8. 7     printf("TK------>>>sizeof i is %d ",sizeof i);  
      9. 8     char *p = NULL;  
      10. 9     strcpy(p,"tankai");  
      11. 10    printf("p is %s ",p);  
      12. (gdb) b 5  
      13. Breakpoint 1 at 0x40054c: file 1.c, line 5.  
      14. (gdb) r  
      15. Starting program: /home/lianxi/extern/ok/1   
      16.   
      17. Breakpoint 1, main () at 1.c:7  
      18. 7     printf("TK------>>>sizeof i is %d ",sizeof i);  
      19. (gdb) n  
      20. TK------>>>sizeof i is 4  
      21. 8     char *p = NULL;  
      22. (gdb) n  
      23. 9     strcpy(p,"tankai");  
      24. (gdb) n  
      25.   
      26. Program received signal SIGSEGV, Segmentation fault.  
      27. 0x00007ffff7b6dec6 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 

    3、启动qemu追踪内核

      (1)启动qemu模拟器:qemu-system-i386 -kernel linux-build/arch/i386/boot/bzImage -hda ubuntu.img -append "root=/dev/sda1" -S

      (2)启动gdbserver:切换到qemu模拟器,alt+ctrl+2, 启动gdbserver,侦听端口1234(gdbserver tcp::1234)

      (3)启动gdb:gdb ./vmlinux ,然后在gdb命令条件下链接上gdbserver, target remote localhost:1234

    4、开始追踪内核

       使用gdb的基本常用命令,step, break等(其他具体的命令可以参考gdb手册)。这时你可以查看系统运行的一些内核参数及系统状态信息,结合源码,查看系统的运行状态

      

  • 相关阅读:
    2.7 矩阵的秩
    HDU
    HDU
    HDU
    HDU
    HDU
    hdu 5179 beautiful number(数位dp)
    ACdream
    CodeForces
    <a>标签中 href="/" 和 hideFocus="true"
  • 原文地址:https://www.cnblogs.com/fyy-hhzzj/p/9101439.html
Copyright © 2020-2023  润新知