如何使用 ProcMon 检查 Win32 CreateProcess() 失败的原因。排除 GetLastError()
Posted
技术标签:
【中文标题】如何使用 ProcMon 检查 Win32 CreateProcess() 失败的原因。排除 GetLastError()【英文标题】:How to check Win32 CreateProcess() failed reason using ProcMon. exclude GetLastError() 【发布时间】:2020-03-17 10:36:35 【问题描述】:我在检查 CreateProcess() 失败原因时遇到问题,生产中的代码在 CreateProcess() 失败时不记录 GetLastError() 所以我正在运行 ProcMon 来检查原因但无法找到原因(procMon 是否会记录失败原因,例如“C:\dummy.exe 路径未找到或权限被拒绝”?)。
有没有办法(工具?)在不考虑 GetLastError() 的情况下检查 CreateProcess() 失败的原因?
我无法调试客户环境(无法访问我),但我可以更改代码并提供新版本,并且由于流程原因需要很长时间。我目前正在寻找可用的快速选项。以下是示例代码,不是确切的生产代码。
int main()
STARTUPINFO info = sizeof(info) ;
PROCESS_INFORMATION processInfo;
TCHAR dymmypath[_MAX_PATH] = _T("C:\\dummy.exe");
static TCHAR TempPathString[_MAX_PATH];
STARTUPINFO si = sizeof(si) ; //default set up
PROCESS_INFORMATION pi; //data structure for CreateProcess
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWMINIMIZED;
if (!CreateProcess(dymmypath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, TempPathString, &si, &pi))
printf("Failed");
else
printf("Success");
return 0;
【问题讨论】:
你不能只附加一个调试器吗? @tenfour 已在生产环境中发布版本。 发布版本仍然可以调试。在kernel32!CreateProcessW
上设置断点,跳出,查看错误码。
@RbMm ""
不是有效路径
@tenfour - 是的,无效。并且使用此代码调用必须总是 失败并出现文件名、目录名或卷标语法不正确。 错误。但我只说TempPathString
实际上是零初始化的。不是说这个正确
【参考方案1】:
我正在运行 ProcMon 来检查原因,但找不到原因(procMon 会记录失败原因,例如“C:\dummy.exe 路径未找到或权限被拒绝”吗?)。
仅当请求到达文件系统时,即查找 EXE 文件,在您的情况下,它听起来好像没有这样做,可能是因为 CreateProcess()
在到达文件系统之前无法验证您的输入参数.
有没有办法(工具?)在不考虑 GetLastError() 的情况下检查 CreateProcess() 失败的原因?
正如其他人所说,您可以尝试将调试器附加到正在运行的应用程序,并在 CreateProcess
函数本身中放置一个断点。
另一种选择是使用API Monitor 之类的工具,它会向您显示您的程序进行的实际 API 调用、它们的参数值是什么、报告的错误代码等。
我无法调试客户环境(无法访问我),但我可以更改代码并提供新版本
那是你应该做的。修复您的代码以正确记录错误代码,不要再忽略它们。
由于处理需要很长时间。
嗯,那是你自己的错,因为你没有更好地优化你的构建过程,或者把你的应用分解成更易于管理的部分,等等。
【讨论】:
【参考方案2】:乍一看,我看到TempPathString
被初始化为""
,这不是一个有效的路径。因此,当您解决该问题时,您就有机会添加适当的错误处理。
您正在寻找的工具是调试器。你应该附加你选择的调试器,在CreateProcess
的返回上设置一个断点,然后检查那里的错误。
除了调试和错误处理(记录等)之外,您还必须发挥创造力。例如,将工作环境与生产环境进行比较。
【讨论】:
调试器,是 WinDbg 还是 Visual Studio 调试器? @NDestiny 都可以。如果您想避免在生产系统上安装 Visual Studio,WinDbg 的重量会更轻。但听起来你有能力只更改代码,所以一个选项是构建足够的错误处理,如果这很麻烦,你不需要调试器。TempPathString
初始化为 0,因为它是静态的。当然,如果这段代码完全相关
如果您无法调试,也无法更改代码,那么您就是在问不可能。如果它在其他环境中工作,但至少你有一个做最后手段的起点:随机猜测和测试。接下来,您将告诉我们您无权访问 repro :D
“那你问的是不可能的事”——这就是说别无他法以上是关于如何使用 ProcMon 检查 Win32 CreateProcess() 失败的原因。排除 GetLastError()的主要内容,如果未能解决你的问题,请参考以下文章
在 win32 服务 (C++) 中生成 casablanca http_listener 的问题
如果某个任务正在任务管理器中运行,我如何在 python 中使用 pywin 或 win32com.client 检查?