Skip to content

Commit e350faa

Browse files
Copilotxusheng6
andcommitted
Complete TTD Heap implementation with documentation and examples
Co-authored-by: xusheng6 <94503187+xusheng6@users.noreply.github.com>
1 parent 74e26b6 commit e350faa

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

docs/ttd-python-api.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,36 @@ class TTDExceptionType:
188188
Hardware = 1 # Hardware exceptions
189189
```
190190

191+
### TTDHeapEvent
192+
193+
Represents a heap operation event in a TTD trace.
194+
195+
```python
196+
class TTDHeapEvent:
197+
"""
198+
TTDHeapEvent represents a heap operation event in a TTD trace.
199+
200+
Attributes:
201+
event_type (str): Type of the event (always "Heap" for TTD.Heap objects)
202+
action (str): Heap action that occurred (Alloc, ReAlloc, Free, Create, Protect, Lock, Unlock, Destroy)
203+
thread_id (int): OS thread ID that performed the heap operation
204+
unique_thread_id (int): Unique thread ID across the trace
205+
heap (int): Handle for the Win32 heap
206+
address (int): Address of the allocated object (if applicable)
207+
previous_address (int): Address before reallocation (for ReAlloc operations)
208+
size (int): Size of allocated object (if applicable)
209+
base_address (int): Base address of allocated object (if applicable)
210+
flags (int): Heap API flags (meaning depends on the specific API)
211+
result (int): Result of heap API call (non-zero means success)
212+
reserve_size (int): Amount of memory to reserve (for Create operations)
213+
commit_size (int): Initial committed size (for Create operations)
214+
make_read_only (int): Non-zero indicates request to make heap read-only
215+
parameters (List[str]): List of raw parameters from the heap call
216+
time_start (TTDPosition): TTD position when heap operation started
217+
time_end (TTDPosition): TTD position when heap operation ended
218+
"""
219+
```
220+
191221
## Constants and Access Types
192222

193223
### DebuggerTTDMemoryAccessType Enum
@@ -311,6 +341,22 @@ def get_ttd_events(self, event_type: int) -> List[TTDEvent]:
311341
"""
312342
```
313343

344+
### get_ttd_heap_objects()
345+
346+
```python
347+
def get_ttd_heap_objects(self) -> List[TTDHeapEvent]:
348+
"""
349+
Get TTD heap operation events.
350+
351+
This method queries all heap operations that occurred during the TTD trace.
352+
It provides information about heap allocations, deallocations, reallocations,
353+
and other heap management operations.
354+
355+
Returns:
356+
List of TTDHeapEvent objects representing heap operations
357+
"""
358+
```
359+
314360
### get_current_ttd_position()
315361

316362
```python
@@ -387,6 +433,58 @@ for call in call_events:
387433
print(f" Return value: {call.return_value:#x}")
388434
```
389435

436+
### Heap Analysis
437+
438+
```python
439+
# Analyze heap operations during the trace
440+
heap_events = dbg.get_ttd_heap_objects()
441+
442+
print(f"Found {len(heap_events)} heap operations")
443+
444+
# Group by action type
445+
actions = {}
446+
for event in heap_events:
447+
if event.action not in actions:
448+
actions[event.action] = []
449+
actions[event.action].append(event)
450+
451+
# Display summary
452+
for action, events in actions.items():
453+
print(f"{action}: {len(events)} operations")
454+
455+
# Find large allocations
456+
large_allocs = [e for e in heap_events
457+
if e.action == "Alloc" and e.size > 1024*1024] # > 1MB
458+
459+
print(f"Found {len(large_allocs)} large allocations (>1MB)")
460+
for alloc in large_allocs:
461+
print(f" {alloc.size} bytes at {alloc.address:#x} (heap {alloc.heap:#x})")
462+
print(f" Time: {alloc.time_start}")
463+
464+
# Analyze heap usage patterns
465+
heap_stats = {}
466+
for event in heap_events:
467+
heap_handle = event.heap
468+
if heap_handle not in heap_stats:
469+
heap_stats[heap_handle] = {'allocs': 0, 'frees': 0, 'total_allocated': 0}
470+
471+
if event.action == "Alloc":
472+
heap_stats[heap_handle]['allocs'] += 1
473+
heap_stats[heap_handle]['total_allocated'] += event.size
474+
elif event.action == "Free":
475+
heap_stats[heap_handle]['frees'] += 1
476+
477+
print("\nHeap usage statistics:")
478+
for heap_handle, stats in heap_stats.items():
479+
print(f"Heap {heap_handle:#x}:")
480+
print(f" Allocations: {stats['allocs']}")
481+
print(f" Frees: {stats['frees']}")
482+
print(f" Total allocated: {stats['total_allocated']} bytes")
483+
leaked = stats['allocs'] - stats['frees']
484+
if leaked > 0:
485+
print(f" Potential leaks: {leaked} allocations")
486+
```
487+
390488
### TTD Navigation
391489

392490
```python

0 commit comments

Comments
 (0)