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

Windows 10下TLS回调实现异常:仅单个回调执行问题咨询

TLS回调函数未全部执行的问题分析与解决

修正后的代码

#include <Windows.h>
#include <cstdio>
__declspec(thread) int a;
__declspec(thread) int b;
void NTAPI on_tls_callback(void* dll, DWORD reason, void* reserved)
{
    a = 543; // 0x21F
    //MessageBox(nullptr, L"In TLS", L"In TLS", MB_OK);
    printf("a in on_tls_callback function: %d\n", a);
}
void NTAPI on_tls_callback_test(void* dll, DWORD reason, void* reserved)
{
    b = 10; // 0xA
    //MessageBox(nullptr, L"Another In TLS", L"Another In TLS", MB_OK);
    printf("b in on_tls_callback_test function: %d\n", b);
}

#pragma comment (linker, "/INCLUDE:__tls_used")

// 修正回调段的链接器指令
#pragma data_seg(".CRT$XLA")
#pragma comment (linker, "/INCLUDE:_xl_a") // 修正符号名:去掉多余的下划线
EXTERN_C __declspec(allocate(".CRT$XLA"))
PIMAGE_TLS_CALLBACK _xl_a = (PIMAGE_TLS_CALLBACK)on_tls_callback_test;
#pragma data_seg()

#pragma data_seg(".CRT$XLX")
#pragma comment (linker, "/INCLUDE:_xl_x") // 同步修正此处符号名
EXTERN_C __declspec(allocate(".CRT$XLX"))
PIMAGE_TLS_CALLBACK _xl_x = (PIMAGE_TLS_CALLBACK)on_tls_callback;
#pragma data_seg()

__declspec(thread) int c = 9;

int main()
{
    printf("a in main: %d\n", a);
    printf("b in main: %d\n", b);
    c = 15;
    printf("c in main: %d\n", c);
    //MessageBox(nullptr, L"In Main", L"In Main", MB_OK);
    printf("end main !!!\n");
    getchar();
    return 0;
}

问题原因

你的代码核心错误是链接器包含的符号名与实际变量名不匹配:

  • 你定义的回调变量是_xl_a(单下划线前缀),但链接器指令写的是/INCLUDE:__xl_a(双下划线前缀),导致链接器无法识别该符号,最终.CRT$XLA段中的on_tls_callback_test回调没有被加入到系统的TLS回调数组中,程序启动时不会执行这个回调。
  • Windows TLS回调的机制是:链接器会自动合并所有位于.CRT$XL*(后缀为A-Z字母)段中的PIMAGE_TLS_CALLBACK变量为一个数组,程序加载时系统会遍历该数组依次执行回调。如果变量因符号未被引用且未强制包含被链接器丢弃,对应的回调就不会触发。

变量b值为0的原因

由于on_tls_callback_test从未执行,b = 10;的赋值操作没有运行。而__declspec(thread)修饰的全局变量,若未显式初始化,会被默认初始化为0,因此main函数中读取到的b值为0。

修正后预期输出

b in on_tls_callback_test function: 10
a in on_tls_callback function: 543
a in main: 543
b in main: 10
c in main: 15
end main !!!

注:TLS回调的执行顺序由段名后缀字母决定,.CRT$XLA的后缀A在.CRT$XLX的X之前,因此on_tls_callback_test会先执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:22:17