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

将C的read_record替换为汇编后,程序main退出时触发段错误

排查MacBook M2上汇编实现read_record后main退出时的段错误(dyld访问0x0地址)

问题概述

课程作业要求将指定C函数用汇编实现并保留原有行为:程序从标准输入读取含last_name、first_name、id的记录,存入RECORD* heap[]数组后执行堆排序。仅替换read_record函数后,在MacBook M2上运行时,main函数退出后触发段错误,错误表现为dyld尝试访问0x0地址的(%rdi)。

已排除的可能性:

  • 栈损坏:lldb调试确认read_record调用前后%rsp、%rbp无变化
  • 内存泄漏:AddressSanitizer和leaks工具检测无泄漏,main中已释放所有记录

核心排查方向

1. ARM64调用约定合规性(MacOS环境)

MacOS ARM64的调用约定要求:

  • 被调用者必须保存并恢复非易失性寄存器(x19-x29、fp、lr),若汇编代码修改了这些寄存器但未做保存/恢复操作,会破坏调用者(main)的上下文,导致程序退出时栈帧处理出错。
  • 函数返回指针类型值时,必须将正确地址存入x0寄存器。若read_record返回的RECORD*指针异常(比如未正确初始化的地址、逻辑上不该返回的NULL),会埋下后续错误隐患,最终在退出阶段触发dyld的内存访问错误。

2. read_record的内存操作正确性

  • 堆内存初始化与越界检查:检查汇编中malloc调用后的处理逻辑:若malloc返回NULL(分配失败),代码是否做了正确处理?另外,即使leaks未检测到泄漏,堆内存越界写入(比如字符串复制时超出NAME_LEN限制)可能破坏堆元数据,程序正常运行时无异常,但退出时dyld清理堆结构会触发段错误。
  • 结构体字段访问对齐:确认汇编中对RECORD结构体字段的访问偏移是否与C代码完全一致(比如last_name偏移0、first_name偏移NAME_LEN、id偏移NAME_LEN*2),ARM64下结构体的内存对齐要求是否被满足,避免因字段错位导致后续内存操作异常。

3. 函数收尾流程正确性

  • 检查汇编函数的返回流程:是否正确执行ret指令?返回前是否完全恢复了所有被修改的非易失性寄存器?比如若修改了x29(帧指针)但未恢复,main函数退出时的栈帧回溯会直接出错。
  • 确认read_record返回的RECORD*是否完全符合C函数预期:所有字段是否正确赋值,无遗漏或错误赋值(比如字符串指针未正确指向分配的内存、id值未正确读取)。

代码验证建议

提供完整C代码与汇编实现后,可重点验证以下细节:

  • 调用fscanf时的参数传递是否符合ARM64约定:前8个参数通过x0-x7传递,需确认stdin、格式串、last_name指针、first_name指针、id指针是否被正确放入对应寄存器。
  • malloc分配RECORD内存后,是否正确为字符串字段分配内存并完成读取内容的复制,无内存地址计算错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:05:13