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

调用LLVM IR函数返回结构体时出现bus error的原因排查

自定义语言返回结构体触发Bus Error的原因分析

问题场景

我在自定义语言中编写了如下代码:

type Struct:
    x: Bool

Struct { x: true }

前端生成的对应LLVM IR代码:

%Struct = type { i1 }

define %Struct @execute() {
  %1 = alloca %Struct, align 8
  %Struct.x = getelementptr inbounds %Struct, ptr %1, i32 0, i32 0
  store i1 true, ptr %Struct.x, align 1
  %2 = load %Struct, ptr %1, align 1
  ret %Struct %2
}

调用该函数时会触发63069 bus error。

但编写代码Struct { x: true }.x时,生成的LLVM IR代码可正常执行:

%Struct = type { i1 }

define i1 @execute() {
  %1 = alloca %Struct, align 8
  %Struct.x = getelementptr inbounds %Struct, ptr %1, i32 0, i32 0
  store i1 true, ptr %Struct.x, align 1
  %x = getelementptr inbounds %Struct, ptr %1, i32 0, i32 0
  %2 = load i1, ptr %x, align 1
  ret i1 %2
}

调试器显示的错误翻译为:

线程1:EXC_BAD_ACCESS(代码=2,地址=0x16f237ff7)

问题原因

核心问题出在结构体的内存对齐与返回值处理上:

  • 结构体大小与对齐不匹配:%Struct类型是仅含1字节i1的结构体,但alloca时指定了align 8,将结构体实例放在8字节对齐的地址上。直接load %Struct并返回整个结构体时,LLVM会尝试按8字节对齐要求加载数据,但实际只有1字节有效数据,剩下7字节是未初始化的栈空间,触发内存访问越界。
  • 调用约定的适配问题:多数平台调用约定中,小型结构体的返回依赖寄存器,但结构体对齐要求高于实际大小时,LLVM生成的代码会错误访问超出结构体实际范围的内存,导致Bus Error。
  • 正常案例对比:返回单个i1值时,仅加载1字节数据,对齐要求与实际大小匹配,不会触发越界,因此可正常执行。

修复方案

  • 调整alloca的对齐值,匹配结构体自然对齐:将alloca %Struct, align 8改为alloca %Struct, align 1(i1的自然对齐为1字节)。
  • 显式指定结构体对齐属性:比如用%Struct = type <{ i1 }> align 8,让结构体实际大小填充到8字节,确保加载时访问的内存合法。

内容的提问来源于stack exchange,提问作者gavrilikhin.d

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:42:43