限制与支持
故障排查
分离编译器、binder、Go ABI、runtime 与平台问题,逐层定位失败。维护者C2Go contributors首先确定失败发生在哪个阶段。compiler diagnostic、manifest validation error、Go build error 和 runtime crash 需要不同证据,不应把整条管线当成一个黑盒调试。
找不到头文件或声明不正确
**现象:**找不到 c2go.h 或 libc 声明,或者错误选择了宿主系统 libc header。
使用 SDK 中的 c2go-clang,并保持 SDK 目录结构完整。不要加入 host libc include path。c2go.h 应只存在于 Clang resource tree,顶层 include/ 属于 c2go-libc。
c2go-clang -print-resource-dir
c2go-clang --target="$C2GO_TARGET" -fc2go -E -v input.c
Manifest 与汇编不一致
现象:c2go-bind 报告 target、version、epoch、symbol、type 或 callback 冲突。
删除陈旧生成输入,同时重建 .s 与 JSON manifest。确认 manifest 中的 pkgpath 就是传给 c2go-clang -fc2go-package 的最终 Go import path,并且不要在共享 build directory 中让多个 target 复用输出文件名。
Go 兼容性探测失败
binder 会检查当前 Go 工具链的 frame-accounting contract。应使用协同版本支持的 Go(当前为 Go 1.25.x 或 1.26.x),并固定匹配的 c2go-libc provider。不要把 --skip-go-probe 变成永久 workaround;它只用于受控诊断。
go version
c2go-bind --version
内存归属诊断
managed-to-unmanaged call、store 或 return warning 表示丢失精确 GC 跟踪。应追踪指针分配与所有权,而不是把它转换成整数。cross-type layout 或 unmanaged record 含 managed field 的 error 则必须修改数据表示。
迁移 warning 审核完成后,CI 中建议启用 -Werror=c2go-managed-as1。
栈指针被堆或全局状态保留
**现象:**出现 -Wc2go-managed-stack-escape、c2go-lto: stack->heap,某个指针在函数调用后失效,或程序在栈增长后发生 runtime fault。
不能静默忽略这个 finding。应改为带正确类型信息的 gc_malloc storage、由 native API 指定 allocator 且释放责任明确的 storage,或稳定 handle。前端只能捕获直接语法;必须对每个 translation unit 的 bitcode 单独运行 c2go-lto。普通 driver 构建采用 nonfatal 策略,不等于审计干净。完整流程见栈指针逃逸安全。
无法解析原生符号
确认函数只有声明、没有 C2Go 定义,符号确实被引用,并且 binder 收到正确的 -l 与 -L。普通 C 函数声明默认就是 native import,不要求写 unmanaged extern。检查动态库架构与 target 是否一致;Windows 还要核对精确导出符号拼写。
Callback 只在某个平台失败
将签名与兼容矩阵对照。Windows callback 会有意拒绝浮点和部分 record 形状。可以把 callback 简化为指针/整数参数,或者提供 ABI 明确且经过测试的 native shim。
Runtime fault
保留精确的生成 .go、.s、manifest、工具版本、target triple 和 Go stack trace。把问题缩减到最小函数,并分别使用 -O0 与 -O2 复现。只在一个优化级别失败是重要 compiler evidence,不应在没有回归测试的情况下静默发布另一个级别。
检查 pointer ownership、独立 stack-address escape 审计、inline assembly clobber 和跨 native boundary 的调用。compiler test 通过不能替代使用生成 package 的端到端 go test。
有效的问题报告
报告问题时至少包含:
- 缩减后的最小 C 源码;
- 完整 compiler 与 binder 命令;
- target triple 与
go version; c2go-clang、c2go-lto、c2go-bind和 c2go-libc 版本;- 生成 manifest 与相关汇编片段;
- 完整 diagnostic 或 Go stack trace。
再分发 package 或 SDK 前,请查看授权边界。