【发布时间】:2021-09-24 02:53:51
【问题描述】:
我正在尝试在 CI 机器上调试 Unreal 中的 DLL 的一些非常不透明的问题(有关更多信息,请参阅 Unreal: Diagnosing why Windows cannot load a DLL)。 glu32.dll 似乎是 Unreal 进程崩溃的 DLL,并且由于 Windows Server 不包含普通 Windows 10 所包含的所有与图形相关的 DLL,因此建议我从我的机器/Microsoft 可再发行组件中上传某些 DLL以确保 Unreal 构建过程可以运行。
出于理智的目的,我编写了一个小实用程序来测试我机器上的glu32.dll 是否可以动态加载并可以正确调用其函数。我打算很快在麻烦的 CI 机器上运行这个可执行文件,看看会发生什么。
程序代码如下:
#include <windows.h>
#include <iostream>
#include <GL/gl.h>
extern "C"
{
typedef const GLubyte* (__stdcall *ErrorStringFunc)(GLenum error);
}
int main(int argc, char** argv)
{
if (argc < 2)
{
std::cerr << "Usage: GLU32Loader.exe <path to glu32.dll>" << std::endl;
return 1;
}
const char* path = argv[1];
std::cout << "Attempting to load: " << path << std::endl;
HMODULE dllHandle = LoadLibraryA(path);
if (!dllHandle)
{
std::cerr << "Could not load " << path << std::endl;
return 1;
}
std::cout << "Successfully loaded DLL: 0x" << dllHandle << std::endl;
const char* funcName = "gluErrorString";
std::cout << "Looking up function: " << funcName << std::endl;
ErrorStringFunc func = reinterpret_cast<ErrorStringFunc>(GetProcAddress(dllHandle, funcName));
if (func)
{
std::cout << "Successfully loaded function: 0x" << func << std::endl;
const GLubyte* str = (*func)(100902);
std::cout << "Error string for value 100902: \"" << str << "\" (0x" << static_cast<const void*>(str) << ")" << std::endl;
}
else
{
std::cerr << "Failed to load function " << funcName << std::endl;
}
FreeLibrary(dllHandle);
return 0;
}
当我运行可执行文件并将其指向System32 文件夹中的glu32.dll 时,我得到了预期的输出:
> GLU32Loader.exe "C:\Windows\System32\glu32.dll"
Attempting to load: C:\Windows\System32\glu32.dll
Successfully loaded DLL: 0x00007FFC7A350000
Looking up function: gluErrorString
Successfully loaded function: 0x00007FFC7A35C650
Error string for value 100902: "out of memory" (0x000001E5757F51D0)
但是,如果我将 DLL 复制到我的桌面并再次运行程序,虽然 DLL 和函数似乎已加载,但函数返回的字符串为空:
> GLU32Loader.exe "C:\Users\Jonathan\Desktop\glu32.dll"
Attempting to load: C:\Users\Jonathan\Desktop\glu32.dll
Successfully loaded DLL: 0x00007FFC8DDB0000
Looking up function: gluErrorString
Successfully loaded function: 0x00007FFC8DDBC650
Error string for value 100902: "" (0x0000025C5236E520)
为什么会这样?它是完全相同的 DLL,只是在不同的文件夹中,我认为它引用的任何其他依赖 DLL 应该仍然可用,因为它们都在 System32 中。是否有一些我不熟悉的 Windows DLL 的神秘属性可能导致这种情况发生?
【问题讨论】:
-
这是一个奇怪的具体问题,在这两种情况下我都会使用调试器进入 gluErrorString 看看发生了什么有什么不同
-
调试器实际上并没有让我看到 gluErrorString 的内容。我不知道这是因为它的 PDB 在我的机器上不可用,还是因为我完全动态链接到它。
-
您也可以使用进程监视器查看运行时访问的文件是否有任何差异。
-
调试器:如果你在你的代码中设置了一个断点,然后“进入”它应该工作的函数调用,你应该得到 glu32 的反汇编代码并能够单步执行它 -当然不是来源,而是汇编
-
Visual Studio 似乎甚至不允许我进入程序集...