gdb使用简介
时间:2006-08-23 来源:zxbjlu1983
使用GDB: 本文描述GDB,GNU的原代码调试器。(这是4.12版1994年一月,GDB版本4。16) |
目录: * 摘要: GDB的摘要 * 实例: 一个使用实例 * 入门: 进入和退出GDB * 命令: GDB 的命令 * 运行: 在GDB下运行程序 * 停止: 暂停和继续执行 * 栈: 检查堆栈 * 原文件: 检查原文件 * 数据: 检查数据 * 语言: 用不同的语言来使用GDB * 符号: 检查符号表 * 更改: 更改执行 * GDB的文件 文件 * 对象 指定调试对象 * 控制GDB 控制 * 执行序列: 执行一序列命令 * Emacs: 使GDB和Emacs一起工作 * GDB的bug: * 命令行编辑: 行编辑 * 使用历史记录交互: * 格式化文档: 如何格式化和打印GDB文档 * 安装GDB : * 索引: GDB简介: ************** 调试器(比如象GDB)能让你观察另一个程序在执行时的内部活动,或程序出错时 发生了什么。 GDB主要能为你做四件事(包括为了完成这些事而附加的功能),帮助你找出程序 中的错误。 * 运行你的程序,设置所有的能影响程序运行的东西。 * 保证你的程序在指定的条件下停止。 * 当你程序停止时,让你检查发生了什么。 * 改变你的程序。那样你可以试着修正某个bug引起的问题,然后继续查找另一 个bug. 你可以用GDB来调试C和C++写的程序。(参考 *C 和C++) 部分支持Modula-2和chill,但现在还没有这方面的文档。 调试Pascal程序时,有一些功能还不能使用。 GDB还可以用来调试FORTRAN程序,尽管现在还不支持表达式的输入,输出变量, 或类FORTRAN的词法。 * GDB是"free software",大家都可以免费拷贝。也可以为GDB增加新的功能,不 过可要遵守GNU的许可协议幺。反正我认为GNU还是比较不错的:-) 就这句话: Fundamentally, the General Public License is a license which says that you have these freedoms and that you cannot take these freedoms away from anyone else. GDB的作者: Richard Stallman是GDB的始作俑者,另外还有许多别的GNU的成员。许多人 为此作出了贡献。(都是老外不提也罢,但愿他们不要来找我麻烦:-)) 这里是GDB的一个例子: 原文中是使用一个叫m4的程序。但很遗憾我找不到这个程序的原代码, 所以没有办法来按照原文来说明。不过反正是个例子,我就拿一个操作系统的 进程调度原码来说明把,原代码我会附在后面。 首先这个程序叫os.c是一个模拟进程调度的原程序(也许是个老古董了:-))。 先说明一下如何取得包括原代码符号的可执行代码。大家有心的话可以去看一下gcc的 man文件(在shell下打man gcc)。gcc -g <原文件.c> -o <要生成的文件名> -g 的意思是生成带原代码调试符号的可执行文件。 -o 的意思是指定可执行文件名。 (gcc 的命令行参数有一大堆,有兴趣可以自己去看看。) (忍不住要加个注,现在应该用gcc -ggdb指定吧!因为有很多人都在问,因为除了gdb还有别的工具:-) 反正在linux下把os.c用以上方法编译连接以后就产生了可供gdb使用的可执行文件。 我用gcc -g os.c -o os,产生的可执行文档叫os. 然后打gdb os,就可进入gdb,屏幕提示: GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.16, Copyright 1995 Free Software Foundation, Inc... (gdb) (gdb)是提示符,在这提示符下可以输入命令,直到退出。(退出命令是q/Q) 为了尽量和原文档说明的命令相符,即使在本例子中没用的命令我也将演示。 首先我们可以设置gdb的屏幕大小。键入: (gdb)set width 70 就是把标准屏幕设为70列。 然后让我们来设置断点。设置方法很简单:break或简单打b后面加行号或函数名 比如我们可以在main 函数上设断点: (gdb)break main 或(gdb)b main 系统提示:Breakpoint 1 at 0x8049552: file os.c, line 455. 然后我们可以运行这个程序,当程序运行到main函数时程序就会停止返回到gdb的 提示符下。运行的命令是run或r(gdb中有不少alias,可以看一下help,在gdb下打help) run 后面可以跟参数,就是为程序指定命令行参数。 比如r abcd,则程序就会abcd以作为参数。(这里要说明的是可以用set args来指定参 数)。打入r或run后,程序就开始运行直到进入main的入口停止,显示: Starting program: <路径>/os Breakpoint 1, main () at os.c:455 455 Initial(); 这里455 Initial();是将要执行的命令或函数。 gdb提供两种方式:1.单步进入,step into就是跟踪到函数内啦。命令是step或s 2.单步,next,就是简单的单步,不会进入函数。命令是next或n 这两个命令还有别的用法以后再说。 我们用n命令,键入: (gdb)n Success forking process# 1 ,pid is 31474 Success forking process# 2 ,pid is 31475 Success forking process# 3 ,pid is 31476 Success forking process# 4 ,pid is 31477 Success forking process# 5 ,pid is 31478 Success forking process# 6 ,pid is 31479 Dispatching Algorithm : FIFO ******************************************************************************** PCB# PID Priority PC State 1 31474 24 0 WAITING 2 31475 19 0 WAITING 3 31476 16 0 WAITING 4 31477 23 0 WAITING 5 31478 22 0 WAITING 6 31479 20 0 WAITING ****************************************************************************** CPU : NO process running IO : No process Waiting CPU!!! 31474 31475 31476 31477 31478 31479 Waiting IO NONE 456 State=WAITING; 最后的一行就是下一句要执行的命令。我们现在在另一个函数上加断点。注意我们 可以用l/list命令来显示原代码。这里我们键入 (gdb)l 451 main() 452 { 453 int message; 454 455 Initial(); 456 State=WAITING; 457 printf("Use Control-C to halt "); 458 signal(SIGALRM,AlarmMessage); 459 signal(SIGINT,InteruptMessage); 460 signal(SIGUSR2,IoMessage); (gdb) l 461 alarm(TimeSlot); 462 for(;;) 463 { 464 message=GetMessage(); 465 switch(message) 466 { 467 case INTERRUPT : printf("Use Control-C t; 468 break; 469 case CHILD_IO: WaitingIo(); 470 break; 显示了原代码,现在在AlarmMessage上加断点。 (gdb) b AlarmMessage Breakpoint 2 at 0x8048ee3: file os.c, line 259. (gdb) 然后我们继续运行程序。 (gdb)c c或continue命令让我们继续被中断的程序。 显示: Continuing. Use Control-C to halt Breakpoint 2, AlarmMessage () at os.c:259 259 ClearSignal(); 注意我们下一句语句就是ClearSignal(); 我们用s/step跟踪进入这个函数看看它是干什么的。 (gdb) s ClearSignal () at os.c:227 227 signal(SIGINT,SIG_IGN); 用l命令列出原代码: (gdb) l 222 } 223 224 225 void ClearSignal() /* Clear other signals */ 226 { 227 signal(SIGINT,SIG_IGN); 228 signal(SIGALRM,SIG_IGN); 229 signal(SIGUSR2,SIG_IGN); 230 } 231 (gdb) 我们可以用s命令继续跟踪。现在让我们来试试bt或backtrace命令。这个命令可以 显示栈中的内容。 (gdb) bt #0 ClearSignal () at os.c:227 #1 0x8048ee8 in AlarmMessage () at os.c:259 #2 0xbffffaec in ?? () #3 0x80486ae in ___crt_dummy__ () (gdb) 大家一定能看懂显示的意思。栈顶是AlarmMessage,接下来的函数没有名字--就是 没有原代码符号。这显示了函数调用的嵌套。 好了,我们跟踪了半天还没有检查过变量的值呢。检查表达式的值的命令是p或print 格式是p <表达式> 444444让我们来找一个变量来看看。:-) (gdb)l 1 还记得l的作用吗?l或list显示原代码符号,l或list加<行号>就显示从<行号>开始的 原代码。好了找到一个让我们来看看WaitingQueue的内容 (gdb) p WaitingQueue = {1, 2, 3, 4, 5, 6, 0} (gdb) WaitingQueue是一个数组,gdb还支持结构的显示, (gdb) p Pcb = {{Pid = 0, State = 0, Prior = 0, pc = 0}, {Pid = 31474, State = 2, Prior = 24, pc = 0}, {Pid = 31475, State = 2, Prior = 19, pc = 0}, { Pid = 31476, State = 2, Prior = 16, pc = 0}, {Pid = 31477, State = 2, Prior = 23, pc = 0}, {Pid = 31478, State = 2, Prior = 22, pc = 0}, { Pid = 31479, State = 2, Prior = 20, pc = 0}} (gdb) 这里可以对照原程序看看。 原文档里是一个调试过程,不过我想这里我已经把gdb的常用功能介绍了一遍,基本上 可以用来调试程序了。:-) 运行GDB(一些详细的说明): 前面已经提到过如何运行GDB了,现在让我们来看一些更有趣的东西。你可以在运行 GDB时通过许多命令行参数指定大量的参数和选项,通过这个你可以在一开始就设置好 程序运行的环境。 这里将要描述的命令行参数覆盖了大多数的情况,事实上在一定环境下有的并没有 什么大用处。最通常的命令就是使用一个参数: $gdb <可执行文档名> 你还可以同时为你的执行文件指定一个core文件: $gdb <可执行文件名> core 你也可以为你要执行的文件指定一个进程号: $gdb <可执行文件名> <进程号> 如:&gdb os 1234将使gdb与进程1234相联系(attach) 除非你还有一个文件叫1234的。gdb首先检查一个core文件。 如果你是使用一个远程终端进行远程调试的话,那如果你的终端不支持的话,你将无法 使用第二个参数甚至没有core dump。如果你觉得开头的提示信息比较碍眼的话,你可以 用gdb -silent。你还可以用命令行参数更加详细的控制GDB的行为。 打入gdb -help或-h 可以得到这方面的提示。所有的参数都被按照排列的顺序传给gdb 除非你用了-x参数。 当gdb开始运行时,它把任何一个不带选项前缀的参数都当作为一个可执行文件或core 文件(或进程号)。就象在前面加了-se或-c选项。gdb把第一个前面没有选项说明的参数 看作前面加了-se 选项,而第二个(如果有的话)看作是跟着-c选项后面的。 许多选项有缩写,用gdb -h可以看到。在gdb中你也可以任意的把选项名掐头去尾,只 要保证gdb能判断唯一的一个参数就行。 在这里我们说明一些最常用的参数选项 -symbols <文件名>(-s <文件名>)------从<文件名>中读去符号。 -exec <文件名>(-e <文件名>)----在合适的时候执行<文件名>来做用正确的数据与core dump的作比较。 -se <文件名>------从<文件名>中读取符号并把它作为可执行文件。 -core <文件名>(-c <文件名>)--指定<文件名>为一个core dump 文件。 -c <数字>----连接到进程号为<数字>,与attach命令相似。 -command <文件名> -x <文件名>-----执行gdb命令,在<文件名>指定的文件中存放着一序列的gdb命令,就 象一个批处理。 -directory(-d) <路径>---指定路径。把<路径>加入到搜索原文件的路径中。 -m -mapped---- 注意这个命令不是在所有的系统上都能用。如果你可以通过mmap系统调用来获得内存 映象文件,你可以用这个命令来使gdb把你当前文件里的符号写入一个文件中,这个文件 将存放在你的当前路径中。如果你调试的程序叫/temp/fred那么map文件就叫 ./fred.syms这样当你以后再调试这个程序时,gdb会认识到这个文件的存在,从而从这 个文件中读取符号,而不是从可执行文件中读取。.syms与主机有关不能共享。 -r -readnow---马上从符号文件中读取整个符号表,而不是使用缺省的。缺省的符号表是 调入一部分符号,当需要时再读入一部分。这会使开始进入gdb慢一些,但可以加快以后 的调试速度。 -m和-r一般在一起使用来建立.syms文件 接下来再谈谈模式的设置(请听下回分解 :-)) 附:在gdb文档里使用的调试例子我找到了在minix下有这个程序,叫m4有兴趣的 可以自己去看看 模式的选择 -------------- 现在我们来聊聊gdb运行模式的选择。我们可以用许多模式来运行gdb,例如在“批模式” 或“安静模式”。这些模式都是在gdb运行时在命令行作为选项指定的。 `-nx' `-n' 不执行任何初始化文件中的命令。(一般初始化文件叫做`.gdbinit').一般情况下在 这些文件中的命令会在所有的命令行参数都被传给gdb后执行。 `-quiet' `-q' “安静模式”。不输出介绍和版权信息。这些信息在“批模式”中也被跳过。 `-batch' “批模式”。在“批模式”下运行。当在命令文件中的所有命令都被成功的执行后 gdb返回状态“0”,如果在执行过程中出错,gdb返回一个非零值。 “批模式”在把gdb作为一个过滤器运行时很有用。比如在一台远程计算机上下载且 执行一个程序。信息“ Program exited normally”(一般是当运行的程序正常结束 时出现)不会在这种模式中出现。 `-cd DIRECTORY' 把DIRECTORY作为gdb的工作目录,而非当前目录(一般gdb缺省把当前目录作为工作目 录)。 `-fullname' `-f' GNU Emacs 设置这个选项,当我们在Emacs下,把gdb作为它的一个子进程来运行时, Emacs告诉gdb按标准输出完整的文件名和行号,一个可视的栈内容。这个格式跟在 文件名的后面。行号和字符重新按列排,Emacs-to-GDB界面使用2字符作为一个 显示一页原文件的信号。 `-b BPS' 为远程调试设置波特率。 `-tty DEVICE' 使用DEVICE来作为你程序的标准输入输出 `quit' 使用'quit'命令来退出gdb,或打一个文件结束符(通常是' CTROL-D')。如果 你没有使用表达式,gdb会正常退出,否则它会把表达式的至作为error code 返回。 一个中断(通常是'CTROL-c)不会导致从gdb中退出,而是结束任何一个gdb的命 令,返回gdb的命令输入模式。一般在任何时候使用'CTROL-C'是安全的,因为 gdb会截获它,只有当安全时,中断才会起作用。 如果你正在用gdb控制一个被连接的进程或设备,你可以用'detach'命令来释放 它。 Shell命令 ============== 当你偶尔要运行一些shell命令时,你不必退出调试过程,也不需要挂起它;你 可以使用'shell'命令。 `shell COMMAND STRING' 调用标准shell来执行'COMMAND STRING'.环境变量'SHELL'决定了那个shell被 运行。否则gdb使用'/bin/sh'. 'make'工具经常在开发环境中使用,所以你可以不用'shell'命令而直接打'make' `make MAKE-ARGS' 用指定的命令行变量来运行'make'程序,这等于使用'shell make MAKE-ARGS' GDB 命令 ************ 我们可以把一个gdb命令缩写成开头几个字母,如果这没有二意性你可以直接回车来 运行。你还可以使用TAB键让gdb给你完成接下来的键入,或向你显示可选择的命令, 如果有不止一个选择的话。 Command语法 ============== 一个gdb命令是一个单行的输入。长度没有限制。它一个命令开头,后面可以跟参量。 比如命令'step'接受一个参量表示单步执行多少步。你也可以不用参量。有的命令 不接受任何参量。 gdb命令只要没有二意性的话就可以被缩写。另外一些缩写作为一个命令列出。在某些 情况下二意也是允许的。比如's'是指定'step'的缩写,但还有命令'start'。你可以把 这些缩写作为'help'命令的参量来测试它们。 空行(直接回车)表示重复上一个命令。但有些命令不能重复比如象'run',就不会以这 种方式重复,另外一些当不小心重复会产生严重后果的命令也不能用这种方法重复。 'list'和'x'命令当你简单的打回车时,会建立新的变量,而不是简单的重复上一个命 令。这样你可以方便的浏览原代码和内存。 gdb还有一种解释RET的方法:分割长输出。这种方法就和'more'命令相似。由于这时经 常会不小心多打回车,gdb将禁止重复当一个命令产生很长的输出时。 任何用'#'开头一直到行尾的命令行被看作是注释。主要在命令文件中使用。 输入命令的技巧 ================== 前面已经提到过TAB键的使用。使用TAB键能让你方便的得到所要的命令。比如 在gdb中: (gdb)info bre <TAB>(键入info bre,后按TAB键) gdb能为你完成剩下的输入。它还能萎蔫提供选择的可能性。如果有两个以上可 能的话,第一次按<TAB>键,gdb会响铃提示,第二次则显示可能的选择。同样gdb 也可以为一些子命令提供快速的访问。用法与上相同。 上例中显示 (gdb)info breakepoints 你也可以直接打回车,gdb就将你输入的作为命令的可能的缩写。来判断执行。 如果你打入的缩写不足以判断,那么gdb会显示一个列表,列出可能的命令。同样的 情况对于命令的参数。在显示完后gdb把你的输入拷贝到当前行以便让你继续输入。 如果你只想看看命令的列表或选项,你可以在命令行下打M-?(就是按着ESC键 同时按SHIFT和?键)。你可以直接在命令行下打试试。 (gdb)<M-?> gdb会响铃并显示所有的命令。不过这种方式好象在远程调试是不行。当有的命令 使用一个字符串时,你可以用" ' "将其括起来。这种方法在调试C++程序时特别有用。 因为C++支持函数的重载。当你要在某个有重载函数上设断点时,不得不给出函数参数 以区分不同的重载函数。这时你就应该把整个函数用" ' "括起来。比如,你要在一个 叫name的函数上设断点,而这个函数被重载了(name(int)和name(float))。你将不得 不给出参变量以区分不同的函数。使用'name(int)'和'name(float)'。这里有个技巧, 你可以在函数名前加一个" ' "符号。然后打M-?. 你可以使用help命令来得到gdb的在线帮助。 `help' `h' 你可以使用help或h后面不加任何参数来得到一个gdb命令类的列表。 (gdb) help List of classes of commands: running -- Running the program stack -- Examining the stack data -- Examining data breakpoints -- Making program stop at certain points files -- Specifying and examining files status -- Status inquiries support -- Support facilities user-defined -- User-defined commands aliases -- Aliases of other commands obscure -- Obscure features Type "help" followed by a class name for a list of commands in that class. Type "help" followed by command name for full documentation. Command name abbreviations are allowed if unambiguous. (gdb) `help CLASS' 使用上面列出的help class作为help或h的参量,你可以得到单一的命令列表。 例如显示一个'status'类的列表。 (gdb) help status Status inquiries. List of commands: show -- Generic command for showing things set with "set" info -- Generic command for printing status Type "help" followed by command name for full documentation. Command name abbreviations are allowed if unambiguous. (gdb) `help COMMAND' 详细列出单个命令的资料。 `complete ARGS' 列出所有以ARGS开头的命令。例如: complete i results in: info inspect ignore This is intended for use by GNU Emacs. 除了使用'help'你还可以使用gdb的命令'info'和'show'来查询你程序的 状态,每个命令可以查询一系列的状态。这些命令以恰当的方式显示所有的 子命令。 `info' 此命令(可以缩写为'i')用来显示你程序的状态。比如,你可以使用info args 列出你程序所接受的命令行参数。使用info registers列出寄存器的状态。 或用info breakpoint列出在程序中设的断点。要获得详细的关于info的信息打 help info. `set' 这个命令用来为你的程序设置一个运行环境(使用一个表达式)。比如你 可以用set prompt $来把gdb的提示符设为$. `show' 与'info'相反,'show'命令用来显示gdb自身的状态。你使用'set'命令来 可以改变绝大多数由'show'显示的信息。比如使用show radix命令来显示基数。 用不带任何参变量的'set'命令你可以显示所有你可以设置的变量的值。 有三个变量是不可以用'set'命令来设置的。 `show version' 显示gdb的版本号。如果你发现gdb有bug的话你应该在bug-reports里加 入gdb的版本号。 `show copying' 显示版权信息。 `show warranty' 显示担保信息。 在gdb下运行你的程序 ************************** 当你在gdb下运行程序时,你必须先为gdb准备好带有调试信息的可执行文档。 还可以在gdb中为你的程序设置参变量,重定向你程序的输入/输出,设置环境变 量,调试一个已经执行的程序或kill掉一个子进程。 这里许多内容在早先的例子中都已经用到过,可以参见gdb(二)。 目录: * 编译:: 为调试编译带调试信息的代码 * 运行:: 运行你的程序 * 参变量:: 为你的程序设置参变量 * 运行环境:: 为你的程序设置运行时环境 * 设置工作目录:: 在gdb中设置程序的工作目录。 * 输入/输出:: 设定你程序的输入和输出 * 连接:: 调试一个已经运行的程序 * 结束子进程:: Kill子进程 * 进程信息:: 附加的进程信息 * 线程:: 调试带多线程的程序 * 多进程:: 调试带多进程的程序 为调试准备带调试信息的代码 =========================== 为了高效的调试一个程序,你需要使用编译器来产生附带调试信息的可执行代码 这些调试信息存储在目标文件中;描述了变量数据类型和函数声明,在原文件代码行 和执行代码之间建立联系。 为产生调试信息,当你使用编译器时指定'-g'选项,就可以为你的程序产生带有 调试信息的可执行代码。 有些c编译器不支持'-g'选项和'-O'选项,那你就有麻烦了,或者有别的方法产生 带调试信息的可执行代码,要不就没办法了。 gcc,GNU的c语言编译器支持'-g'和'-O'选项。这样你就可以产生带调试信息的且 优化过的可执行代码. 当你使用gdb来调试一个使用'-g','-O'选项产生的程序时,千万记住编译器为了优 化你的程序重新安排了你的程序。不要为运行次序与你原来设想的不同,最简单的例子 就是当你定义了一个变量但从未使用过它时,gdb中是看不到这个变量的--因为它已经 被优化掉了。 所以有时你不要使用'-O'选项,如果当你不用优化时产生的程序是正确的,而优化 过后变的不正确了,那么这是编译器的bug你可以向开发者提供bug-reports(包括出错 的例子)。 早期的GUN C语言编译器允许'-gg'选项,也用来产生调试信息,gdb不再支持这种格 式的调试信息,如果你的编译器支持'-gg'选项,请不要使用它。 `run' `r' 使用'run'命令在gdb下启动你的程序。你必须先指定你程序的名字(用gdb的命令行 参数)或使用'file'命令,来指定文件名。如果你在一个支持多进程的环境下运行你的程 序'run'命令创建一个子进程然后加载你的程序。如果环境不支持进程,则gdb直接调到 程序的第一条命令。 一些父进程设置的参量可以决定程序的运行。gdb提供了指定参量的途径,但你必须 在程序执行前设置好他们。你也可以在运行过程中改变它们,但每次改变只有在下一次 运行中才会体现出来。这些参量可以分为四类: ---参数 你可以在使用'run'命令时设置,如果shell支持的话,你还可以使用通配符,或 变量代换。在UNIX系统中你可以使用'shell环境变量'来控制shell。 ---环境: 你的程序一般直接从gdb那里继承环境变量。但是你可以使用'set environment' 命令来设置专门的环境变量。 ---工作目录 你的程序还同时从gdb那里继承了工作目录,你可以使用'cd'命令在gdb中改变工作 目录。 ---标准输入/输出 你的程序一般使用与gdb所用的相似的设备来输入/输出。不过你可以为你的程序的 输入/输出进行重定向。使用'run'或'tty'命令来设置于gdb所用不同的设备。 *注意:当你使用输入/输出重定向时,你将不能使用无名管道来把你所调试的程序的输出 传给另一个程序。这样gdb会认为调试程序出错。 当你发出'run'命令后,你的程序就开始运行。 如果你的符号文件的时间与gdb上一次读入的不同,gdb会废弃原来的符号表并重新读 入。当前的断点不变。 程序环境 ========================== “环境”包括了一系列的环境变量和它们的值。环境变量一般记录了一些常用的信息, 比如你的用户名,主目录,你的终端型号和你的运行程序的搜索路径。一般你可以在shell 下设置环境变量,然后这些变量被所有你所运行的程序所共享。在调试中,可以设置恰当 的环境变量而不用退出gdb. `path DIRECTORY' 在'PATH'环境变量前加入新的内容('PATH'提供了搜索执行文件的路径)。对于gdb和 你的程序来说你也许要设置一些专门的路径。使用':'或空格来分隔。如果DIRECTORY已经 在路径中了,这个操作将会把它移到前面。 你可以使用串'$cmd'来代表当前路径,如果你用'.'的话,它代表你使用'path'命令 时的路径,gdb将在把DIRECTORY加入搜索路径前用'.'代替当前路径 `show paths' 显示当前路径变量的设置情况。 `show environment [VARNAME]' 显示某个环境变量的值。如果你不指明变量名,则gdb会显示所有的变量名和它们的 内容。environment可以被缩写成'env' `set environment VARNAME [=] VALUE' 设置某个环境变量的值。不过只对你所调试的程序有效。对gdb本身是不起作用的。 值可以是任何串。如果未指定值,则该变量值将被设为NULL. 看一个例子: % |
相关阅读 更多 +
排行榜 更多 +