You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1440 lines
38 KiB
1440 lines
38 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// SHOW_MEMDUMP.CPP |
|
// |
|
// Show Mem Dump Display. |
|
//=====================================================================================// |
|
#include "vxconsole.h" |
|
|
|
#define ID_SHOWMEMDUMP_LISTVIEW 100 |
|
|
|
// column id, pool mode |
|
#define ID_DUMPPOOL_POOL 0 |
|
#define ID_DUMPPOOL_SIZE 1 |
|
#define ID_DUMPPOOL_ALLOCATED 2 |
|
#define ID_DUMPPOOL_FREE 3 |
|
#define ID_DUMPPOOL_COMMITTED 4 |
|
#define ID_DUMPPOOL_COMMITTEDSIZE 5 |
|
|
|
// column id, detailed mode |
|
#define ID_DUMPDETAIL_ALLOCATION 0 |
|
#define ID_DUMPDETAIL_CURRENTSIZE 1 |
|
#define ID_DUMPDETAIL_PEAKSIZE 2 |
|
#define ID_DUMPDETAIL_TOTALSIZE 3 |
|
#define ID_DUMPDETAIL_OVERHEAD 4 |
|
#define ID_DUMPDETAIL_PEAKOVERHEAD 5 |
|
#define ID_DUMPDETAIL_TIME 6 |
|
#define ID_DUMPDETAIL_CURRENTCOUNT 7 |
|
#define ID_DUMPDETAIL_PEAKCOUNT 8 |
|
#define ID_DUMPDETAIL_TOTALCOUNT 9 |
|
#define ID_DUMPDETAIL_LTE16 10 |
|
#define ID_DUMPDETAIL_LTE32 11 |
|
#define ID_DUMPDETAIL_LTE128 12 |
|
#define ID_DUMPDETAIL_LTE1024 13 |
|
#define ID_DUMPDETAIL_GT1024 14 |
|
|
|
#define SHOW_BYTES 0 |
|
#define SHOW_KILOBYTES 1 |
|
#define SHOW_MEGABYTES 2 |
|
|
|
#define FORMAT_POOLS 0 |
|
#define FORMAT_DETAILS 1 |
|
|
|
struct MemoryPool_t |
|
{ |
|
int pool; |
|
char poolBuff[32]; |
|
int size; |
|
char sizeBuff[32]; |
|
int allocated; |
|
char allocatedBuff[32]; |
|
int free; |
|
char freeBuff[32]; |
|
int committed; |
|
char committedBuff[32]; |
|
int committedSize; |
|
char committedSizeBuff[32]; |
|
}; |
|
|
|
struct MemoryDetail_t |
|
{ |
|
char *pAllocationName; |
|
int currentSize; |
|
char currentSizeBuff[32]; |
|
int peakSize; |
|
char peakSizeBuff[32]; |
|
int totalSize; |
|
char totalSizeBuff[32]; |
|
int overheadSize; |
|
char overheadSizeBuff[32]; |
|
int peakOverheadSize; |
|
char peakOverheadSizeBuff[32]; |
|
int time; |
|
char timeBuff[32]; |
|
int currentCount; |
|
char currentCountBuff[32]; |
|
int peakCount; |
|
char peakCountBuff[32]; |
|
int totalCount; |
|
char totalCountBuff[32]; |
|
int lte16; |
|
char lte16Buff[32]; |
|
int lte32; |
|
char lte32Buff[32]; |
|
int lte128; |
|
char lte128Buff[32]; |
|
int lte1024; |
|
char lte1024Buff[32]; |
|
int gt1024; |
|
char gt1024Buff[32]; |
|
}; |
|
|
|
struct memory_t |
|
{ |
|
int listIndex; |
|
MemoryPool_t pool; |
|
MemoryDetail_t detail; |
|
}; |
|
|
|
struct label_t |
|
{ |
|
const CHAR* name; |
|
int width; |
|
int subItemIndex; |
|
CHAR nameBuff[64]; |
|
}; |
|
|
|
HWND g_showMemDump_hWnd; |
|
HWND g_showMemDump_hWndListView; |
|
RECT g_showMemDump_windowRect; |
|
int g_showMemDump_sortColumn; |
|
int g_showMemDump_sortDescending; |
|
memory_t *g_showMemDump_pMemory; |
|
int g_showMemDump_numMemory; |
|
int g_showMemDump_showBytes; |
|
bool g_showMemDump_bCollapseOutput; |
|
char g_showMemDump_currentFilename[MAX_PATH]; |
|
int g_showMemDump_format; |
|
|
|
void ShowMemDump_Parse( const char *pBuffer, int fileSize ); |
|
|
|
label_t g_showMemDump_PoolLabels[] = |
|
{ |
|
{"Pool", 120, ID_DUMPPOOL_POOL}, |
|
{"Size", 120, ID_DUMPPOOL_SIZE}, |
|
{"Allocated Count", 120, ID_DUMPPOOL_ALLOCATED}, |
|
{"Free Count", 120, ID_DUMPPOOL_FREE}, |
|
{"Committed Count", 120, ID_DUMPPOOL_COMMITTED}, |
|
{"Committed Size", 120, ID_DUMPPOOL_COMMITTEDSIZE}, |
|
}; |
|
|
|
label_t g_showMemDump_DetailLabels[] = |
|
{ |
|
{"Allocation", 200, ID_DUMPDETAIL_ALLOCATION}, |
|
{"Current Size", 120, ID_DUMPDETAIL_CURRENTSIZE}, |
|
{"Peak Size", 120, ID_DUMPDETAIL_PEAKSIZE}, |
|
{"Total Allocations", 120, ID_DUMPDETAIL_TOTALSIZE}, |
|
{"Overhead Size", 120, ID_DUMPDETAIL_OVERHEAD}, |
|
{"Peak Overhead Size", 120, ID_DUMPDETAIL_PEAKOVERHEAD}, |
|
{"Time (ms)", 120, ID_DUMPDETAIL_TIME}, |
|
{"Current Count", 120, ID_DUMPDETAIL_CURRENTCOUNT}, |
|
{"Peak Count", 120, ID_DUMPDETAIL_PEAKCOUNT}, |
|
{"Total Count", 120, ID_DUMPDETAIL_TOTALCOUNT}, |
|
{"<=16 bytes", 100, ID_DUMPDETAIL_LTE16}, |
|
{"17-32 bytes", 100, ID_DUMPDETAIL_LTE32}, |
|
{"33-128 bytes", 100, ID_DUMPDETAIL_LTE128}, |
|
{"129-1024 bytes", 100, ID_DUMPDETAIL_LTE1024}, |
|
{"> 1024 bytes", 100, ID_DUMPDETAIL_GT1024}, |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_FormatSize |
|
// |
|
//----------------------------------------------------------------------------- |
|
char *ShowMemDump_FormatSize( int size, char *pBuff, bool bUnits ) |
|
{ |
|
switch ( g_showMemDump_showBytes ) |
|
{ |
|
case SHOW_BYTES: |
|
sprintf( pBuff, "%d", size ); |
|
break; |
|
|
|
case SHOW_KILOBYTES: |
|
sprintf( pBuff, "%.2f", (float)size/1024.0f ); |
|
if ( bUnits ) |
|
strcat( pBuff, " K"); |
|
break; |
|
|
|
case SHOW_MEGABYTES: |
|
sprintf( pBuff, "%.2f", (float)size/(1024.0f*1024.0f) ); |
|
if ( bUnits ) |
|
strcat( pBuff, " MB"); |
|
break; |
|
} |
|
|
|
return pBuff; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_SaveConfig |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_SaveConfig() |
|
{ |
|
char buff[256]; |
|
|
|
Sys_SetRegistryInteger( "showMemDumpSortColumn", g_showMemDump_sortColumn ); |
|
Sys_SetRegistryInteger( "showMemDumpSortDescending", g_showMemDump_sortDescending ); |
|
Sys_SetRegistryInteger( "showMemDumpShowBytes", g_showMemDump_showBytes ); |
|
|
|
WINDOWPLACEMENT wp; |
|
memset( &wp, 0, sizeof( wp ) ); |
|
wp.length = sizeof( WINDOWPLACEMENT ); |
|
GetWindowPlacement( g_showMemDump_hWnd, &wp ); |
|
g_showMemDump_windowRect = wp.rcNormalPosition; |
|
|
|
sprintf( buff, "%d %d %d %d", g_showMemDump_windowRect.left, g_showMemDump_windowRect.top, g_showMemDump_windowRect.right, g_showMemDump_windowRect.bottom ); |
|
Sys_SetRegistryString( "showMemDumpWindowRect", buff ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_LoadConfig |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_LoadConfig() |
|
{ |
|
int numArgs; |
|
char buff[256]; |
|
|
|
Sys_GetRegistryInteger( "showMemDumpSortColumn", 0, g_showMemDump_sortColumn ); |
|
Sys_GetRegistryInteger( "showMemDumpSortDescending", false, g_showMemDump_sortDescending ); |
|
Sys_GetRegistryInteger( "showMemDumpShowBytes", SHOW_KILOBYTES, g_showMemDump_showBytes ); |
|
|
|
Sys_GetRegistryString( "showMemDumpWindowRect", buff, "", sizeof( buff ) ); |
|
numArgs = sscanf( buff, "%d %d %d %d", &g_showMemDump_windowRect.left, &g_showMemDump_windowRect.top, &g_showMemDump_windowRect.right, &g_showMemDump_windowRect.bottom ); |
|
if ( numArgs != 4 || g_showMemDump_windowRect.left < 0 || g_showMemDump_windowRect.top < 0 || g_showMemDump_windowRect.right < 0 || g_showMemDump_windowRect.bottom < 0 ) |
|
memset( &g_showMemDump_windowRect, 0, sizeof( g_showMemDump_windowRect ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_Clear |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_Clear() |
|
{ |
|
// delete all the list view entries |
|
if ( g_showMemDump_hWnd ) |
|
{ |
|
ListView_DeleteAllItems( g_showMemDump_hWndListView ); |
|
} |
|
|
|
if ( !g_showMemDump_pMemory ) |
|
return; |
|
|
|
for ( int i=0; i<g_showMemDump_numMemory; i++ ) |
|
{ |
|
delete [] g_showMemDump_pMemory[i].detail.pAllocationName; |
|
} |
|
|
|
Sys_Free( g_showMemDump_pMemory ); |
|
|
|
g_showMemDump_pMemory = NULL; |
|
g_showMemDump_numMemory = 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_Export |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_Export() |
|
{ |
|
OPENFILENAME ofn; |
|
char logFilename[MAX_PATH]; |
|
int retval; |
|
FILE* fp; |
|
int i; |
|
char buff[64]; |
|
|
|
if ( g_showMemDump_format != FORMAT_DETAILS ) |
|
{ |
|
return; |
|
} |
|
|
|
memset( &ofn, 0, sizeof( ofn ) ); |
|
ofn.lStructSize = sizeof( ofn ); |
|
ofn.hwndOwner = g_showMemDump_hWnd; |
|
ofn.lpstrFile = logFilename; |
|
ofn.lpstrFile[0] = '\0'; |
|
ofn.nMaxFile = sizeof( logFilename ); |
|
ofn.lpstrFilter = "Excel CSV\0*.CSV\0All Files\0*.*\0"; |
|
ofn.nFilterIndex = 1; |
|
ofn.lpstrFileTitle = NULL; |
|
ofn.nMaxFileTitle = 0; |
|
ofn.lpstrInitialDir = "c:\\"; |
|
ofn.Flags = OFN_PATHMUSTEXIST; |
|
|
|
// display the Open dialog box. |
|
retval = GetOpenFileName( &ofn ); |
|
if ( !retval ) |
|
return; |
|
|
|
Sys_AddExtension( ".csv", logFilename, sizeof( logFilename ) ); |
|
|
|
fp = fopen( logFilename, "wt+" ); |
|
if ( !fp ) |
|
return; |
|
|
|
// labels |
|
fprintf( fp, "Allocation Type" ); |
|
fprintf( fp, ",Current Size" ); |
|
fprintf( fp, ",Peak Size" ); |
|
fprintf( fp, ",Total Allocations" ); |
|
fprintf( fp, ",Overhead Size" ); |
|
fprintf( fp, ",Peak Overhead Size" ); |
|
fprintf( fp, ",Time(ms)" ); |
|
fprintf( fp, ",Current Count" ); |
|
fprintf( fp, ",Peak Count" ); |
|
fprintf( fp, ",Total Count" ); |
|
fprintf( fp, ",<=16 Byte Allocations" ); |
|
fprintf( fp, ",17-32 Byte Allocations" ); |
|
fprintf( fp, ",33-128 Byte Allocations" ); |
|
fprintf( fp, ",129-1024 Byte Allocations" ); |
|
fprintf( fp, ",>1024 Byte Allocations" ); |
|
fprintf( fp, "\n" ); |
|
|
|
// dump to the log |
|
for ( i=0; i<g_showMemDump_numMemory; i++ ) |
|
{ |
|
fprintf( fp, "\"%s\"", g_showMemDump_pMemory[i].detail.pAllocationName ); |
|
fprintf( fp, ",%s", ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.currentSize, buff, false ) ); |
|
fprintf( fp, ",%s", ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.peakSize, buff, false ) ); |
|
fprintf( fp, ",%s", ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.totalSize, buff, false ) ); |
|
fprintf( fp, ",%s", ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.overheadSize, buff, false ) ); |
|
fprintf( fp, ",%s", ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.peakOverheadSize, buff, false ) ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.time ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.currentCount ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.peakCount ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.totalCount ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.lte16 ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.lte32 ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.lte128 ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.lte1024 ); |
|
fprintf( fp, ",%d", g_showMemDump_pMemory[i].detail.gt1024 ); |
|
fprintf( fp, "\n" ); |
|
} |
|
|
|
fclose( fp ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_Summary |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_Summary() |
|
{ |
|
char buff[1024]; |
|
int i; |
|
|
|
if ( g_showMemDump_format != FORMAT_DETAILS ) |
|
{ |
|
return; |
|
} |
|
|
|
int currentSize = 0; |
|
int peakSize = 0; |
|
int totalSize = 0; |
|
int overheadSize = 0; |
|
int peakOverheadSize = 0; |
|
int time = 0; |
|
int currentCount = 0; |
|
int peakCount = 0; |
|
int totalCount = 0; |
|
int lte16 = 0; |
|
int lte32 = 0; |
|
int lte128 = 0; |
|
int lte1024 = 0; |
|
int gt1024 = 0; |
|
|
|
// tally the totals |
|
for (i=0; i<g_showMemDump_numMemory; i++) |
|
{ |
|
if ( !strnicmp( g_showMemDump_pMemory[i].detail.pAllocationName, "Totals,", 7 ) ) |
|
continue; |
|
|
|
currentSize += g_showMemDump_pMemory[i].detail.currentSize; |
|
peakSize += g_showMemDump_pMemory[i].detail.peakSize; |
|
totalSize += g_showMemDump_pMemory[i].detail.totalSize; |
|
overheadSize += g_showMemDump_pMemory[i].detail.overheadSize; |
|
peakOverheadSize += g_showMemDump_pMemory[i].detail.peakOverheadSize; |
|
time += g_showMemDump_pMemory[i].detail.time; |
|
currentCount += g_showMemDump_pMemory[i].detail.currentCount; |
|
peakCount += g_showMemDump_pMemory[i].detail.peakCount; |
|
totalCount += g_showMemDump_pMemory[i].detail.totalCount; |
|
lte16 += g_showMemDump_pMemory[i].detail.lte16; |
|
lte32 += g_showMemDump_pMemory[i].detail.lte32; |
|
lte128 += g_showMemDump_pMemory[i].detail.lte128; |
|
lte1024 += g_showMemDump_pMemory[i].detail.lte1024; |
|
gt1024 += g_showMemDump_pMemory[i].detail.gt1024; |
|
} |
|
|
|
sprintf( |
|
buff, |
|
"Entries:\t\t\t%d\n" |
|
"Current Size:\t\t%.2f MB\n" |
|
"Peak Size:\t\t%.2f MB\n" |
|
"Total Size:\t\t%.2f MB\n" |
|
"Overhead Size:\t\t%d\n" |
|
"Peak Overhead Size:\t%d\n" |
|
"Time:\t\t\t%d\n" |
|
"Current Count:\t\t%d\n" |
|
"Peak Count:\t\t%d\n" |
|
"Total Count:\t\t%d\n" |
|
"<= 16:\t\t\t%d\n" |
|
"17-32:\t\t\t%d\n" |
|
"33-128:\t\t\t%d\n" |
|
"129-1024:\t\t%d\n" |
|
"> 1024:\t\t\t%d\n", |
|
g_showMemDump_numMemory, |
|
(float)currentSize/( 1024.0F*1024.0F ), |
|
(float)peakSize/( 1024.0F*1024.0F ), |
|
(float)totalSize/( 1024.0F*1024.0F ), |
|
overheadSize, |
|
peakOverheadSize, |
|
time, |
|
currentCount, |
|
peakCount, |
|
totalCount, |
|
lte16, |
|
lte32, |
|
lte128, |
|
lte1024, |
|
gt1024 ); |
|
|
|
MessageBox( g_showMemDump_hWnd, buff, "Memory Dump Summary", MB_OK|MB_APPLMODAL ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_SetTitle |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_SetTitle() |
|
{ |
|
if ( g_showMemDump_hWnd ) |
|
{ |
|
SetWindowText( g_showMemDump_hWnd, "Memory Dump" ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_CompareFunc |
|
// |
|
//----------------------------------------------------------------------------- |
|
int CALLBACK ShowMemDump_CompareFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) |
|
{ |
|
memory_t* pMemoryA = (memory_t*)lParam1; |
|
memory_t* pMemoryB = (memory_t*)lParam2; |
|
|
|
int sort = 0; |
|
|
|
if ( g_showMemDump_format == FORMAT_POOLS ) |
|
{ |
|
switch ( g_showMemDump_sortColumn ) |
|
{ |
|
case ID_DUMPPOOL_POOL: |
|
sort = pMemoryA->pool.pool - pMemoryB->pool.pool; |
|
break; |
|
|
|
case ID_DUMPPOOL_SIZE: |
|
sort = pMemoryA->pool.size - pMemoryB->pool.size; |
|
break; |
|
|
|
case ID_DUMPPOOL_ALLOCATED: |
|
sort = pMemoryA->pool.allocated - pMemoryB->pool.allocated; |
|
break; |
|
|
|
case ID_DUMPPOOL_FREE: |
|
sort = pMemoryA->pool.free - pMemoryB->pool.free; |
|
break; |
|
|
|
case ID_DUMPPOOL_COMMITTED: |
|
sort = pMemoryA->pool.committed - pMemoryB->pool.committed; |
|
break; |
|
|
|
case ID_DUMPPOOL_COMMITTEDSIZE: |
|
sort = pMemoryA->pool.committedSize - pMemoryB->pool.committedSize; |
|
break; |
|
} |
|
} |
|
else |
|
{ |
|
switch ( g_showMemDump_sortColumn ) |
|
{ |
|
case ID_DUMPDETAIL_ALLOCATION: |
|
sort = stricmp( pMemoryA->detail.pAllocationName, pMemoryB->detail.pAllocationName ); |
|
break; |
|
|
|
case ID_DUMPDETAIL_CURRENTSIZE: |
|
sort = pMemoryA->detail.currentSize - pMemoryB->detail.currentSize; |
|
break; |
|
|
|
case ID_DUMPDETAIL_PEAKSIZE: |
|
sort = pMemoryA->detail.peakSize - pMemoryB->detail.peakSize; |
|
break; |
|
|
|
case ID_DUMPDETAIL_TOTALSIZE: |
|
sort = pMemoryA->detail.totalSize - pMemoryB->detail.totalSize; |
|
break; |
|
|
|
case ID_DUMPDETAIL_OVERHEAD: |
|
sort = pMemoryA->detail.overheadSize - pMemoryB->detail.overheadSize; |
|
break; |
|
|
|
case ID_DUMPDETAIL_PEAKOVERHEAD: |
|
sort = pMemoryA->detail.peakOverheadSize - pMemoryB->detail.peakOverheadSize; |
|
break; |
|
|
|
case ID_DUMPDETAIL_TIME: |
|
sort = pMemoryA->detail.time - pMemoryB->detail.time; |
|
break; |
|
|
|
case ID_DUMPDETAIL_CURRENTCOUNT: |
|
sort = pMemoryA->detail.currentCount - pMemoryB->detail.currentCount; |
|
break; |
|
|
|
case ID_DUMPDETAIL_PEAKCOUNT: |
|
sort = pMemoryA->detail.peakCount - pMemoryB->detail.peakCount; |
|
break; |
|
|
|
case ID_DUMPDETAIL_TOTALCOUNT: |
|
sort = pMemoryA->detail.totalCount - pMemoryB->detail.totalCount; |
|
break; |
|
|
|
case ID_DUMPDETAIL_LTE16: |
|
sort = pMemoryA->detail.lte16 - pMemoryB->detail.lte16; |
|
break; |
|
|
|
case ID_DUMPDETAIL_LTE32: |
|
sort = pMemoryA->detail.lte32 - pMemoryB->detail.lte32; |
|
break; |
|
|
|
case ID_DUMPDETAIL_LTE128: |
|
sort = pMemoryA->detail.lte128 - pMemoryB->detail.lte128; |
|
break; |
|
|
|
case ID_DUMPDETAIL_LTE1024: |
|
sort = pMemoryA->detail.lte1024 - pMemoryB->detail.lte1024; |
|
break; |
|
|
|
case ID_DUMPDETAIL_GT1024: |
|
sort = pMemoryA->detail.gt1024 - pMemoryB->detail.gt1024; |
|
break; |
|
} |
|
} |
|
|
|
// flip the sort order |
|
if ( g_showMemDump_sortDescending ) |
|
{ |
|
sort *= -1; |
|
} |
|
|
|
return ( sort ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_SortItems |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_SortItems() |
|
{ |
|
LVITEM lvitem; |
|
memory_t *pMemory; |
|
int i; |
|
|
|
if ( !g_showMemDump_hWnd ) |
|
{ |
|
// only sort if window is visible |
|
return; |
|
} |
|
|
|
ListView_SortItems( g_showMemDump_hWndListView, ShowMemDump_CompareFunc, 0 ); |
|
|
|
memset( &lvitem, 0, sizeof( lvitem ) ); |
|
lvitem.mask = LVIF_PARAM; |
|
|
|
// get each item and reset its list index |
|
int itemCount = ListView_GetItemCount( g_showMemDump_hWndListView ); |
|
for ( i=0; i<itemCount; i++ ) |
|
{ |
|
lvitem.iItem = i; |
|
ListView_GetItem( g_showMemDump_hWndListView, &lvitem ); |
|
|
|
pMemory = (memory_t*)lvitem.lParam; |
|
pMemory->listIndex = i; |
|
} |
|
|
|
int count; |
|
label_t* pLabels; |
|
if ( g_showMemDump_format == FORMAT_POOLS ) |
|
{ |
|
count = sizeof( g_showMemDump_PoolLabels )/sizeof( g_showMemDump_PoolLabels[0] ); |
|
pLabels = g_showMemDump_PoolLabels; |
|
} |
|
else |
|
{ |
|
count = sizeof( g_showMemDump_DetailLabels )/sizeof( g_showMemDump_DetailLabels[0] ); |
|
pLabels = g_showMemDump_DetailLabels; |
|
} |
|
|
|
// update list view columns with sort key |
|
for ( i = 0; i < count; i++ ) |
|
{ |
|
char symbol; |
|
LVCOLUMN lvc; |
|
|
|
if ( i == g_showMemDump_sortColumn ) |
|
symbol = g_showMemDump_sortDescending ? '<' : '>'; |
|
else |
|
symbol = ' '; |
|
sprintf( pLabels[i].nameBuff, "%s %c", pLabels[i].name, symbol ); |
|
|
|
memset( &lvc, 0, sizeof( lvc ) ); |
|
lvc.mask = LVCF_TEXT; |
|
lvc.pszText = (LPSTR)pLabels[i].nameBuff; |
|
|
|
ListView_SetColumn( g_showMemDump_hWndListView, i, &lvc ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_FormatItems |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_FormatItems() |
|
{ |
|
if ( g_showMemDump_format == FORMAT_POOLS ) |
|
{ |
|
for ( int i = 0; i < g_showMemDump_numMemory; i++ ) |
|
{ |
|
sprintf( g_showMemDump_pMemory[i].pool.sizeBuff, "%d", g_showMemDump_pMemory[i].pool.size ); |
|
ShowMemDump_FormatSize( g_showMemDump_pMemory[i].pool.committedSize, g_showMemDump_pMemory[i].pool.committedSizeBuff, true ); |
|
} |
|
} |
|
else |
|
{ |
|
for ( int i = 0; i < g_showMemDump_numMemory; i++ ) |
|
{ |
|
ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.currentSize, g_showMemDump_pMemory[i].detail.currentSizeBuff, true ); |
|
ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.peakSize, g_showMemDump_pMemory[i].detail.peakSizeBuff, true ); |
|
ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.totalSize, g_showMemDump_pMemory[i].detail.totalSizeBuff, true ); |
|
ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.overheadSize, g_showMemDump_pMemory[i].detail.overheadSizeBuff, true ); |
|
ShowMemDump_FormatSize( g_showMemDump_pMemory[i].detail.peakOverheadSize, g_showMemDump_pMemory[i].detail.peakOverheadSizeBuff, true ); |
|
} |
|
} |
|
|
|
ShowMemDump_SortItems(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_AddViewItem |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_AddViewItem( memory_t* pMemory ) |
|
{ |
|
LVITEM lvi; |
|
|
|
if ( !g_showMemDump_hWnd ) |
|
{ |
|
// only valid if log window is visible |
|
return; |
|
} |
|
|
|
// update the text callback buffers |
|
if ( g_showMemDump_format == FORMAT_POOLS ) |
|
{ |
|
sprintf( pMemory->pool.sizeBuff, "%d", pMemory->pool.size ); |
|
sprintf( pMemory->pool.poolBuff, "%d", pMemory->pool.pool ); |
|
sprintf( pMemory->pool.allocatedBuff, "%d", pMemory->pool.allocated ); |
|
sprintf( pMemory->pool.freeBuff, "%d", pMemory->pool.free ); |
|
sprintf( pMemory->pool.committedBuff, "%d", pMemory->pool.committed ); |
|
ShowMemDump_FormatSize( pMemory->pool.committedSize, pMemory->pool.committedSizeBuff, true ); |
|
} |
|
else |
|
{ |
|
ShowMemDump_FormatSize( pMemory->detail.currentSize, pMemory->detail.currentSizeBuff, true ); |
|
ShowMemDump_FormatSize( pMemory->detail.peakSize, pMemory->detail.peakSizeBuff, true ); |
|
ShowMemDump_FormatSize( pMemory->detail.totalSize, pMemory->detail.totalSizeBuff, true ); |
|
ShowMemDump_FormatSize( pMemory->detail.overheadSize, pMemory->detail.overheadSizeBuff, true ); |
|
ShowMemDump_FormatSize( pMemory->detail.peakOverheadSize, pMemory->detail.peakOverheadSizeBuff, true ); |
|
sprintf( pMemory->detail.timeBuff, "%d", pMemory->detail.time ); |
|
sprintf( pMemory->detail.currentCountBuff, "%d", pMemory->detail.currentCount ); |
|
sprintf( pMemory->detail.peakCountBuff, "%d", pMemory->detail.peakCount ); |
|
sprintf( pMemory->detail.totalCountBuff, "%d", pMemory->detail.totalCount ); |
|
sprintf( pMemory->detail.lte16Buff, "%d", pMemory->detail.lte16 ); |
|
sprintf( pMemory->detail.lte32Buff, "%d", pMemory->detail.lte32 ); |
|
sprintf( pMemory->detail.lte128Buff, "%d", pMemory->detail.lte128 ); |
|
sprintf( pMemory->detail.lte1024Buff, "%d", pMemory->detail.lte1024 ); |
|
sprintf( pMemory->detail.gt1024Buff, "%d", pMemory->detail.gt1024 ); |
|
} |
|
|
|
int itemCount = ListView_GetItemCount( g_showMemDump_hWndListView ); |
|
|
|
// setup and insert at end of list |
|
memset( &lvi, 0, sizeof( lvi ) ); |
|
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; |
|
lvi.iItem = itemCount; |
|
lvi.iSubItem = 0; |
|
lvi.state = 0; |
|
lvi.stateMask = 0; |
|
lvi.pszText = LPSTR_TEXTCALLBACK; |
|
lvi.lParam = (LPARAM)pMemory; |
|
|
|
// insert and set the real index |
|
pMemory->listIndex = ListView_InsertItem( g_showMemDump_hWndListView, &lvi ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_Refresh |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_Refresh() |
|
{ |
|
// send the command to application which replies with list data |
|
if ( g_connectedToApp ) |
|
{ |
|
ProcessCommand( "mem_dump" ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_RefreshView |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_RefreshView() |
|
{ |
|
if ( strlen( g_showMemDump_currentFilename ) == 0 ) |
|
{ |
|
// first time |
|
ShowMemDump_Refresh(); |
|
return; |
|
} |
|
|
|
// get current file |
|
int fileSize; |
|
char *pBuffer; |
|
bool bSuccess = LoadTargetFile( g_showMemDump_currentFilename, &fileSize, (void **)&pBuffer ); |
|
if ( !bSuccess ) |
|
{ |
|
// stale, try again |
|
ShowMemDump_Refresh(); |
|
return; |
|
} |
|
|
|
// parse and update view |
|
ShowMemDump_Parse( pBuffer, fileSize ); |
|
|
|
Sys_Free( pBuffer ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_PopulateList |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_PopulateList() |
|
{ |
|
// delete previous labels |
|
while ( 1 ) |
|
{ |
|
if ( !ListView_DeleteColumn( g_showMemDump_hWndListView, 0 ) ) |
|
{ |
|
break; |
|
} |
|
} |
|
|
|
int count; |
|
label_t* pLabels; |
|
if ( g_showMemDump_format == FORMAT_POOLS ) |
|
{ |
|
count = sizeof( g_showMemDump_PoolLabels )/sizeof( g_showMemDump_PoolLabels[0] ); |
|
pLabels = g_showMemDump_PoolLabels; |
|
} |
|
else |
|
{ |
|
count = sizeof( g_showMemDump_DetailLabels )/sizeof( g_showMemDump_DetailLabels[0] ); |
|
pLabels = g_showMemDump_DetailLabels; |
|
} |
|
|
|
// init list view columns |
|
for ( int i = 0; i < count; i++ ) |
|
{ |
|
LVCOLUMN lvc; |
|
memset( &lvc, 0, sizeof( lvc ) ); |
|
|
|
lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; |
|
lvc.iSubItem = 0; |
|
lvc.cx = pLabels[i].width; |
|
lvc.fmt = LVCFMT_LEFT; |
|
lvc.pszText = ( LPSTR )pLabels[i].name; |
|
|
|
ListView_InsertColumn( g_showMemDump_hWndListView, i, &lvc ); |
|
} |
|
|
|
// populate list view |
|
for ( int i = 0; i < g_showMemDump_numMemory; i++ ) |
|
{ |
|
ShowMemDump_AddViewItem( &g_showMemDump_pMemory[i] ); |
|
} |
|
|
|
ShowMemDump_SortItems(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_SizeWindow |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_SizeWindow( HWND hwnd, int cx, int cy ) |
|
{ |
|
if ( cx==0 || cy==0 ) |
|
{ |
|
RECT rcClient; |
|
GetClientRect( hwnd, &rcClient ); |
|
cx = rcClient.right; |
|
cy = rcClient.bottom; |
|
} |
|
|
|
// position the ListView |
|
SetWindowPos( g_showMemDump_hWndListView, NULL, 0, 0, cx, cy, SWP_NOZORDER ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_WndProc |
|
// |
|
//----------------------------------------------------------------------------- |
|
LRESULT CALLBACK ShowMemDump_WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) |
|
{ |
|
WORD wID = LOWORD( wParam ); |
|
memory_t* pMemory; |
|
|
|
switch ( message ) |
|
{ |
|
case WM_CREATE: |
|
return 0L; |
|
|
|
case WM_DESTROY: |
|
ShowMemDump_SaveConfig(); |
|
|
|
g_showMemDump_hWnd = NULL; |
|
return 0L; |
|
|
|
case WM_INITMENU: |
|
CheckMenuItem( (HMENU)wParam, IDM_OPTIONS_BYTES, MF_BYCOMMAND | ( g_showMemDump_showBytes == SHOW_BYTES ? MF_CHECKED : MF_UNCHECKED ) ); |
|
CheckMenuItem( (HMENU)wParam, IDM_OPTIONS_KILOBYTES, MF_BYCOMMAND | ( g_showMemDump_showBytes == SHOW_KILOBYTES ? MF_CHECKED : MF_UNCHECKED ) ); |
|
CheckMenuItem( (HMENU)wParam, IDM_OPTIONS_MEGABYTES, MF_BYCOMMAND | ( g_showMemDump_showBytes == SHOW_MEGABYTES ? MF_CHECKED : MF_UNCHECKED ) ); |
|
CheckMenuItem( (HMENU)wParam, IDM_OPTIONS_COLLAPSEOUTPUT, MF_BYCOMMAND | ( g_showMemDump_bCollapseOutput ? MF_CHECKED : MF_UNCHECKED ) ); |
|
return 0L; |
|
|
|
case WM_SIZE: |
|
ShowMemDump_SizeWindow( hwnd, LOWORD( lParam ), HIWORD( lParam ) ); |
|
return 0L; |
|
|
|
case WM_NOTIFY: |
|
switch ( ( ( LPNMHDR )lParam )->code ) |
|
{ |
|
case LVN_COLUMNCLICK: |
|
NMLISTVIEW* pnmlv; |
|
pnmlv = ( NMLISTVIEW* )lParam; |
|
if ( g_showMemDump_sortColumn == pnmlv->iSubItem ) |
|
{ |
|
// user has clicked on same column - flip the sort |
|
g_showMemDump_sortDescending ^= 1; |
|
} |
|
else |
|
{ |
|
// sort by new column |
|
g_showMemDump_sortColumn = pnmlv->iSubItem; |
|
} |
|
ShowMemDump_SortItems(); |
|
return 0L; |
|
|
|
case LVN_GETDISPINFO: |
|
NMLVDISPINFO* plvdi; |
|
plvdi = (NMLVDISPINFO*)lParam; |
|
pMemory = (memory_t*)plvdi->item.lParam; |
|
|
|
if ( g_showMemDump_format == FORMAT_POOLS ) |
|
{ |
|
switch ( plvdi->item.iSubItem ) |
|
{ |
|
case ID_DUMPPOOL_POOL: |
|
plvdi->item.pszText = pMemory->pool.poolBuff; |
|
return 0L; |
|
|
|
case ID_DUMPPOOL_SIZE: |
|
plvdi->item.pszText = pMemory->pool.sizeBuff; |
|
return 0L; |
|
|
|
case ID_DUMPPOOL_ALLOCATED: |
|
plvdi->item.pszText = pMemory->pool.allocatedBuff; |
|
return 0L; |
|
|
|
case ID_DUMPPOOL_FREE: |
|
plvdi->item.pszText = pMemory->pool.freeBuff; |
|
return 0L; |
|
|
|
case ID_DUMPPOOL_COMMITTED: |
|
plvdi->item.pszText = pMemory->pool.committedBuff; |
|
return 0L; |
|
|
|
case ID_DUMPPOOL_COMMITTEDSIZE: |
|
plvdi->item.pszText = pMemory->pool.committedSizeBuff; |
|
return 0L; |
|
} |
|
} |
|
else |
|
{ |
|
switch ( plvdi->item.iSubItem ) |
|
{ |
|
case ID_DUMPDETAIL_ALLOCATION: |
|
plvdi->item.pszText = pMemory->detail.pAllocationName; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_CURRENTSIZE: |
|
plvdi->item.pszText = pMemory->detail.currentSizeBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_PEAKSIZE: |
|
plvdi->item.pszText = pMemory->detail.peakSizeBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_TOTALSIZE: |
|
plvdi->item.pszText = pMemory->detail.totalSizeBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_OVERHEAD: |
|
plvdi->item.pszText = pMemory->detail.overheadSizeBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_PEAKOVERHEAD: |
|
plvdi->item.pszText = pMemory->detail.peakOverheadSizeBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_TIME: |
|
plvdi->item.pszText = pMemory->detail.timeBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_CURRENTCOUNT: |
|
plvdi->item.pszText = pMemory->detail.currentCountBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_PEAKCOUNT: |
|
plvdi->item.pszText = pMemory->detail.peakCountBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_TOTALCOUNT: |
|
plvdi->item.pszText = pMemory->detail.totalCountBuff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_LTE16: |
|
plvdi->item.pszText = pMemory->detail.lte16Buff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_LTE32: |
|
plvdi->item.pszText = pMemory->detail.lte32Buff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_LTE128: |
|
plvdi->item.pszText = pMemory->detail.lte128Buff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_LTE1024: |
|
plvdi->item.pszText = pMemory->detail.lte1024Buff; |
|
return 0L; |
|
|
|
case ID_DUMPDETAIL_GT1024: |
|
plvdi->item.pszText = pMemory->detail.gt1024Buff; |
|
return 0L; |
|
|
|
default: |
|
break; |
|
} |
|
} |
|
break; |
|
} |
|
break; |
|
|
|
case WM_COMMAND: |
|
switch ( wID ) |
|
{ |
|
case IDM_OPTIONS_REFRESH: |
|
ShowMemDump_Refresh(); |
|
return 0L; |
|
|
|
case IDM_OPTIONS_EXPORT: |
|
ShowMemDump_Export(); |
|
return 0L; |
|
|
|
case IDM_OPTIONS_SUMMARY: |
|
ShowMemDump_Summary(); |
|
return 0L; |
|
|
|
case IDM_OPTIONS_BYTES: |
|
g_showMemDump_showBytes = SHOW_BYTES; |
|
ShowMemDump_FormatItems(); |
|
return 0L; |
|
|
|
case IDM_OPTIONS_KILOBYTES: |
|
g_showMemDump_showBytes = SHOW_KILOBYTES; |
|
ShowMemDump_FormatItems(); |
|
return 0L; |
|
|
|
case IDM_OPTIONS_MEGABYTES: |
|
g_showMemDump_showBytes = SHOW_MEGABYTES; |
|
ShowMemDump_FormatItems(); |
|
return 0L; |
|
|
|
case IDM_OPTIONS_COLLAPSEOUTPUT: |
|
g_showMemDump_bCollapseOutput = !g_showMemDump_bCollapseOutput; |
|
ShowMemDump_RefreshView(); |
|
return 0L; |
|
} |
|
break; |
|
} |
|
|
|
return ( DefWindowProc( hwnd, message, wParam, lParam ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_Init |
|
// |
|
//----------------------------------------------------------------------------- |
|
bool ShowMemDump_Init() |
|
{ |
|
// set up our window class |
|
WNDCLASS wndclass; |
|
|
|
memset( &wndclass, 0, sizeof( wndclass ) ); |
|
wndclass.style = 0; |
|
wndclass.lpfnWndProc = ShowMemDump_WndProc; |
|
wndclass.cbClsExtra = 0; |
|
wndclass.cbWndExtra = 0; |
|
wndclass.hInstance = g_hInstance; |
|
wndclass.hIcon = g_hIcons[ICON_APPLICATION]; |
|
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); |
|
wndclass.hbrBackground = g_hBackgroundBrush; |
|
wndclass.lpszMenuName = MAKEINTRESOURCE( MENU_SHOWMEMORYDUMP ); |
|
wndclass.lpszClassName = "SHOWMEMDUMPCLASS"; |
|
if ( !RegisterClass( &wndclass ) ) |
|
return false; |
|
|
|
ShowMemDump_LoadConfig(); |
|
|
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_Open |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_Open() |
|
{ |
|
RECT clientRect; |
|
HWND hWnd; |
|
|
|
if ( g_showMemDump_hWnd ) |
|
{ |
|
// only one instance |
|
if ( IsIconic( g_showMemDump_hWnd ) ) |
|
ShowWindow( g_showMemDump_hWnd, SW_RESTORE ); |
|
SetForegroundWindow( g_showMemDump_hWnd ); |
|
return; |
|
} |
|
|
|
hWnd = CreateWindowEx( |
|
WS_EX_CLIENTEDGE, |
|
"SHOWMEMDUMPCLASS", |
|
"", |
|
WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX, |
|
0, |
|
0, |
|
700, |
|
400, |
|
g_hDlgMain, |
|
NULL, |
|
g_hInstance, |
|
NULL ); |
|
g_showMemDump_hWnd = hWnd; |
|
|
|
GetClientRect( g_showMemDump_hWnd, &clientRect ); |
|
hWnd = CreateWindow( |
|
WC_LISTVIEW, |
|
"", |
|
WS_VISIBLE|WS_CHILD|LVS_REPORT, |
|
0, |
|
0, |
|
clientRect.right-clientRect.left, |
|
clientRect.bottom-clientRect.top, |
|
g_showMemDump_hWnd, |
|
( HMENU )ID_SHOWMEMDUMP_LISTVIEW, |
|
g_hInstance, |
|
NULL ); |
|
g_showMemDump_hWndListView = hWnd; |
|
|
|
ListView_SetBkColor( g_showMemDump_hWndListView, g_backgroundColor ); |
|
ListView_SetTextBkColor( g_showMemDump_hWndListView, g_backgroundColor ); |
|
|
|
DWORD style = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP; |
|
ListView_SetExtendedListViewStyleEx( g_showMemDump_hWndListView, style, style ); |
|
|
|
ShowMemDump_PopulateList(); |
|
|
|
ShowMemDump_SetTitle(); |
|
|
|
if ( g_showMemDump_windowRect.right && g_showMemDump_windowRect.bottom ) |
|
MoveWindow( g_showMemDump_hWnd, g_showMemDump_windowRect.left, g_showMemDump_windowRect.top, g_showMemDump_windowRect.right-g_showMemDump_windowRect.left, g_showMemDump_windowRect.bottom-g_showMemDump_windowRect.top, FALSE ); |
|
ShowWindow( g_showMemDump_hWnd, SHOW_OPENWINDOW ); |
|
|
|
// get data from application |
|
ShowMemDump_Refresh(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// MatchAllocationName |
|
// |
|
//----------------------------------------------------------------------------- |
|
void MatchAllocationName( memory_t *&pMemory ) |
|
{ |
|
memory_t *curEntry = g_showMemDump_pMemory; |
|
for ( int i=0; i<g_showMemDump_numMemory; ++i ) |
|
{ |
|
if ( !strcmp( curEntry->detail.pAllocationName, pMemory->detail.pAllocationName ) ) |
|
{ |
|
pMemory = curEntry; |
|
return; |
|
} |
|
++curEntry; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// ShowMemDump_Parse |
|
// |
|
//----------------------------------------------------------------------------- |
|
void ShowMemDump_Parse( const char *pBuffer, int fileSize ) |
|
{ |
|
char *ptr; |
|
char *pToken; |
|
char *pLineStart; |
|
int numLines; |
|
int size; |
|
memory_t *pMemory; |
|
|
|
// remove old entries |
|
ShowMemDump_Clear(); |
|
|
|
if ( !pBuffer || !fileSize ) |
|
{ |
|
// no valid data |
|
return; |
|
} |
|
|
|
Sys_SetScriptData( pBuffer, fileSize ); |
|
|
|
// skip first line, column headers |
|
Sys_SkipRestOfLine(); |
|
|
|
Sys_SaveParser(); |
|
|
|
// count lines |
|
numLines = 0; |
|
while ( 1 ) |
|
{ |
|
pToken = Sys_GetToken( true ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
numLines++; |
|
Sys_SkipRestOfLine(); |
|
} |
|
|
|
// each line represents one complete entry |
|
g_showMemDump_pMemory = (memory_t *)Sys_Alloc( numLines * sizeof( memory_t ) ); |
|
|
|
Sys_RestoreParser(); |
|
|
|
pMemory = g_showMemDump_pMemory; |
|
|
|
int format = 0; |
|
if ( !V_strnicmp( g_sys_scriptptr, "pool ", 5 ) ) |
|
{ |
|
// parse as pool stats |
|
format = FORMAT_POOLS; |
|
|
|
while ( 1 ) |
|
{ |
|
// find start of relevant data |
|
bool bFound = false; |
|
while ( 1 ) |
|
{ |
|
pToken = Sys_GetToken( true ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
if ( !V_stricmp( pToken, "size:" ) ) |
|
{ |
|
bFound = true; |
|
break; |
|
} |
|
} |
|
if ( !bFound ) |
|
{ |
|
break; |
|
} |
|
|
|
memset( pMemory, 0, sizeof( memory_t ) ); |
|
|
|
pMemory->pool.pool = g_showMemDump_numMemory; |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->pool.size = atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
if ( !V_stricmp( pToken, "allocated:" ) ) |
|
{ |
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->pool.allocated = atoi( pToken ); |
|
} |
|
else |
|
{ |
|
break; |
|
} |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
if ( !V_stricmp( pToken, "free:" ) ) |
|
{ |
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->pool.free = atoi( pToken ); |
|
} |
|
else |
|
{ |
|
break; |
|
} |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
if ( !V_stricmp( pToken, "committed:" ) ) |
|
{ |
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->pool.committed = atoi( pToken ); |
|
} |
|
else |
|
{ |
|
break; |
|
} |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
if ( !V_stricmp( pToken, "committedsize:" ) ) |
|
{ |
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->pool.committedSize = atoi( pToken ); |
|
} |
|
else |
|
{ |
|
break; |
|
} |
|
|
|
pMemory++; |
|
g_showMemDump_numMemory++; |
|
if ( g_showMemDump_numMemory >= numLines ) |
|
break; |
|
} |
|
} |
|
else |
|
{ |
|
// parse as detail stats |
|
format = FORMAT_DETAILS; |
|
|
|
while ( 1 ) |
|
{ |
|
pLineStart = g_sys_scriptptr; |
|
|
|
// can't tokenize, find start of parsable data |
|
ptr = V_stristr( g_sys_scriptptr, ", line " ); |
|
if ( !ptr ) |
|
break; |
|
g_sys_scriptptr = ptr + strlen( ", line " ); |
|
|
|
// advance past the expected line number |
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
|
|
if ( !g_showMemDump_bCollapseOutput ) |
|
{ |
|
size = g_sys_scriptptr-pLineStart; |
|
} |
|
else |
|
{ |
|
size = ptr-pLineStart; |
|
} |
|
|
|
memset( pMemory, 0, sizeof(memory_t) ); |
|
memory_t *pCurRecordStart = pMemory; |
|
|
|
pMemory->detail.pAllocationName = new char[size+1]; |
|
memcpy( pMemory->detail.pAllocationName, pLineStart, size ); |
|
pMemory->detail.pAllocationName[size] = '\0'; |
|
Sys_NormalizePath( pMemory->detail.pAllocationName, false ); |
|
|
|
if ( g_showMemDump_bCollapseOutput ) |
|
{ |
|
MatchAllocationName( pMemory ); |
|
} |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.currentSize += (int)(1024.0f*atof( pToken )); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.peakSize += (int)(1024.0f*atof( pToken )); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.totalSize += (int)(1024.0f*atof( pToken )); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.overheadSize += (int)(1024.0f*atof( pToken )); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.peakOverheadSize += (int)(1024.0f*atof( pToken )); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.time += atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.currentCount += atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.peakCount += atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.totalCount += atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.lte16 += atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.lte32 += atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.lte128 += atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.lte1024 += atoi( pToken ); |
|
|
|
pToken = Sys_GetToken( false ); |
|
if ( !pToken || !pToken[0] ) |
|
break; |
|
pMemory->detail.gt1024 += atoi( pToken ); |
|
|
|
Sys_SkipRestOfLine(); |
|
|
|
if( pMemory == pCurRecordStart ) |
|
{ |
|
pMemory++; |
|
g_showMemDump_numMemory++; |
|
} |
|
else |
|
{ |
|
pMemory = pCurRecordStart; |
|
} |
|
|
|
if ( g_showMemDump_numMemory >= numLines ) |
|
break; |
|
} |
|
} |
|
|
|
if ( g_showMemDump_format != format ) |
|
{ |
|
// format change will cause list view change |
|
g_showMemDump_format = format; |
|
g_showMemDump_sortColumn = 0; |
|
g_showMemDump_sortDescending = 0; |
|
} |
|
|
|
ShowMemDump_PopulateList(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// rc_MemDump |
|
// |
|
// Sent from application with memory dump file |
|
//----------------------------------------------------------------------------- |
|
int rc_MemDump( char *pCommand ) |
|
{ |
|
char* pToken; |
|
int retVal; |
|
int errCode = -1; |
|
int fileSize; |
|
char *pBuffer; |
|
|
|
// get name of file |
|
pToken = GetToken( &pCommand ); |
|
if ( !pToken[0] ) |
|
goto cleanUp; |
|
|
|
// get file |
|
strcpy( g_showMemDump_currentFilename, pToken ); |
|
retVal = LoadTargetFile( g_showMemDump_currentFilename, &fileSize, (void **)&pBuffer ); |
|
|
|
DebugCommand( "0x%8.8x = MemDump( %s )\n", retVal, g_showMemDump_currentFilename ); |
|
|
|
// parse and update view |
|
ShowMemDump_Parse( pBuffer, fileSize ); |
|
|
|
Sys_Free( pBuffer ); |
|
|
|
// success |
|
errCode = 0; |
|
|
|
cleanUp: |
|
return ( errCode ); |
|
}
|
|
|