2

这是一个家庭作业,我只想要 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();
}

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

4

2 回答 2

6

有不同种类的错误。有些可以被程序(编译器、操作系统、调试器)检测到,有些则不能。

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

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

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

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

您可以检查变量print(例如,print Argc将告诉您有多少命令行参数run在线)。并将display变量添加到每个提示之前显示的列表中。如果我通过 in 中的 for 循环进行调试Insert,我可能会做display Jand display Y[J], next,然后按 enter 很多次来观察计算进度。

如果您的断点嵌套很深,您可以使用backtrace.

next将带您进入下一条语句(在分号之后)。step将带您进入函数调用和函数的第一条语句。请记住:如果您单步执行一个函数并进入“return”语句,请使用step在调用语句中输入下一个函数调用;在 return 处使用next来完成调用语句(并且只执行语句中剩余的任何函数调用,而不提示)。你可能还不需要知道这一点,但如果你知道,那就去吧。

于 2013-01-24T05:42:19.183 回答
1

gdb,做break main,然后run

从那里开始,next或者step直到你发现哪里出错了。

于 2013-01-24T05:25:34.707 回答