GCC 嵌套函数、宽指针与无 Trampoline 方案(二)
来源:uecker.codeberg.page — 2026-07-18
本文作者 Martin Uecker 介绍了 GCC 嵌套函数(nested functions)在避免运行时 trampoline 方面的两项最新进展。GCC 16 已正式保证不捕获父函数局部变量的嵌套函数无需 trampoline,从而消除了可执行栈带来的安全隐患;GCC 17 开发分支则合并了一对新的内置函数,使得带变量捕获的闭包也能通过“宽指针”安全实现,不再需要在栈或堆上生成动态代码。
🔑 核心要点
- 传统 GCC 嵌套函数在被取地址时会生成 trampoline,默认放在栈上,导致需要可执行栈,存在安全漏洞。
- GCC 16 保证不访问父函数局部变量的嵌套函数不生成 trampoline,并可安全返回;编译器还会对明显的捕获场景发出 警告。
- GCC 17 引入了 __builtin_call_code_address 和 __builtin_call_static_chain,配合 __builtin_call_with_static_chain 实现带捕获的闭包。
- 通过定义 wide pointer 类型并用宏封装内置函数,可以用接近原生嵌套函数的方式书写闭包,编译器仍能将其优化到单个汇编指令。
- 上下文指针通过 ABI 中已为静态链保留的特殊寄存器传递,彻底摆脱运行时生成和执行动态代码。
- 作者预告下一步将探讨如何让嵌套函数同时兼容 clang 与 GCC,并在旧版 GCC 中通过技巧避免 trampoline。
“In fact, with trampolines out of the picture, all that GCC does under the hood is to automatically transform this into the example above!”