⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1059.html

📁 著名的linux英雄站点的文档打包
💻 HTML
📖 第 1 页 / 共 3 页
字号:
                        <input maxlength=100 size=30 name=keyword2>
                      </div>
                    </td>
                  </tr></tbody> 
                </table>
              </form>
            </TD>
            <TD rowSpan=2><IMG src="images/header_r1_c7.gif" tppabs="http://www.linuxhero.com/docs/images/header_r1_c7.gif" width=26 border=0 name=header_r1_c7></TD>
          <TD><IMG height=83 src="images/spacer.gif" tppabs="http://www.linuxhero.com/docs/images/spacer.gif" width=1 border=0></TD></TR>
        <TR>
          <TD background="images/bgline.gif" tppabs="http://www.linuxhero.com/docs/images/bgline.gif"><IMG height=22 
            src="images/header_r2_c1.gif" tppabs="http://www.linuxhero.com/docs/images/header_r2_c1.gif" width=296 border=0 
            name=header_r2_c1></TD>
          <TD background="images/bgline.gif" tppabs="http://www.linuxhero.com/docs/images/bgline.gif" colSpan=5>
              <DIV align=right><FONT class=normalfont>当前位置: 
              <A href="index.html" tppabs="http://www.linuxhero.com/docs/index.html">本站首页</A>
              <font color="#FF6699">&gt;&gt;</font>
<A href="type14.html" tppabs="http://www.linuxhero.com/docs/type14.html">编程技术</A>                 | <A href="copyright.html" tppabs="http://www.linuxhero.com/docs/copyright.html">版权说明</A></font></DIV>
            </TD>
          <TD><IMG height=22 src="images/spacer.gif" tppabs="http://www.linuxhero.com/docs/images/spacer.gif" width=1 
        border=0></TD></TR></TBODY></TABLE>
      <TABLE cellSpacing=10 cellPadding=0 width="100%" bgColor=#ffffff 
        border=0>
         <TR>
          <TD>
            <TABLE cellSpacing=0 cellPadding=3 width="100%" border=0>
              
              <TR>
                <TD vAlign=top align=middle width="60%">
                  <TABLE cellSpacing=0 cellPadding=0 width="100%" 
                  background="images/back.gif" tppabs="http://www.linuxhero.com/docs/images/back.gif" border=0>
                    <TBODY>
                    <TR>
                        <TD vAlign=top width="80%"> 
                          <DIV align=center>
                        <FORM action="search.html" tppabs="http://www.linuxhero.com/docs/search.html" method=get>
                            </FORM>
                        <TABLE cellSpacing=0 cellPadding=0 width="95%" 
                          border=0><TBODY>
                          <TR>
                            <TD background="images/bgi.gif" tppabs="http://www.linuxhero.com/docs/images/bgi.gif" 
                          height=30></TD></TR></TBODY></TABLE>
                        <TABLE cellSpacing=0 cellPadding=3 width="95%" 
                        align=center border=0>
                          <TBODY>
                          <TR>
                            <TD>
                              <TABLE cellSpacing=0 cellPadding=3 width="100%" 
                              border=0>
                                <TBODY>
                                <TR>
                                      <TD vAlign=top> 
<p><FONT class=normalfont><B><font color=blue>gdb基础</font></B></FONT><BR><FONT class=smallfont color=#ff9900>2004-04-23 15:18 pm</FONT><BR><FONT class=normalfont>作者:作者<br>来自:Linux知识宝库<br>联系方式:无名<br><br>就调试本机可执行文件(即不是 Java* 或 perl 等)而言,使用 gdb 就对了。gdb 可用于源代码级调试,以及跟踪没有源代码的程序或检查某个终止的程序留下的核心文件。遗憾的是,当您从来没有使用过它,或者已经有一段时间没有使用它时,使用它来做这些工作可能很困难。图 1 展示了使用 gdb 来进行调试所需的每个命令。<br>
<br>
<br>
Command Description<br>
file        load program<br>
b    set breakpoint<br>
r       run<br>
c       continue<br>
s       step (line)<br>
si      step (machine instruction)<br>
n       next (step over function call)<br>
finish  run until function returns<br>
i r     show all registers<br>
i r    show specific register<br>
l       list source<br>
p         display value<br>
set args  set command line arguments<br>
<br>
图 1<br>
<br>
  要将 gdb 用作源代码级调试器,请确保在包括调试符号的情况下编译程序;这就是 gcc 的 -g 选项。对于启动 gdb,您可以通过输入 gdb programname(此例中是 gdb simple),或者通过单独运行 gdb 本身并使用 file 命令加载可执行文件来达到目的。<br>
<br>
  要设置基本的断点,您可以在某个函数名称或行号上中断。例如,b 27 将在当前文件的第 27 行上设置了一个断点。有两种使用函数名称的方式:b main 在函数 main 中的第一行可执行代码上中断,b *main 在 main 的入口地址上设置一个断点(如果打算单步调试函数的每条指令,这样是很有用的)。<br>
<br>
  一旦设置了第一个断点,可使用 run 或 r 来启动程序并运行到第一个断点。还可以不带任何断点运行程序,如果您不知道程序是在何处崩溃的,这样将很有帮助。当您命中一个断点 c 或 continue 时,程序将恢复执行,直至命中下一个断点。<br>
<br>
  step“单步”调试源代码行。Step instruction (si) 单步调试机器代码行(当您单步调试优化过的代码时,si 指令可能特别有用,这将在后面介绍)。 next 工作起来就像 step,但是它不跟踪进入函数调用(如果的确错误地跟踪进入了函数调用,可使用 finish 来完成该函数,然后在它返回的地方中断)。<br>
<br>
  单独的 info register(i r)本身显示所有寄存器的值(浮点值除外),不过您可以指定一个寄存器名称。在 31 位系统上,通用寄存器被命名为 gpr0、gpr1、gpr2,等等;在 64 位系统上,它们被命名为 r0、r1、r2,等等。浮点寄存器遵循相同的命名约定:在 31 位系统上是 fpr0、fpr1、fpr2,等等;在 64 位系统上是 f0、f1、f2,等等。<br>
<br>
  “l”列出程序当前停止位置周围的源代码。您还可以指定开始列出代码的行号或要列出的函数名称。print 允许您打印程序中任何变量的值。 print 的一个最好的优点在于,它会为您取出一个结构中的所有值,或允许您直接引用该结构的一部分:<br>
<br>
<br>
Breakpoint 1, main () at simple.c:30<br>
30 boink.boik = &r1;<br>
(gdb) print boink<br>
$3 = {boik = 0x0}<br>
(gdb) print boink.boik<br>
$4 = (int *) 0x0<br>
<br>
  最后,set args 为程序设置命令行参数。您也可以在执行 run 时指定命令行参数,但是 set args 将使参数在 run 的多次执行中都有效。<br>
<br>
<br>
gdb Post Mortem<br>
<br>
  当程序意外地终止时,内核会尝试产生一个核心文件,以图判断发生了什么错误。然而,核心文件通常不是在默认设置值下产生的。这可以使用 ulimit 命令来改变。ulimit -c unlimited 帮助确保您获得应用程序的完整核心文件。<br>
<br>
  虽然核心文件当前仅提供多线程应用程序中的有限的值,不过 2.5 版的开发内核已开始处理这个问题。预计 2.6 版的内核中会提供一些理想的线程改进。<br>
<br>
<br>
Command Description<br>
file         load program<br>
core    load core file<br>
bt      back trace<br>
where   same as back trace<br>
i f     frame information<br>
up      move up stack<br>
down    move down stack<br>
frame  jump to frame<br>
disassem        display function’s machine code<br>
i locals        display local variable values<br>
<br>
图 2<br>
<br>
  图 2 突出显示了一系列便利的 post mortem 命令。<br>
<br>
<br>
(gdb) file simple<br>
Reading symbols from simple...done.<br>
(gdb) core core<br>
Core was generated by `./simple’.<br>
Program terminated with signal 11, Segmentation fault.<br>
Reading symbols from /lib/libc.so.6...done.<br>
Loaded symbols for /lib/libc.so.6<br>
Reading symbols from /lib/ld.so.1...done.<br>
Loaded symbols for /lib/ld.so.1<br>
#0  0x400ab738 in memcpy () from /lib/libc.so.6<br>
(gdb) where<br>
#0  0x400ab738 in memcpy () from /lib/libc.so.6<br>
#1  0x40066e in main () at simple.c:34<br>
#2  0x40041eb8 in __libc_start_main () from /lib/libc.so.6<br>
#3  0x4004ac in _start ()<br>
(gdb) i f<br>
Stack level 0, frame at 0x7ffff7a0:<br>
 pswa = 0x400ab738 in memcpy; saved pswa 0x0<br>
 (FRAMELESS), called by frame at 0x7ffff7a0<br>
 Arglist at 0x7ffff7a0, args:<br>
 Locals at 0x7ffff7a0, Previous frame’s sp is 0x0<br>
(gdb) up<br>
#1  0x40066e in main () at simple.c:34<br>
34        memcpy (doink.boik, boink.boik, sizeof(boink.boik));<br>
(gdb) i locals<br>
doink = {boik = 0x4019a0}<br>
boink = {boik = 0x0}<br>
(gdb) ptype boink.boik<br>
type = int *<br>
(gdb) print *boink.boik<br>
Cannot access memory at address 0x0<br>
(gdb) print *doink.boik<br>
$1 = 4<br>
<br>
图 3<br>
<br>
  图 3 简要显示了一个核心程序的完整运行过程。同样,我们使用了 simple 程序。 但不是手动加载程序和核心文件,而是从命令行调入:<br>
<br>
<br>
gdb simple core<br>
<br>
  在加载符号之后,gdb 将指出程序在何处终止。注意当前帧 #0 包含前一节中计算的地址。gdb 将在 31 位系统上截去高位,仅显示指令地址。 还要注意帧 #1 包含 gpr14 中的返回地址。<br>
<br>
  接着往下看,i f 提供了关于当前堆栈帧的信息。在堆栈帧中往上移到 main,这就是我们离开该帧的地方(即调用 memcpy 的地方)。简单的 i locals 提供了传递给 memcpy 的变量的值,其中一个变量 boink.boik 的值为 0x0。使用 ptype 来检查变量类型,这样将确认它是一个整型指针,并且如果目的是为了拷贝内容到其中,它就不应该是 0x0。最后一个选项是使用 print,通过一个星号(*)来解除指针引用,以便接收值。<br>
<br>
处理优化过的代码<br>
<br>
  先前,我曾提到当您在源代码级调试优化过的代码时,gdb 可能变得有点棘手。编译器优化一些代码的执行顺序以最大化性能。图 4 显示了这样一个例子。您可以看到行号如何从 32 切换到 30 然后又切换回 32。<br>
<br>
<br>
(gdb) break main<br>
Breakpoint 1 at 0x800007a8: file simple.c, line 32.<br>
(gdb) r<br>
Starting program: /home/grundym/foo/simple<br>
Breakpoint 1, main () at simple.c:32<br>
32        do_one_thing(&doink);<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -