GDB 调试

本文介绍如何使用GDB调试工具进行程序调试,包括设置断点、查看调用栈、打印变量和表达式等实用命令。此外还讲解了如何利用这些命令进行更深入的调试工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们需要得到当前进程的函数调用栈的情况,以此回溯找到我们自己的方法。这时我们需要用到backtrace命令,一般简写为bt:

们还可以使用list(简写为l)命令,打印出更多信息:


    (gdb) l 
      
      int main(int argc, char **argv) 
      { 
          NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
          int x = 42; 
    10      NSLog("Hello, world! x = %@", x); 
    11      [pool release]; 
    12      
    13      return 0; 
    14  }


一个很重要的调试方法是输出表达式和变量的值。在gdb中,这是通过print命令完成的。

    (gdb) p x 
    $1 = 42

在print命令后追加/format可以格式化输出。/format是一个gdb的格式化字符串,比较有用的格式化字符有 x:十进制数; c:字符; a:地址等。

    (gdb) p/x x 
    $2 = 0x2a

print-object方法(简写为po)用来输出obj-c中的对象。它的工作原理是,向被调用的对象发送名为debugDescription的消息。它和常见的description消息很像。

举例来说,让我们输出一下autorelease pool:

    (gdb) po pool 
    <NSAutoreleasePool: 0x10010e820>

这个命令不仅仅可以输出显式定义的对象,也可以输出表达式的结果。这次我们测试一下nsobject中debugDescription的方法签名:

    (gdb) po [NSObject instanceMethodSignatureForSelector: @selector(debugDescription)] 
    <NSMethodSignature: 0x10010f320> 
        number of arguments = 2 
        frame size = 224 
        is special struct return? NO 
        return value: -------- -------- -------- -------- 
            type encoding (@) '@' 
            flags {isObject} 
            modifiers {} 
            frame {offset = 0, offset adjust = 0, size = 8, size adjust = 0} 
            memory {offset = 0, size = 8} 
        argument 0: -------- -------- -------- -------- 
            type encoding (@) '@' 
            flags {isObject} 
            modifiers {} 
            frame {offset = 0, offset adjust = 0, size = 8, size adjust = 0} 
            memory {offset = 0, size = 8} 
        argument 1: -------- -------- -------- -------- 
            type encoding (:) ':' 
            flags {} 
            modifiers {} 
            frame {offset = 8, offset adjust = 0, size = 8, size adjust = 0} 
            memory {offset = 0, size = 8}

是不是很方便。但是要注意,gdb也许会不能识别NSObject这样的类名。这时我们就要使用一些小技巧,比如说用NSClassFromString来获得类名:

    (gdb) po [NSClassFromString(@"NSObject") instanceMethodSignatureForSelector: @selector(debugDescription)]


返回值是对象的表达式可以用po命令输出结果,那么返回值是基本类型的方法又怎样呢?显然,它们是可以用p命令输出的。但是要小心,因为gdb并不能自动识别出返回值的类型。所以我们在输出前要显式地转换一下:

    (gdb) p [NSObject instancesRespondToSelector: @selector(doesNotExist)] 
    Unable to call function "objc_msgSend" at 0x7fff84f100f4: no return type information available. 
    To call this function anyway, you can cast the return type explicitly (e.g. 'print (float) fabs (3.0)') 


    (gdb) p (char)[NSObject instancesRespondToSelector: @selector(doesNotExist)] 
    $5 = 0 '00'



有时,查看数值程度的能力还是稍弱了一点,我们还想能够修改变量。这也很简单,只需要使用set命令:

    (gdb) set x = 43

我们可以用任意表达式给一个变量赋值。比如说新创建一个对象然后赋值:

    (gdb) set obj = (void *)[[NSObject alloc] init]


Xcode的调试器为用户提供了一个GDB的界面,GDB是GNU组织的开放源代码调试器。您可以在Xcode的图形界面里做任何事情;但是,如果您需要 您可以在命令行里使用GDB的命令。 

要在一个调试的任务里输入GDB命令行命令: 

在工具栏里点击Console Drawer (控制台抽屉窗口)按钮打开控制台。 
您可以在控制台里查看Xcode调试器发送给GDB的命令,或者您可以直接在控制台里输入GDB命令。在控制台窗口里点击然后在gdb提示符后面 输入命令。

  1. 命 令                        解释  
  2. break NUM               在指定的行上设置断点。  
  3. bt                      显 示所有的调用栈帧。该命令可用来显示函数的调用顺序。  
  4. clear                   删 除设置在特定源文件、特定行上的断点。其用法为:clear FILENAME:NUM。  
  5. continue                继续执行正在调试的程序。该命令用在程序 由于处理信号或断点而  
  6.                         导致停止运行 时。  
  7. display EXPR            每次程序停止后显示表达式的值。表达式由程序定 义的变量组成。  
  8. file FILE               装载指定的可执行文件进行调试。  
  9. help NAME               显 示指定命令的帮助信息。  
  10. info break              显 示当前断点清单,包括到达断点处的次数等。  
  11. info files              显 示被调试文件的详细信息。  
  12. info func               显示所有的函数名称。  
  13. info local              显 示当函数中的局部变量信息。  
  14. info prog               显示被调试程序的执行状 态。  
  15. info var                显示所有的全局和静态变量名称。  
  16. kill                    终 止正被调试的程序。  
  17. list                    显示源代码段。  
  18. make                    在 不退出 gdb 的情况下运行 make 工具。  
  19. next                    在 不单步执行进入其他函数的情况下,向前执行一行源代码。  
  20. print EXPR              显 示表达式 EXPR 的值。  
  21.   
  22. print- object            打印一个对象  
  23. print (int) name      打印一个类型  
  24. print- object [artist description]   调用一个函数  
  25. set artist = @"test"    设置变量值  
  26. whatis                      查 看变理的数据类型  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值