【问题标题】:How to use lldb to debug the segmentation fault如何使用lldb调试分段错误
【发布时间】:2016-10-16 19:44:14
【问题描述】:

我通过为我的程序运行 LLDB 得到了这个异常。

但是,这个异常并没有给我任何找到根本原因的具体线索。

当然,根据经验,我可能无法正确访问内存。

有没有办法通过 LLDB 找到根本原因?谢谢

continue to play (y/n)? y
Process 30020 stopped
* thread #1: tid = 0x24b72, 0x00007fff893c8365 libsystem_platform.dylib`_platform_strncmp + 325, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x79)
    frame #0: 0x00007fff893c8365 libsystem_platform.dylib`_platform_strncmp + 325
libsystem_platform.dylib`_platform_strncmp:
->  0x7fff893c8365 <+325>: movzbq (%rsi,%rcx), %r8
    0x7fff893c836a <+330>: subq   %r8, %rax
    0x7fff893c836d <+333>: jne    0x7fff893c837d            ; <+349>
    0x7fff893c836f <+335>: testq  %r8, %r8
(lldb)
error: No auto repeat.

代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>

const int USER_INPUT_SIZE_EACH_LINE = 999;

void draw_middle_lines(char *middle_line, int width) {
    printf("%s", middle_line);
    for (int i = 2; i < width; i++) {
        printf(" ");
    }
    printf("%s\n", middle_line);
}

void draw_bound_line(char *bound_char, int width) {
    for (int i = 0; i < width; i++) {
        printf("%s", bound_char);
    }
    printf("\n");
}


void clearNewline(char *line, int max_len) {
    for (int i = 0; i < max_len; i++) {
        if (line[i] == '\n') {
            line[i] = '\0';
        }
    }
}

char **ask_user_preference() {
    const int NUM_OF_PROMPTS = 4;
    char *prompt[] = {
            "please input height:",
            "please input width:",
            "please input horizontal char:",
            "please input vertical char:",
    };
    char **preference;
    preference = malloc(NUM_OF_PROMPTS);
    for (int i = 0; i < NUM_OF_PROMPTS; i++) {
        preference[i] = malloc(USER_INPUT_SIZE_EACH_LINE);
        memset(preference[i], 0, sizeof(char) * USER_INPUT_SIZE_EACH_LINE);
        printf("%s", prompt[i]);
        fgets(preference[i], USER_INPUT_SIZE_EACH_LINE, stdin);
        clearNewline(preference[i], USER_INPUT_SIZE_EACH_LINE);
    }
    return preference;
}

void draw(int w, int h, char *bound_char, char *middle_char) {
    draw_bound_line(bound_char, w);
    for (int i = 2; i < h; i++) {
        draw_middle_lines(middle_char, w);
    }
    draw_bound_line(bound_char, w);
}

void clr_input_buffer() {
    for (;;) {
        int c = getchar();
        if (c == EOF || c == '\n')
            break;
    }

}

int main() {
    char *cont;
    do {
        char **pref = ask_user_preference();
        int height = atoi(pref[0]);
        int width = atoi(pref[1]);
        char *bound_char = pref[2];
        char *middle_char = pref[3];
        draw(width, height, bound_char, middle_char);
        printf("continue to play (y/n)? ");
        fgets(cont, 10, stdin);
        if (strncmp(cont, 'y', 1) != 0) {
            break;
        }
    } while (1);
    printf("BYE BYE~");
    return 0;
}

【问题讨论】:

    标签: c lldb


    【解决方案1】:

    函数调用

    strncmp(cont, 'y', 1)
    

    可能会导致段错误,因为'y' 是作为内存位置传递的字符值。我建议

    strncmp(cont, "y", 1)
    

    虽然我不确定你比较的意义。无论如何,我建议这会更好

    toupper(cont[0]) == 'Y'
    

    我把比较的感觉留给你。最后,请启用所有可能会捕获此问题的编译器警告。

    【讨论】:

    • 嗨,谢谢你的好点子。分段问题已修复。但是,有没有办法让这个问题更容易被发现?看来您是在使用自己的经验来修复它,而不是借助调试器或异常消息^^
    • 编译器确实会发出警告。
    • 事实上,MSVC 编译器发出 两个 警告:一个关于参数类型,一个关于间接级别。
    • 这个答案仍然没有回答如何用 lldb 调试这个错误的原始问题...
    • @Dr_Zaszuś 这个答案是您可以通过查看编译器输出在调试器之前捕获错误。您甚至不应该运行带有警告的代码。捕获这个错误很简单。
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2016-09-07
    • 2013-01-06
    • 2013-05-19
    • 2012-01-06
    • 2023-03-24
    • 1970-01-01
    相关资源
    最近更新 更多