0

今天查看Visual Studio 2008和2010的CRT库的源代码,发现mtdll.h文件有bug。问题出在宏 FLS_GETVALUE 上。在 x86 系统上,此宏直接调用 TlsGetValue,而不是调用分配给变量 gpFlsGetValue 的函数。

首先,这是一个问题,因为 FlsAlloc、FlsGetValue、FlsFree 和 FlsSetValue 并非在所有系统(Windows Vista+ 和 Windows Server 2003+)上都可用。这些函数的行为类似于 TlsAlloc、TlsGetValue、TlsFree 和 TlsSetValue,但支持 Fibers(一种用户线程)。因为我们应该更喜欢使用 Fls* 函数而不是 Tls 函数,所以 VS 的 C 运行时库会在加载进程或 dll 时检查 Fls 函数是否可用,并初始化 gpFls* 变量。如果 Fls* 不可用,CRT 将使用等效的 Tls* 函数初始化这些变量。

您不能在代码中直接使用宏 FLS_GETVALUE,因为它在运行时库内部使用。运行时使用此宏来初始化运行时库的每个线程数据。

我的问题是关于这个错误的影响。我知道 Fiber 并没有被广泛使用,但是如果您开发一个在使用 Fiber 的应用程序中使用的 DLL,会产生什么影响?这个错误是否会导致应用程序崩溃或只会产生错误的结果?这个问题是否会导致 SQL Server 等广泛使用的应用程序出现问题?你怎么看?这个错误会带来安全风险吗?IIS 或 ASP.Net 是否使用可能导致崩溃的光纤?

对于好奇的人,这里是 mtdll.h 中问题行的当前来源:

#define FLS_GETVALUE ((PFLS_GETVALUE_FUNCTION)TlsGetValue(__getvalueindex))

这里是宏 FLS_GETVALUE 的固定版本:

#define FLS_GETVALUE (((PFLS_GETVALUE_FUNCTION)DecodePointer(gpFlsGetValue))(__getvalueindex))

现在,我应该找到如何向 Microsoft 提交错误。

4

2 回答 2

0

对此我不确定。CRT 似乎处理 FlsGetValue 与其他 FLS 函数不同。看起来 CRT 正在 TLS 中存储指向 FlsGetValue 函数的指针(伪代码):

void init_fls()
{
    FLS_GET_VALUE_PROC proc = GetProcAddress(kernel32, "FlsGetValue");
    if(!proc)
    {
        // FlsGetValue not implemented on this platform
        // use alternative implementation provided by CRT
        proc = __crtFlsGetValue;
    }
    // store pointer to FlsGetValue proc in TLS
    TlsSetValue(fls_get_value_index, proc);
}

void* get_fls_value(int index)
{
    // retrieve pointer to FlsGetValue proc from TLS
    FLS_GET_VALUE_PROC proc = TlsGetValue(fls_get_value_index);
    return proc(index);
}
于 2011-04-19T14:41:36.253 回答
0

通过Microsoft Connect报告 Visual Studio 错误。

于 2011-04-19T03:55:24.607 回答