亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? memsnapshot.cpp

?? 一個內存調試工具,給需要的coder 喜歡就下
?? CPP
字號:
/*********************************************************************************** * filename	: MemSnapShot.cpp * author	: mjguan * date		: 2003/04/22 * description	: receive message( data ) from the message queue, and analysis it. *  * 1. 使用curses庫寫屏幕后,應該調用refresh()來刷新。 ***********************************************************************************/#include <curses.h>#include <unistd.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <sys/types.h>#include <sys/msg.h>#include <pwd.h>#include <assert.h>#include <map>#include <list>using namespace std;#define SINGLE_NEW		0x00		// indicate alloc memory with new type#define ARRAY_NEW		0x01		// indicate alloc memory with new[] type#define SINGLE_DELETE		0x02		// indicate free memory with delete type#define ARRAY_DELETE		0x03		// indicate free memory with delete[] type#define FILENAME_LENGTH		32		// the filename length#define MEMORY_INFO		0X12345678	// indicate the message type on the message queuetypedef struct{	char		Filename[ FILENAME_LENGTH ];	// new所在的源程序文件名	unsigned long	LineNum;	// new在源文件中的行號	size_t 		AllocSize;	// 分配的內存大小	int		OperationType;	void *		pBuffer;	// 分配后得到的內存指針	short		errCode;	// 0 - 沒有釋放, 1 - delete了new[]分配的內存}MemOperation;typedef struct {	int	Type;			// message type, in this module must be MEMORY_INFO	MemOperation Data;		// content of memory operation} MsgBuffer;typedef struct{	char Filename[ FILENAME_LENGTH ];	unsigned long LineNum;	void *MemoryPtr;	int OperationType;	unsigned long TotalSize;} StatResult;int nMsgQueue;	// message queue idint interval = 1;pid_t pid = 0;map<void*, StatResult> mapMemory;list<StatResult> listMemory;pthread_mutex_t mutexMap;extern int errno;pthread_t tid1, tid2, tid3;unsigned long int totalLeak = 0;WINDOW *win;	void *AnalyseMessage( void * );void *DisplayStatResult( void * );void *MonitorKeyboard( void * );void initial();void popWin( char *str );void DecodeErr( int ErrNum );intmain( int argc, char *argv[] ){	key_t key;	int flags, counter = 0, ch;	char msgpath[ 64 ], str[ 16 ], *p;	struct passwd *pwd;	bool bCorrect = false;	struct msqid_ds	msgInfo;	MsgBuffer ReceiveMsg;		while( 1 )	{			if ( -1 == (ch = getopt( argc, argv, "pt" ) ) )			break;			switch( ch )		{		case 'p':			p = argv[ optind ];			// 判斷輸入的PID的長度的合法性			if ( strlen( p  ) > 11 )			{				printf( "你輸入的PID數值太大了, 請檢查后再試\n" );				exit( 1 );			} 			while ( *p )			{				if ( *p < '0' || *p > '9' )				{					printf( "你輸入的PID含有非法字符, 請檢查后再試\n" );					exit( 1 );				}				p++;			}			pid = atol( argv[ optind ] );			bCorrect = true;			break;		case 't':			p = argv[ optind ];			// 判斷輸入的PID的長度的合法性			if ( strlen( p  ) > 3 )			{				printf( "你輸入的時間間隔數值太大了, 請檢查后再試\n" );				exit( 1 );			} 			while ( *p )			{				if ( *p < '0' || *p > '9' )				{					printf( "你輸入的時間間隔含有非法字符, 請檢查后再試\n" );					exit( 1 );				}				p++;			}			interval = atol( argv[ optind ] );			if ( interval < 1 )				interval = 1;			if ( interval > 30 )				interval = 30;			break;		default:			break;		}		}	if ( false == bCorrect )		printf( "usage: MemSnapShot -p pid [ -t interval ]\n" ), exit( 1 );			pwd = getpwuid( getuid() );	sprintf( msgpath, "%s/.MemMsgQueue%d", pwd->pw_dir, pid );	// 確保m_szMsgPath表示的文件存在, 否則計算創建消息隊列成功	// 其key值也將是0XFFFFFFFF(-1)。	// 如果文件不存在則創建, 創建不成功則嘗試10次	do	{		// Open for reading and appending (writing at end  of  file). The		// file  is created if it does not exist		FILE *fp = fopen( msgpath, "r" );		if ( fp )			break;	} while( counter++ < 10 );	if ( counter == 10 )		exit( 0 );	key  =  ftok( msgpath, 'a' );			nMsgQueue  =  msgget( key, 0 );	if( nMsgQueue == -1 ) // the message queue exist then delete it	{		switch( errno )		{		case EIDRM:			printf( "消息隊列已經被刪除\n" );			break;		case EACCES:			printf( "消息隊列存在, 但是你沒有訪問權限\n" );			break;		default:			printf( "錯誤, 可能的原因:\n"				"1. 輸入的進程(ID:%d)不存在\n"				"2. 輸入的進程(ID:%d)中沒有含有消息隊列\n"				"3. 你與運行進程(ID:%d)的用戶不是同一個人\n",				pid, pid, pid );			break;		}		exit( 1 );	}		initial();		// 清空當前消息隊列中	if ( 0 != msgctl( nMsgQueue, IPC_STAT, &msgInfo ) )	{		printf( "不能讀取消息隊列的屬性" );		exit( 1 );	}	for ( counter = 0; counter < msgInfo.msg_qnum; counter++ )		msgrcv( nMsgQueue, &ReceiveMsg, sizeof( ReceiveMsg.Data ), MEMORY_INFO, IPC_NOWAIT );				// 啟動兩個線程來監控內存的變化	pthread_mutex_init( &mutexMap, NULL );		// 從消息隊列中讀取消息并進行分析	pthread_create( &tid1, NULL, AnalyseMessage, NULL );	// 顯示分析的結果	pthread_create( &tid2, NULL, DisplayStatResult, NULL );	// 監控鍵盤輸入	pthread_create( &tid3, NULL, MonitorKeyboard, NULL );		pthread_join( tid1, NULL );	pthread_join( tid2, NULL );	pthread_join( tid3, NULL );		endwin();}void*AnalyseMessage( void *arg ){	MsgBuffer ReceiveMsg;		while( 1 )	{		// get the message from the message queue		int reval = msgrcv( nMsgQueue, &ReceiveMsg, sizeof( ReceiveMsg.Data ), MEMORY_INFO, 0 );		if ( reval != -1 )		{			map<void *, StatResult>::iterator record;			record = mapMemory.find( ReceiveMsg.Data.pBuffer );			if ( record != mapMemory.end() ) // find it in the map			{				pthread_mutex_lock( &mutexMap );				if ( ARRAY_NEW == ReceiveMsg.Data.OperationType ||					SINGLE_NEW == ReceiveMsg.Data.OperationType )				{					// 這個情況相當于使用new/new[]后, 沒有刪除					// 又分配了一塊內存.					// 新分配的內存的指針應該與以前的指針不相同的					// 如果相同則表示有一個delete消息被丟失了或傳送的					// 消息有誤					totalLeak += ReceiveMsg.Data.AllocSize;										record->second.TotalSize += 						ReceiveMsg.Data.AllocSize;					record->second.OperationType = 						ReceiveMsg.Data.OperationType;					// 這個應該是不會出現的,如果出現了應該仔細地分析原因					// 這個情況在被測進程使用了fork創建子進程時會出現的					char prompt[ 128 ];					sprintf( prompt, "致命錯誤(%s:%d), 請仔細檢查你的代碼", __FILE__, __LINE__ );										pthread_cancel( tid2 );					pthread_cancel( tid3 );					popWin( prompt );					endwin();					exit( 1 );				}				else if ( SINGLE_DELETE == ReceiveMsg.Data.OperationType ||					ARRAY_DELETE == ReceiveMsg.Data.OperationType )				{					/**************仔細檢查以下這段代碼**************/					// alloc with new[] but free with delete, but not delete[]					if ( SINGLE_DELETE == ReceiveMsg.Data.OperationType &&						ARRAY_NEW == record->second.OperationType )					{						list<StatResult>::iterator ite;												for ( ite = listMemory.begin(); ite != listMemory.end(); ++ite )						{							if ( 0 == strcasecmp( ite->Filename, record->second.Filename )								&& ite->LineNum == record->second.LineNum )							{								ite->TotalSize += record->second.TotalSize;								break;							}						}						if ( ite == listMemory.end() )							listMemory.push_back( record->second );											}					else						totalLeak -= record->second.TotalSize;										mapMemory.erase( record );					/**************仔細檢查以上這段代碼**************/				}				else // unknown memory operation, ignore now.				{					char prompt[ 128 ];										sprintf( prompt, "致命錯誤(%s:%d), 請仔細檢查你的代碼", __FILE__, __LINE__ );					pthread_cancel( tid2 );					pthread_cancel( tid3 );					popWin( prompt );					endwin();					exit( 1 );				}				pthread_mutex_unlock( &mutexMap );			}			else			{				if ( SINGLE_NEW == ReceiveMsg.Data.OperationType || 					ARRAY_NEW == ReceiveMsg.Data.OperationType )				{					StatResult result;										totalLeak += ReceiveMsg.Data.AllocSize;										strncpy( result.Filename, ReceiveMsg.Data.Filename, FILENAME_LENGTH - 1 );					result.Filename[ FILENAME_LENGTH - 1 ]= '\0';					result.LineNum = ReceiveMsg.Data.LineNum;					result.MemoryPtr = ReceiveMsg.Data.pBuffer;					result.OperationType = ReceiveMsg.Data.OperationType;					result.TotalSize = ReceiveMsg.Data.AllocSize;					pair<void *, StatResult> value( ReceiveMsg.Data.pBuffer, result );					mapMemory.insert( value );				}				else				{									}			}		}		else		{			if (( EIDRM == errno )||(EINVAL == errno)) // the message queue has removed, exit the thread			{				char *prompt = "消息隊列已經被刪除, 退出內存快照.";				pthread_cancel( tid2 );				pthread_cancel( tid3 );								popWin( prompt );				endwin();				break;			}			}	}	return NULL;}void DecodeErr( int ErrNum ){	switch( ErrNum )	{	case EAGAIN:		printf( "---EAGAIN---\n" );		break;	case EACCES:		printf( "---EACCES---\n" );		break;	case EFAULT:		printf( "---EFAULT---\n" );		break;	case EIDRM:		printf( "---EIDRM---\n" );		break;	case EINTR:		printf( "---EINTR---\n" );		break;	case EINVAL:		printf( "---EINVAL---\n" );		break;	case ENOMEM:		printf( "---ENOMEM---\n" );		break;	default:		printf( "---Undefined---\n" );		break;		}}/* ############################################################################ 顯示內存泄漏的結果, 目前是一秒鐘顯示一次. 目前的DEBUG: . 屏幕刷新不對 ############################################################################*/void *DisplayStatResult(  void *arg ){	char content[128];	int line  = 0;	unsigned long total;	list<StatResult> temp;	static bool firstFlag = true;		temp.clear();		while( true )	{		pthread_mutex_lock( &mutexMap );		map<void*, StatResult>::iterator record1;		list<StatResult>::iterator record2;						// 統計mapMemory中的泄漏記錄		// 注意這里是++record1而不是record1++		for ( record1 = mapMemory.begin(); record1 != mapMemory.end(); ++record1 )		{			list<StatResult>::iterator ite;									for ( ite = temp.begin(); ite != temp.end(); ++ite )			{				if ( 0 == strcasecmp( ite->Filename, record1->second.Filename )					&& ite->LineNum == record1->second.LineNum )				{					ite->TotalSize += record1->second.TotalSize;					break;				}			}			if ( ite == temp.end() )			{				StatResult tmpRecord;				memcpy( &tmpRecord, &(record1->second), sizeof( tmpRecord ) );				// 不能寫成push_back( record1->second )				temp.push_back( tmpRecord );			}		}		// 統計listMemory中的泄漏記錄		// 注意這里是++record2而不是record2++		for ( record2 = listMemory.begin(); record2 != listMemory.end(); ++record2 )		{			list<StatResult>::iterator ite;			// 同樣這里是++ite而不是ite++			for ( ite = temp.begin(); ite != temp.end(); ++ite )			{				if ( 0 == strcasecmp( ite->Filename, record2->Filename )					&& ite->LineNum == record2->LineNum )				{					ite->TotalSize += record2->TotalSize;					break;				}			}			if ( ite == temp.end() )			{				// 注意這里不能直接寫成temp.push_back( *record2 );				StatResult tmpRecord;				memcpy( &tmpRecord, &(*record2), sizeof( tmpRecord ) );				temp.push_back( tmpRecord );			}		}							if ( 0 != totalLeak )		{			erase(); // clear the screen						mvprintw( line++, 0, "被檢測的進程是 ID = %d, 目前 %d 秒進行一次統計", pid, interval );			mvprintw( line++, 0, "" );					mvprintw( line++, 0, "" );						attrset( A_REVERSE );			mvprintw( line++, 0, "%-24s%-12s%-22s%-8s\n",				"所在文件", "行號", "分配內存數量(字節)", "所占比例" );			attrset( A_NORMAL );			refresh();						// 注意這里也不要寫成record2++			for ( record2 = temp.begin(); record2 != temp.end(); ++record2 )			{				mvprintw( line++, 0, "%-24s%-12d%-22d%2.2f%%",					record2->Filename, record2->LineNum,					record2->TotalSize,					( double ) record2->TotalSize * 100 / totalLeak );			}			mvprintw( line++, 0, "");			mvprintw( line++, 0, "內存分配統計, 共 %d 字節(%0.1fKB = %0.1fMB)",				totalLeak, ( double )totalLeak / 1024, ( double ) totalLeak / 1024 / 1024 );			refresh(); // output to screen			line = 0;		}		else		{					}		temp.clear();		pthread_mutex_unlock( &mutexMap );		sleep( interval );	}	return NULL;}void *MonitorKeyboard(  void *arg ){	int ch;		for(;;)	{		ch = getch();		switch( ch )		{		case 'q':		case 'Q':			endwin();			exit( 0 );		case 'i':		case 'I':			if ( interval >= 30 )				interval = 30;			else				interval++;			break;		case 'd':		case 'D':			if ( interval <= 1 )				interval = 1;			else				interval--;			break;		default:			break;			}	}}voidinitial(){	initscr();	cbreak();	noecho();	nonl();			mvprintw( 0, 0, "被檢測的進程是 ID = %d, 目前 %d 秒進行一次統計", pid, interval );	attrset( A_REVERSE );		mvprintw( 3, 0, "%-24s%-12s%-22s%-8s\n",		"所在文件", "行號", "分配內存數量(字節)", "所占比例" );	attrset( A_NORMAL );	refresh();}voidpopWin( char *str ){	char *prompt = "按任何鍵退出";	WINDOW *popWin = newwin( 4, 70, LINES/2 - 3, COLS / 2 - 35 ); 		box( popWin, '#' , '#' ); 	if ( str )		mvwaddstr( popWin, 1, ( 70 - strlen( str ) ) / 2,  str );	mvwaddstr( popWin, 2, ( 70 - strlen( prompt ) ) / 2,  prompt );	touchwin( popWin );	wrefresh( popWin );	getch();	touchwin( stdscr );	refresh();}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美一级免费大片| 精品污污网站免费看| 91免费视频网| 欧美成人精品福利| 一片黄亚洲嫩模| 国产一区二区福利视频| 欧美日韩国产成人在线91| 国产精品三级视频| 乱一区二区av| 91精品国产综合久久国产大片| 亚洲三级在线看| 国产成人99久久亚洲综合精品| 欧美日韩大陆一区二区| 亚洲欧美成人一区二区三区| 国产剧情一区二区| 欧美tickling网站挠脚心| 午夜免费欧美电影| 91福利国产成人精品照片| 国产精品久久久久9999吃药| 国产老女人精品毛片久久| 日韩欧美亚洲一区二区| 三级影片在线观看欧美日韩一区二区| 激情欧美日韩一区二区| 天堂成人国产精品一区| 在线精品亚洲一区二区不卡| 亚洲欧洲99久久| 成人中文字幕电影| 日本一区二区视频在线观看| 国产成人久久精品77777最新版本| 欧美一级欧美三级在线观看| 日韩国产精品久久久| 欧美麻豆精品久久久久久| 一区二区三区不卡在线观看| 91免费看视频| 亚洲自拍与偷拍| 欧美日韩精品一区二区天天拍小说 | 亚洲欧洲韩国日本视频| 成人中文字幕合集| 国产精品久久毛片| 91丨九色丨黑人外教| 1024成人网| 在线观看亚洲专区| 日韩国产成人精品| 欧美va亚洲va香蕉在线| 国产乱对白刺激视频不卡| 久久久久久久久久美女| 国产精品18久久久久久久久| 国产精品久久久久影院色老大| 91麻豆国产福利在线观看| 亚洲精品成人少妇| 欧美一区二区在线视频| 国产精品18久久久久久久久久久久 | 午夜欧美2019年伦理| 精品免费国产二区三区| 懂色av中文字幕一区二区三区 | 成人免费毛片a| 亚洲精品高清在线| 精品欧美一区二区在线观看 | 国产精品亚洲视频| 一区二区三区四区乱视频| 777xxx欧美| 成人免费视频一区二区| 亚洲码国产岛国毛片在线| 欧美美女喷水视频| 成人午夜大片免费观看| 香蕉影视欧美成人| 国产欧美一区二区三区鸳鸯浴| 色综合一个色综合亚洲| 久久精品国产一区二区| |精品福利一区二区三区| 91精品国产乱码| av影院午夜一区| 看电视剧不卡顿的网站| 日韩伦理电影网| 久久嫩草精品久久久精品一| 欧美性三三影院| 国产成人av电影在线播放| 午夜精品久久久| 中文无字幕一区二区三区| 欧美精品v日韩精品v韩国精品v| 国产不卡视频一区二区三区| 天堂午夜影视日韩欧美一区二区| 国产午夜精品久久久久久久| 欧美日韩精品欧美日韩精品一综合| 国产成人av电影在线观看| 日日夜夜精品视频天天综合网| 亚洲少妇屁股交4| 欧美mv和日韩mv的网站| 欧美裸体一区二区三区| 91免费看片在线观看| 成人永久aaa| 国产精品1区2区| 激情五月播播久久久精品| 亚洲国产精品一区二区久久| 中文字幕中文字幕在线一区 | 久久九九影视网| 日韩网站在线看片你懂的| 欧美日韩一区二区三区四区五区| 成人妖精视频yjsp地址| 国产精品91xxx| 国产精品资源在线观看| 美美哒免费高清在线观看视频一区二区 | 日本二三区不卡| aaa欧美色吧激情视频| 国产精品一区二区在线观看不卡 | 中文字幕一区二区三区四区不卡| 久久色.com| 亚洲精品一区二区精华| 欧美成人三级在线| 欧美电影免费观看完整版| 91精品国产免费| 日韩三级视频在线看| 日韩免费一区二区三区在线播放| 日韩一区二区三区av| 91精品国产麻豆| 精品国产精品网麻豆系列| 欧美成人vps| 久久亚洲影视婷婷| 久久精品日产第一区二区三区高清版 | 91视频免费看| 91在线porny国产在线看| 成人av电影在线观看| 欧美少妇性性性| 欧美日韩亚洲综合一区二区三区| 在线免费观看日本欧美| 91精品办公室少妇高潮对白| 日本韩国视频一区二区| 欧美性感一区二区三区| 9191国产精品| 欧美精品一区二区三区很污很色的| 精品国产乱码久久久久久1区2区 | www.欧美.com| 欧美色图12p| 欧美人体做爰大胆视频| 日韩女优制服丝袜电影| 亚洲精品一区二区在线观看| 国产欧美一区二区精品秋霞影院| 国产精品亲子伦对白| 亚洲欧美日韩久久| 天天色天天操综合| 国产一区二区精品在线观看| av电影在线观看一区| 欧美色手机在线观看| 精品久久五月天| 亚洲欧美另类久久久精品| 日韩精品久久理论片| 粉嫩久久99精品久久久久久夜| 91浏览器在线视频| 欧美mv日韩mv国产网站| 亚洲丝袜美腿综合| 久久se精品一区二区| 成人高清免费在线播放| 欧美日韩国产综合一区二区| 亚洲精品在线观看视频| 亚洲宅男天堂在线观看无病毒| 蜜桃av一区二区| 91丨porny丨最新| 2欧美一区二区三区在线观看视频| 国产精品国产自产拍在线| 欧美a一区二区| 色综合色狠狠综合色| www国产精品av| 日韩二区三区四区| 91蜜桃免费观看视频| 日韩免费成人网| 亚洲一区二区三区四区在线免费观看 | 韩日欧美一区二区三区| 欧美在线小视频| 亚洲国产成人在线| 久久成人免费网| 欧洲精品在线观看| 国产精品视频线看| 美女视频一区二区三区| 欧美日韩免费观看一区二区三区| 国产日韩成人精品| 久久精品国产77777蜜臀| 在线区一区二视频| 国产精品的网站| 丁香一区二区三区| 欧美va亚洲va国产综合| 日韩高清不卡在线| 欧美乱妇20p| 亚洲午夜电影在线| 91久久线看在观草草青青| 国产精品嫩草99a| 国产成人精品aa毛片| 久久影视一区二区| 狠狠色狠狠色综合| 精品免费一区二区三区| 蜜臀久久99精品久久久画质超高清| 在线欧美日韩精品| 亚洲一区在线播放| 色综合久久中文字幕综合网 | 日本成人在线视频网站| 日本乱人伦aⅴ精品| 亚洲精品国产精品乱码不99 | 久久天堂av综合合色蜜桃网| 美女脱光内衣内裤视频久久网站| 欧美放荡的少妇| 婷婷久久综合九色国产成人|