我的应用程序(基本应用程序是MFC与C++/CLI互操作,但它也包含很多C#,Windows窗体,WPF)有一个句柄泄漏.在应用程序启动后不久,我可以看到任务管理器中的句柄计数不断增长(以每秒10个新句柄的速率).所以我使用handles.exe来查看它们是什么类型的句柄.我发现泄漏的手柄是工艺手柄.它们是我的应用程序流程的流程句柄.
所以我想知道什么操作通常会创建它运行的进程的句柄.任何想法?你见过这样的东西吗?考虑到我不能使用调试DLL并且我只能使用可以部署xcopy的工具,我还能做些什么来追踪泄漏.
更新:
我能够向它发出windbg和!handle,!htrace,并发现进程句柄都是使用以下堆栈跟踪创建的(按频率排序):
0x79f7570b: mscorwks!CorExitProcess+0x00022055
0x79f03edd: mscorwks!GetPrivateContextsPerfCounters+0x0000b6fe
0x79f04b87: mscorwks!GetPrivateContextsPerfCounters+0x0000c3a8
0x79f04b03: mscorwks!GetPrivateContextsPerfCounters+0x0000c324
0x79f919bf: mscorwks!CorExitProcess+0x0003e309
0x79f91b28: mscorwks!CorExitProcess+0x0003e472
0x792d6b4c: mscorlib_ni+0x00216b4c
0x1391a663: +0x1391a663
0x1391a0b1: +0x1391a0b1
0x7a9ea544: System_ni+0x005aa544
0x792a842f: mscorlib_ni+0x001e842f
Run Code Online (Sandbox Code Playgroud)
要么
0x7c8106f5: kernel32!CreateThread+0x0000001e
0x79f04bb2: mscorwks!GetPrivateContextsPerfCounters+0x0000c3d3
0x79f04b03: mscorwks!GetPrivateContextsPerfCounters+0x0000c324
0x79f919bf: mscorwks!CorExitProcess+0x0003e309
0x79f91b28: mscorwks!CorExitProcess+0x0003e472
0x792d6b4c: mscorlib_ni+0x00216b4c
0x1391a663: +0x1391a663
0x1391a0b1: +0x1391a0b1
0x7a9ea544: System_ni+0x005aa544
0x792a842f: mscorlib_ni+0x001e842f
Run Code Online (Sandbox Code Playgroud)
要么
0x08ec2eba: +0x08ec2eba
0x792b8277: mscorlib_ni+0x001f8277
0x792b8190: mscorlib_ni+0x001f8190
0x792b8040: mscorlib_ni+0x001f8040
0x792b7ff2: mscorlib_ni+0x001f7ff2
0x677e48f3: System_Runtime_Remoting_ni+0x000748f3
0x677e44be: System_Runtime_Remoting_ni+0x000744be
0x677e46ec: System_Runtime_Remoting_ni+0x000746ec
0x677e8408: System_Runtime_Remoting_ni+0x00078408
0x7926eb8d: mscorlib_ni+0x001aeb8d
Run Code Online (Sandbox Code Playgroud)
那告诉我什么?
似乎在System.Threading.Timer回调函数的回调中调用Winforms控件上的Invoke泄漏句柄,直到计时器被释放.有没有人知道如何解决这个问题?我需要每秒轮询一次值并相应地更新UI.
我在一个测试项目中尝试过,以确保这确实是泄漏的原因,这只是以下几点:
System.Threading.Timer timer;
public Form1()
{
InitializeComponent();
timer = new System.Threading.Timer(new System.Threading.TimerCallback(DoStuff), null, 0, 500);
}
void DoStuff(object o)
{
this.Invoke(new Action(() => this.Text = "hello world"));
}
Run Code Online (Sandbox Code Playgroud)
如果您在Windows任务管理器中观看,这将泄漏2个句柄/秒.
嗨好StackOverflow的人.
我正在使用pyzmq并且我有一些长时间运行的进程,这导致发现套接字句柄处于打开状态.我已将违规代码缩小到以下内容:
import zmq
uri = 'tcp://127.0.0.1'
sock_type = zmq.REQ
linger = 250
# Observe output of lsof -p <pid> here and see no socket handles
ctx = zmq.Context.instance()
sock = ctx.socket(sock_type)
sock.setsockopt(zmq.LINGER, linger)
port = sock.bind_to_random_port(uri)
# Observe output of lsof -p <pid> here and see many socket handles
sock.close() # lsof -p <pid> still showing many socket handles
ctx.destroy() # Makes no difference
Run Code Online (Sandbox Code Playgroud)
pyzmq版本是pyzmq-13.1.0
pyzmq中有一个错误,或者我做错了什么.我希望你能帮帮我!!
谢谢!
我在C#程序中有一个句柄泄漏.我正在尝试使用WinDbg使用!htrace进行诊断,大致如此答案中所示,但是当我运行!在WinDbg中运行htrace -diff时,我看到的堆栈跟踪没有显示我的C#函数的名称(或者甚至我的.net组装).
我创建了一个小测试程序来说明我的难度.除"泄漏"手柄外,该程序不执行任何操作.
class Program
{
static List<Semaphore> handles = new List<Semaphore>();
static void Main(string[] args)
{
while (true)
{
Fun1();
Thread.Sleep(100);
}
}
static void Fun1()
{
handles.Add(new Semaphore(0, 10));
}
}
Run Code Online (Sandbox Code Playgroud)
我编译了程序集,然后在WinDbg中我去"File" - >"Open Executable"并选择我的程序(D:\ Projects\Sandpit\bin\Debug\Sandpit.exe).我继续执行程序,打破它,然后运行"!htrace -enable",然后再继续一段时间,然后打破并运行"!htrace -diff".这就是我得到的:
0:004> !htrace -enable
Handle tracing enabled.
Handle tracing information snapshot successfully taken.
0:004> g
(1bd4.1c80): Break instruction exception - code 80000003 (first chance)
eax=7ffda000 ebx=00000000 ecx=00000000 edx=77b2f17d esi=00000000 edi=00000000
eip=77ac410c esp=0403fc20 ebp=0403fc4c iopl=0 nv up ei pl zr …
Run Code Online (Sandbox Code Playgroud) 我们为Windows窗体UI渲染引擎开发了一个小型测试套件,可以在自动运行测试用例的同时测量性能并检测内存泄漏.现在我们也想检查手柄泄漏.在桌面平台上,我们可以使用以下代码:
[DllImport("User32")]
private extern static int GetGuiResources(IntPtr hProcess, int uiFlags);
using (var process = Process.GetCurrentProcess())
{
var gdiHandles = GetGuiResources(process.Handle, 0);
var userHandles = GetGuiResources(process.Handle, 1);
}
Run Code Online (Sandbox Code Playgroud)
此方法似乎在Windows Mobile中不可用.是否有另一种方法可以在Windows Mobile/CE上以编程方式确定这些值?
背景:我正在尝试创建一个可由多个进程访问的内存映射文件。在下面的代码中,我只输入了与我目前必须使事情更简单的问题有关的代码。根据msdn,我应该能够创建一个文件映射,映射文件的视图并关闭我从 CreateFileMapping 接收到的句柄,而 MapViewOfFile 将使我的 FileMap 保持活动状态。FileMap 应该仍然可以访问,直到我 UnmapViewOfFile。
MSDN: CreateFileMapping 函数
文件映射对象的映射视图维护对对象的内部引用,并且文件映射对象在对它的所有引用都被释放之前不会关闭。因此,要完全关闭文件映射对象,应用程序必须通过调用 UnmapViewOfFile 取消映射文件映射对象的所有映射视图,并通过调用 CloseHandle 关闭文件映射对象句柄。这些函数可以按任何顺序调用。
问题:成功映射文件视图并关闭 CreateFileMapping 接收到的句柄后,FileMap 不再存在(它应该仍然存在)并且我的 MemMapFileReader 能够创建一个错误为 0 的新映射。(当它应该接收错误 183 '已经存在')
错误的解决方案:不关闭句柄允许它被 MemMapFileReader 程序访问,但会导致 MemMapFileCreator 中的句柄泄漏,因为在进程关闭之前句柄永远不会关闭。
问题:我错过了什么或做错了什么?
内存映射文件创建器
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#define BUF_SIZE 256
TCHAR szName[] = TEXT("MyFileMappingObject");
TCHAR szMsg[] = TEXT("Message from first process.");
int _tmain()
{
HANDLE hMapFile;
LPCTSTR pBuf;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, …
Run Code Online (Sandbox Code Playgroud) handle-leak ×6
c# ×4
.net ×2
c++ ×1
file-mapping ×1
gdi ×1
interop ×1
mfc ×1
multiprocess ×1
python ×1
pyzmq ×1
stack-trace ×1
timer ×1
winapi ×1
windbg ×1
winforms ×1
zeromq ×1