You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言汇编器get_label函数触发SIGSEGV段错误求助

问题:汇编器get_label函数触发段错误(SIGSEGV)

开发C语言汇编器时,get_label函数处理以下汇编文件第二行的LOOP:时触发SIGSEGV(段错误),但第一行的MAIN:可正常处理。怀疑是内存问题,但作为新手不知如何排查。试过strdup函数无效,改用自定义PUT_WORD宏配合malloc实现后仍未解决,寻求修复方法及相关建议。

测试用汇编文件内容

MAIN: mov @r3 ,LENGTH
LOOP: jmp L1
mcro m1
...rest of file

get_label函数代码

char *get_label(char *token) {
    char *label;
    label = (char *) malloc(MAX_LABEL_LEN); //<-- THIS LINE

    if (label == NULL) {
        printf("ERROR: Memory allocation failed for label in line %d.\n", line_count);
    }
    char *label_ptr = label;
    PUT_WORD(label_ptr, token);


    if(is_label_decleration(label))
        {
        label[strlen(label) - 1] = '\0';
        }

    if (get_commend(label) != NOT_OPCODE)
        {/*checks if the label is a command name*/
        valid_file = NOT_VALID;
        printf("ERROR: the label %s with invalid name at line %d, can't use command keyword as label\n", label,
               line_count);
        return NULL;
        }
    if (!isalpha(*label))
        {
        valid_file = NOT_VALID;
        printf("ERROR: the label %s with invalid name at line %d, can't start label with non letter character\n",
               label, line_count);
        return NULL;
        }
    label_ptr = label;
    while (isalnum(*++label_ptr));
    if (*label_ptr != '\0')
        {
        valid_file = NOT_VALID;
        printf("ERROR: the label %s with invalid name at line %d, can't have label with non letter or digit character\n",
               label, line_count);
        return NULL;
        }

    return label;
}

问题分析与修复建议

核心问题点

  1. malloc失败未终止流程:当malloc返回NULL时,仅打印错误但继续执行后续代码,操作空指针直接触发段错误。
  2. PUT_WORD宏的安全性问题:如果宏未正确给字符串添加终止符\0,strlen会读取越界;若token长度超过MAX_LABEL_LEN-1,会导致缓冲区溢出。
  3. 字符串长度未检查:调用label[strlen(label)-1]前未判断字符串长度,若label为空,会访问label[-1]触发段错误。
  4. 循环越界风险:while (isalnum(*++label_ptr))未先检查是否到达字符串终止符,若字符串无\0,会持续读取非法内存。

具体修复步骤

  1. 处理malloc失败的情况:分配失败后直接返回NULL,避免后续操作空指针
if (label == NULL) {
    printf("ERROR: Memory allocation failed for label in line %d.\n", line_count);
    return NULL; // 新增返回逻辑
}
  1. 替换为安全的字符串复制:避免PUT_WORD的潜在问题,用strncpy确保不溢出并手动添加终止符
// 替换PUT_WORD(label_ptr, token);
strncpy(label, token, MAX_LABEL_LEN - 1);
label[MAX_LABEL_LEN - 1] = '\0'; // 强制终止,防止溢出
  1. 添加字符串长度检查:修改标签处理逻辑,避免访问非法内存
if(is_label_decleration(label)) {
    size_t len = strlen(label);
    if (len > 0) {
        label[len - 1] = '\0';
    } else {
        valid_file = NOT_VALID;
        printf("ERROR: Empty label declaration at line %d.\n", line_count);
        free(label); // 释放已分配内存
        return NULL;
    }
}
  1. 修复循环逻辑:先检查终止符,再判断字符类型,避免越界
label_ptr = label;
while (*label_ptr != '\0' && isalnum(*label_ptr)) {
    label_ptr++;
}
if (*label_ptr != '\0') {
    valid_file = NOT_VALID;
    printf("ERROR: the label %s with invalid name at line %d, can't have label with non letter or digit character\n", label, line_count);
    free(label); // 释放内存
    return NULL;
}
  1. 内存泄漏防护:所有错误分支返回NULL前,记得用free(label)释放已分配的内存,避免内存泄漏。

调试建议

用gdb工具定位崩溃点:

  • 编译程序时添加-g参数生成调试信息:gcc -g your_assembler.c -o assembler
  • 运行gdb ./assembler,输入run test.asm启动程序
  • 崩溃后输入bt查看调用栈,确认具体是哪一行代码触发的段错误,精准定位问题。

内容的提问来源于stack exchange,提问作者Itay Segev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:39:50