使用gdb调试C代码

asi*_*mes 2 c terminal gcc gdb

这是一个家庭作业,我只是想要gdb的帮助,而不是具体的答案.

我没有任何gdb的经验和很少的终端体验.我在线跟踪了一个简单的示例,使用gdb调试了一些代码,但在示例中,gdb指出在运行代码时发生了问题.当我试图模仿这个任务的过程时,gdb没有说什么.我对C仍然有点新,但是当我查看代码并且gdb没有说什么时,我可以看到问题.

假设文件名为test.c,在终端我输入gcc test.c并且它给了我一个警告,因为printf()它存在但#include <stdio.h>不是,这很好,因为这应该是错误的.

它也会产生一个a.out,如果我在终端中使用./a.out运行它没有任何反应.终端刚准备好接下来没有消息的输入.如果我键入gdb ./a.out然后运行它只是告诉我程序正常退出.

有人可以指出我要做什么让gdb指向错误吗?

// insertion sort, several errors

int X[10],  // input array
    Y[10],  // workspace array  
    NumInputs,  // length of input array
    NumY = 0;  // current number of 
               // elements in Y

void GetArgs(int AC, char **AV) {
    int I;
    NumInputs = AC - 1;
    for (I = 0; I < NumInputs; I++) X[I] = atoi(AV[I+1]);
}

void ScootOver(int JJ) {
    int K;
    for (K = NumY-1; K > JJ; K++) Y[K] = Y[K-1];
}

void Insert(int NewY) {
    int J;
    if (NumY = 0) { // Y empty so far, 
        // easy case
        Y[0] = NewY;
        return;
    }
    // need to insert just before the first Y
    // element that NewY is less than
    for (J = 0; J < NumY; J++) {
        if (NewY < Y[J]) {
            // shift Y[J], Y[J+1],... rightward 
            // before inserting NewY
            ScootOver(J);
            Y[J] = NewY;
            return;
        }
    }
}

void ProcessData() {
    // insert new Y in the proper place
    // among Y[0],...,Y[NumY-1]
    for (NumY = 0; NumY < NumInputs; NumY++) Insert(X[NumY]);
}

void PrintResults() {
    int I;
    for (I = 0; I < NumInputs; I++) printf("%d\n",Y[I]);
}

int main(int Argc, char ** Argv) {
    GetArgs(Argc,Argv);
    ProcessData();
    PrintResults();
}
Run Code Online (Sandbox Code Playgroud)

编辑:代码不是我的,它是作业的一部分

lus*_*oog 6

有各种各样的错误.有些可以被程序(编译器,操作系统,调试器)检测到,有些则无法检测到.

如果检测到任何约束违规,则需要编译器(通过C标准)发出错误.未处于标准合规模式时,它可能会发出其他错误和警告.如果添加-Wall-Wextra选项,编译器将为您提供更多错误诊断.如果启用优化(-O0通过-O3设置不同的优化级别),编译器可能能够检测到更多错误,但如果您想在调试器中单步执行,则可能希望跳过优化,因为优化器会使更难调试器向您显示相关的源代码行(有些可能会重新排序,有些可能会被删除).

操作系统将检测涉及遍历坏指针(通常)或系统调用的错误参数或(通常)浮点除零的错误.

但是任何不会导致程序崩溃的都是语义错误.而这些需要人脑来寻找它们.

因此,正如Brian所说,您需要设置断点并单步执行该程序.并且,正如jweyrich所说,您需要编译程序-g以添加调试符号.

您可以检查变量print(例如,print Argc将告诉您行上有多少命令行参数run).而且display将增加变数,这只是每个提示之前显示的列表.如果我是通过for循环调试Insert,我可能会做display Jdisplay Y[J],next,并按下回车键一堆倍看着计算的进展.

如果你的断点是深度嵌套的,你可以得到一个"堆栈转储" backtrace.

next将带您到下一个语句(分号后面).step将带您进入函数调用和函数的第一个语句.请记住:如果您单步执行函数并转到'return'语句,请使用step在调用语句中输入下一个函数调用; next在返回时使用来完成调用语句(并且只是在语句中执行任何剩余的函数调用,而不提示).你可能还不需要知道这一点,但如果你这样做,你就去了.

  • +1.我还建议使用`-g3 -O0`进行编译,因此gdb可以打印文件名,符号和源代码行.另外,我建议使用`-Wall -Wextra`(和可能的'-pedantic`)一起编译的好习惯. (3认同)