【Jenkins】cmd脚本运行正常,而jenkins卡住 报Process leaked file descriptors PostQuitMessage已经解决

使用PostQuitMessage(0);(会自动执行ExitInstance())替代exit(0); 有效。

cmd脚本运行正常,而jenkins卡住 报Process leaked file descriptors. config.ini路径不对,出现MessageBox导致的。有效。

windows jenkens延时ping -n 11 127.0.0.1 >nul
使用timeout /t 10 /nobreak 报错“错误: 不支持输入重新定向,立即退出此进程。”

我使用的是MFC写的程序,里面有可以从命令行运行,退出时我用了exit(0),我在jenkins里报“Process leaked file descriptors”,怎么分析是哪个文件句柄没关闭

在 Windows 上,Jenkins 报 “Process leaked file descriptors” 说明你的 MFC 程序可能有 未正确关闭的文件句柄。要找出具体 哪个文件句柄泄露了,可以使用以下方法分析:


方法 1:使用 handle.exe 检查进程文件句柄

Windows 没有 lsof,但可以用 Sysinternals Handle 工具检查哪些文件句柄未关闭。

1. 下载并安装 handle.exe

  • 官方下载地址
  • 解压 handle.exe,放到 C:\Windows\System32\(或者你的 PATH 路径)

2. 在 Jenkins 任务执行前后运行

先让 MFC 程序运行,在 Jenkins 执行 exit(0) 之前 运行:

handle.exe -p your_mfc_program.exe > before_exit.log

然后在 程序退出后 再执行:

handle.exe -p your_mfc_program.exe > after_exit.log

然后对比 before_exit.logafter_exit.log,找出哪些文件句柄 没有正确释放


方法 2:使用 Process Explorer 查看句柄

如果 handle.exe 输出太多,可以用 GUI 版的 Process Explorer

1. 下载 Process Explorer

  • 官方下载地址
  • 解压并运行 procexp.exe

2. 查找文件句柄

  1. 运行 procexp.exe
  2. Ctrl+F,输入你的 MFC 进程名
  3. 观察哪些 文件、套接字(socket)或注册表项 仍然处于打开状态

方法 3:使用 _CrtDumpMemoryLeaks() 检查 MFC 资源泄露

如果你的程序在 exit(0) 退出时仍然 持有 GDI 资源、文件句柄、内存分配,可以在 ExitInstance() 里添加:

#ifdef _DEBUG
    _CrtDumpMemoryLeaks();
#endif

然后在 Debug 控制台 查看输出,找出 未释放的对象


方法 4:在代码里手动打印所有打开的句柄

你可以使用 NtQuerySystemInformation()EnumProcessModules() 手动遍历当前进程的所有打开句柄:

#include 
#include 
#include 

void PrintOpenHandles()
{
    HANDLE hProcess = GetCurrentProcess();
    DWORD handleCount = 0;

    if (GetProcessHandleCount(hProcess, &handleCount))
    {
        printf("Process has %lu open handles\n", handleCount);
    }
}

在程序退出前调用:

PrintOpenHandles();
exit(0);

如果 handleCount 始终不为 0,说明有资源未释放。


方法 5:检查 MFC 代码中的资源泄露

1. 检查文件句柄

如果你的代码使用了 CreateFile()fopen(),确保调用了 CloseHandle()fclose()

HANDLE hFile = CreateFile(L"log.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
    // 正确释放文件句柄
    CloseHandle(hFile);
}

2. 检查网络套接字

如果你使用了 socket()WSAStartup(),确保在退出前 调用 closesocket()

closesocket(my_socket);
WSACleanup();

3. 检查 GDI 资源

如果你用 CreateDC()CreateFont(),确保调用:

DeleteDC(hDC);
DeleteObject(hFont);

方法 6:用 Resource Monitor 查看文件锁

Windows 自带 资源监视器(Resource Monitor),可以查找进程 锁住的文件

  1. Win + R,输入 resmon.exe 打开资源监视器
  2. 进入 “CPU” → “关联的句柄”
  3. 搜索你的 MFC 进程,查看未释放的文件句柄

总结

方法 作用
handle.exe -p 列出所有文件句柄,找到未关闭的文件
Process Explorer (procexp.exe) GUI 方式查看未释放的资源
_CrtDumpMemoryLeaks() 在 Debug 模式下检查 MFC 资源泄露
PrintOpenHandles() 手动打印程序的打开句柄数量
resmon.exe(资源监视器) 查找进程锁住的文件

最终解决步骤

  1. 运行 handle.exe -p your_mfc_program.exe > before_exit.log
  2. 运行程序并 exit(0)
  3. 运行 handle.exe -p your_mfc_program.exe > after_exit.log
  4. 对比 before_exit.logafter_exit.log,找到泄露的句柄
  5. 修改代码,在 ExitInstance() 释放所有资源
  6. 重新运行 Jenkins 任务,确保不再报 Process leaked file descriptors

这样,你就能精准找到 泄露的句柄 并修复它!

你可能感兴趣的:(jenkins,运维)