Discussion:
Heap32Next slow, and HeapWalk crashes
(too old to reply)
Kieron
2008-02-25 08:47:05 UTC
Permalink
Hi,

I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.

How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.

My code is:
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT


Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer

tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)

If blnUseHeapWalk Then

DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else

' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop


' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function


Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long

Dim lngRet As Long
Dim lngBytes As Long

tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)

' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then


blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet

If True Then

Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If

HeapUnlock lngHeapID
End If


End Sub
Ivan Brugiolo [MSFT]
2008-02-25 18:34:55 UTC
Permalink
Can you try to use the VerifierEnumerateResource(AvrfResourceHeapAllocation)
API
to solve the performance issues with Heap-Walk ?
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub
Kieron
2008-02-25 18:46:03 UTC
Permalink
I'm not having performance issues with Heap-Walk, but if this API will stop
the crashes I'll try it. (Unless you meant me to use this api instead of
heap32next)
--
Build it better, faster, quicker... Then fix it!
Post by Ivan Brugiolo [MSFT]
Can you try to use the VerifierEnumerateResource(AvrfResourceHeapAllocation)
API
to solve the performance issues with Heap-Walk ?
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub
Kieron
2008-02-26 06:59:01 UTC
Permalink
Hi,
I'm working on implementing this API in c# but the only example is some
pretty advanced c++. Can you give me any pointers(??) on implementation in c#?
Also, this appears to be limited to XP which I can do, but most of my
clients use 2000.
Thanks in advance
Post by Ivan Brugiolo [MSFT]
Can you try to use the VerifierEnumerateResource(AvrfResourceHeapAllocation)
API
to solve the performance issues with Heap-Walk ?
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub
Ivan Brugiolo [MSFT]
2008-02-26 08:28:28 UTC
Permalink
The VerifierEnumerateResource API should not
be any harder then EnumWindows to interop in c#
or any other managed language.
The API is available in WinXp and above, sorry.
HeapWalk id your best friend for other OS-es,
unless you want o use `!heap -p -all` and parse the text output
of that debugger extension in Win2000
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm working on implementing this API in c# but the only example is some
pretty advanced c++. Can you give me any pointers(??) on implementation in c#?
Also, this appears to be limited to XP which I can do, but most of my
clients use 2000.
Thanks in advance
Post by Ivan Brugiolo [MSFT]
Can you try to use the
VerifierEnumerateResource(AvrfResourceHeapAllocation)
API
to solve the performance issues with Heap-Walk ?
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub
Kieron
2008-02-26 09:09:00 UTC
Permalink
Ok I'll have another go at HeapWalk.
Heapwalk is whining about an unhandled exception in vb6.exe
Unhandled exception at 0x7c96012c in getvb6data.exe: 0xC0000005: Access
violation reading location 0x037c0013.

This was during the api call to heapwalk and not directly in my code. I'll
port the heapwalk stuff to c# and see if I get the same result, but do you
know why HeapLock and HEapValidate would return zero?
Post by Ivan Brugiolo [MSFT]
The VerifierEnumerateResource API should not
be any harder then EnumWindows to interop in c#
or any other managed language.
The API is available in WinXp and above, sorry.
HeapWalk id your best friend for other OS-es,
unless you want o use `!heap -p -all` and parse the text output
of that debugger extension in Win2000
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm working on implementing this API in c# but the only example is some
pretty advanced c++. Can you give me any pointers(??) on implementation in c#?
Also, this appears to be limited to XP which I can do, but most of my
clients use 2000.
Thanks in advance
Post by Ivan Brugiolo [MSFT]
Can you try to use the
VerifierEnumerateResource(AvrfResourceHeapAllocation)
API
to solve the performance issues with Heap-Walk ?
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub
Ivan Brugiolo [MSFT]
2008-02-26 11:13:15 UTC
Permalink
Post by Kieron
but do you
know why HeapLock and HEapValidate would return zero?
Without knowing the application whose heap is being walked,
the OS, and all other surrounding items, it's impossible to answer.

In general, I'd start with a known good heap-walk implementation,
such as the one implemented in the !ext.heap and !exts.heap debugger
extensions, and. take it from there.
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Ok I'll have another go at HeapWalk.
Heapwalk is whining about an unhandled exception in vb6.exe
Unhandled exception at 0x7c96012c in getvb6data.exe: 0xC0000005: Access
violation reading location 0x037c0013.
This was during the api call to heapwalk and not directly in my code. I'll
port the heapwalk stuff to c# and see if I get the same result, but do you
know why HeapLock and HEapValidate would return zero?
Post by Ivan Brugiolo [MSFT]
The VerifierEnumerateResource API should not
be any harder then EnumWindows to interop in c#
or any other managed language.
The API is available in WinXp and above, sorry.
HeapWalk id your best friend for other OS-es,
unless you want o use `!heap -p -all` and parse the text output
of that debugger extension in Win2000
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm working on implementing this API in c# but the only example is some
pretty advanced c++. Can you give me any pointers(??) on implementation
in
c#?
Also, this appears to be limited to XP which I can do, but most of my
clients use 2000.
Thanks in advance
Post by Ivan Brugiolo [MSFT]
Can you try to use the
VerifierEnumerateResource(AvrfResourceHeapAllocation)
API
to solve the performance issues with Heap-Walk ?
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub
Karthikeyan Mahadevan
2008-05-26 09:11:00 UTC
Permalink
Even I am getting a simillar issue. What I am trying to do is, I have process
A and Process B, both are unmanaged. Using Process A, I am creating some
heaps using HeapCreate and allocating some memory. In process B, I enumerate
all the Heaps held by process A and try to do a HeapWalk. Though HeapWalk is
successfull on some heaps, it crashes on other occasions, giving the same
access violation error.

I am using CreatToolhelp32SnapShot, Heap32ListFirst() API to enumerate all
the heaps.

Any Insight on this will be helpful.
Post by Ivan Brugiolo [MSFT]
Post by Kieron
but do you
know why HeapLock and HEapValidate would return zero?
Without knowing the application whose heap is being walked,
the OS, and all other surrounding items, it's impossible to answer.
In general, I'd start with a known good heap-walk implementation,
such as the one implemented in the !ext.heap and !exts.heap debugger
extensions, and. take it from there.
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Ok I'll have another go at HeapWalk.
Heapwalk is whining about an unhandled exception in vb6.exe
Unhandled exception at 0x7c96012c in getvb6data.exe: 0xC0000005: Access
violation reading location 0x037c0013.
This was during the api call to heapwalk and not directly in my code. I'll
port the heapwalk stuff to c# and see if I get the same result, but do you
know why HeapLock and HEapValidate would return zero?
Post by Ivan Brugiolo [MSFT]
The VerifierEnumerateResource API should not
be any harder then EnumWindows to interop in c#
or any other managed language.
The API is available in WinXp and above, sorry.
HeapWalk id your best friend for other OS-es,
unless you want o use `!heap -p -all` and parse the text output
of that debugger extension in Win2000
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm working on implementing this API in c# but the only example is some
pretty advanced c++. Can you give me any pointers(??) on implementation
in
c#?
Also, this appears to be limited to XP which I can do, but most of my
clients use 2000.
Thanks in advance
Post by Ivan Brugiolo [MSFT]
Can you try to use the
VerifierEnumerateResource(AvrfResourceHeapAllocation)
API
to solve the performance issues with Heap-Walk ?
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Kieron
Hi,
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub
Loading...