【问题标题】:Access Violation Calling into Dynamically Loaded DLL with C++使用 C++ 调用动态加载的 DLL 的访问冲突
【发布时间】:2011-07-27 11:53:42
【问题描述】:

我有一个使用 VS2010 构建并定义了一组函数的 dll(C 代码)。我还有一个 exe(C++ 代码),使用 VS2010 构建,可以动态加载 dll 并调用函数。前几个函数调用工作正常,然后大约 20% 的时间调用第三个函数会导致地址 0 的访问冲突。其他 80% 的通话时间都很好。导致问题的总是同一个函数调用。

typedef void (__cdecl *mtSim_ResetODScan)(void);
mtSim_ResetODScan mpSim_ResetODScan;

if ((mpSim_ResetODScan = (mtSim_ResetODScan)GetProcAddress(mhSimDLL,
    "_Sim_ResetODScan")) == NULL) return 0;

此时mpSim_ResetODScan = 0x5E9741D0。稍后调用该函数,当我调试可执行文件时,它会在函数调用处中断执行:

mpSim_ResetODScan();

尝试进入函数会重新生成访问冲突。 VS 调试器报告 mpSim_ResetODScan 的值仍然为 0x5E9741D0。

在 dll 中注释掉函数内的所有代码没有区别。

在 DLL 中:

extern "C" __declspec(dllexport) void __cdecl _Sim_ResetODScan(void);

Dependency Walker 显示 dll 和 exe 正在使用 MSVCR100.DLL 版本 10.0.30319.460。

关于如何进一步调试的任何建议或任何关于我可能错过的事情的提示?

【问题讨论】:

  • 这可能根本不需要对 dll 做任何事情:C dll 可能只是写入 OOB 内存左右。您是否在调试版本中运行了所有可能的运行时检查?
  • 我不能直接运行这个exe,因为它是由另一个exe启动的。崩溃发生在它启动后,所以我无法使用 VS 中的“附加到进程”功能。我能做的最好的就是在 JIT 调试器已经崩溃时使用它。我已打开所有调试功能。
  • 只需在 exe 的 main() 中插入一个 DebugBreak(),这样您就可以在崩溃发生之前附加调试器
  • 你的 DLL 被卸载了吗?尝试列出加载的模块,或者查看地址 0x5E9741D0 是否仍然有效(例如通过在数据窗口或程序集窗口中查看)

标签: c++ visual-studio-2010 dll linker


【解决方案1】:

尝试在调试器本身下正常运行程序,并在变量mpSim_ResetODScan 周围放置一个数据断点 - 看看它何时可能发生变化。似乎是缓冲区溢出的问题。

【讨论】:

  • 函数指针的地址在调用 GetProcAddress 和尝试执行之间没有改变。我用 VS 调试器验证了这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-19
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多