今天,我正在检查Visual Studio 2008和2010的CRT库的源代码,我在文件mtdll.h中发现了一个错误。问题在于宏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直接用于代码,因为它在运行时库内部使用。运行时使用此宏来初始化运行时库的每个线程数据。
我的问题是关于这个bug的影响。我知道光纤没有被广泛使用,但是如果你开发了一个在使用光纤的应用程序中使用的DLL,那会有什么影响呢?此错误是否会导致应用程序崩溃或仅产生错误结果?此问题是否会导致SQL Server等广泛使用的应用程序出现问题?你怎么看?这个bug是否存在安全风险? 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提交错误。
答案 0 :(得分:0)
通过Microsoft Connect报告Visual Studio错误。
答案 1 :(得分:0)
我不确定。 CRT似乎与其他FLS函数不同地处理FlsGetValue。看起来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);
}