c++ - 如何阻止重载的 new() 从 C++/Linux 中的 Ostream 调用?

标签 c++ c linux new-operator ostream

如何解决这里的崩溃问题?如何在登录文件时避免使用 new() 运算符?

我正在编写内存故障排除调试器。这将每 10 秒左右写入一个文件 - “可用的空闲 block 并将检查内存块的签名以进行缓冲区溢出运行。”这是我的设计 -

enter image description here

这是尝试进行监控的代码。一段时间后我看到崩溃。此外,Ostream 正在调用 - new 并且文件中捕获了冗余数据。我也不介意使用 C 类型的调用。

/** Headers needed for the tool **/

#include <cstdlib>
#include <stdio.h>
#include <fstream>
#include  <execinfo.h>
#include  <cxxabi.h>
#include <malloc.h>
#include <string.h>

/** timer check **/
#include <signal.h>
#include <sys/time.h>
/** timer checks ends here **/


/*** USE CASE HEADERS ***/
#include "memOperation.h"
#include  "DumpMemory.h"
/*** USE CASE HEADERS ENDS ***/


/** Buffer for adding Pattern - Signature **/
#define BUFFER (4)

/*** Array Assume-- map of pointers and size  *********/
struct pointerBlkSizeInfo
{
	unsigned long int m_PointerAddress;
	unsigned long int m_blkSize;
};


/*** String for File Name path ***/
const char *FileName = "/export/home/joshis1/DBG_REC.log";

/*** DUMP Corrupted Memory details **/
const char *FileCorruptDetails = "/export/home/joshis1/DBG_CORRUPT.log";

/**** Maintain array of pointerBlkSizeInfo **/
#define MONITOR_MEM_SIZE  (1024)
/**** Map created **************************/
pointerBlkSizeInfo ptrSizeMap[MONITOR_MEM_SIZE];

/*** Prototype *********/
static void startMonitorMem();
/*****************Prototype ends here **/


/**********Prints the caller needs rdynamic***********************/
static void printCaller( void )
{
	void *array[ 50 ];
	int size = backtrace( array, 50 );
	char **messages = backtrace_symbols( array, size );

	std::ofstream dumpfile;
	dumpfile.open(FileName);

	/* skip first and second stack frame (points here) */
	for ( int frame = 0; frame < size  && messages != NULL; ++frame )
	{
		char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;

		/* find parantheses and +address offset surrounding mangled name */
		for ( char *msg = messages[frame]; *msg; ++msg )
		{
			if ( *msg == '(' )
			{
				mangled_name = msg;
			}
			else if ( *msg == '+' )
			{
				offset_begin = msg;
			}
			else if ( *msg == ')' )
			{
				offset_end = msg;
				break;
			}
		}

		/* if the line could be processed, attempt to demangle the symbol */
		if ( mangled_name && offset_begin && offset_end &&
				mangled_name < offset_begin )
		{
			*mangled_name++ = '\0';
			*offset_begin++ = '\0';
			*offset_end++ = '\0';

			int status;
			char * real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);

			/* if demangling is successful, output the demangled function name */
			if ( status == 0 )
			{
				dumpfile<< "demangled name"<<real_name<<std::endl;
			}
			else
			{
				dumpfile<<"mangled name"<< real_name <<std::endl;
			}
			free( real_name );
		}
	}
	free( messages );

	struct mallinfo freeblockAvailable;

	freeblockAvailable = mallinfo();

	dumpfile<<"Available free space in bytes = "<<freeblockAvailable.fordblks;

	dumpfile.close();
}

/** Overloaded new Operator **/
void* operator new(std::size_t sz)
{
	unsigned int index = 0;

	char buff[4] = "ACE";

	void *mem = std::malloc(sz + BUFFER );
	std::cout<<"Strcpy Started"<<std::endl;
	strncpy((char *)((unsigned long int )mem + sz),buff,4);
	std::cout<<"Strcpy done"<<std::endl;
	printCaller();

	for(index = 0; index <= MONITOR_MEM_SIZE; index++ )
	{
		if( ptrSizeMap[index].m_PointerAddress == 0 )
		{
			ptrSizeMap[index].m_PointerAddress =  ( unsigned long int)mem;
			ptrSizeMap[index].m_blkSize = sz;
			break;
		}
	}

	if(index  > MONITOR_MEM_SIZE )
	{
		std::cout<<"MemoryTool..MapSize Increase"<<std::endl;
	}

	return mem;
}

/** Overloaded free Operator **/
void operator delete(void* ptr)
{
	std::free(ptr);

	for(unsigned int index = 0; index <= MONITOR_MEM_SIZE; index++ )
	{
		if( ptrSizeMap[index].m_PointerAddress == (unsigned long int)ptr )
		{
			ptrSizeMap[index].m_PointerAddress =  0;
			ptrSizeMap[index].m_blkSize = 0;
			break;
		}
	}
}


/**************Memory Monitor Routine--Every 10 seconds executes *******************************/
void monitorMem (int temp)
{
	struct itimerval tout_val;

	std::ofstream corruptMemFile;
	corruptMemFile.open(FileName);

	std::cout<<"Monitoring Memory!!!"<<std::endl;
	tout_val.it_interval.tv_sec = 0;
	tout_val.it_interval.tv_usec = 0;
	tout_val.it_value.tv_sec = 10; /* 10 seconds timer */
	tout_val.it_value.tv_usec = 0;

	/**** check if the memory buffer overflow occurred or not **/

	for(unsigned int index = 0; index <= MONITOR_MEM_SIZE; index++ )
	{
		if (ptrSizeMap[index].m_PointerAddress != 0 )
		{
			const char *temp = (char *) (ptrSizeMap[index].m_PointerAddress + ptrSizeMap[index].m_blkSize);

			if(strncmp(temp,"ACE",3) == 0 )
			{
				/** Matched **/
			}
			else
			{
				/** Un -Matched ***/
				std::cout<<"Shreyas..the memory is corrupted";
				corruptMemFile<<"Pointer corrupted = "<<ptrSizeMap[index].m_PointerAddress<<" Size = "<<ptrSizeMap[index].m_blkSize;

			}
		}

	}

	corruptMemFile.close();
	signal(SIGALRM,monitorMem);
	setitimer(ITIMER_REAL, &tout_val,0);

}

/*** Start Monitoring the Mem -- Timer Initialization ***/
static void startMonitorMem()
{
	/** initialize the memory lookup map to zero **/
	memset(&ptrSizeMap,0,sizeof(pointerBlkSizeInfo)*MONITOR_MEM_SIZE);

	struct itimerval tout_val;
	tout_val.it_interval.tv_sec = 0;
	tout_val.it_interval.tv_usec = 0;
	tout_val.it_value.tv_sec = 10; /* 10 seconds timer */
	tout_val.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &tout_val,0);
	signal(SIGALRM,monitorMem); /* set the Alarm signal capture */
}



/********************Main routine ************************/
int main(int argc, char *argv[])
{

	/** Install the memory monitoring now **/
	startMonitorMem();

	/** USE CASE STARTS HERE **/

	MemPlay *pCorruptMem = new MemPlay();
	pCorruptMem->MyMemPlay();

	DumpMemory *pSafeMem = new DumpMemory();
	pSafeMem->MyDumpMemory();

	/*** USE CASE ENDS HERE **/

	while(1)
	{

	}


	return 0;
}

这是输出 -

 <<< a lot of strCpy calls >>>
Strcpy done
Strcpy Started
Strcpy done
Strcpy Started
Strcpy done
Strcpy Started
Strcpy done
Strcpy Started
Strcpy done
Strcpy Started
Strcpy done
Strcpy Started
Strcpy done
Strcpy Started
Strcpy done
*** glibc detected *** ./prog.out: malloc(): memory corruption: 0x0999a050 ***
======= Backtrace: =========
/lib/libc.so.6[0x4bfc99f2]
/lib/libc.so.6[0x4bfcbad2]
/lib/libc.so.6(__libc_malloc+0x65)[0x4bfcde75]
./prog.out(_Znwj+0x22)[0x8049130]
./prog.out(main+0x36)[0x80494e0]
/lib/libc.so.6(__libc_start_main+0xf3)[0x4bf6a6b3]
./prog.out[0x8048da1]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 fd:00 31854551   /export/home/joshis1/Eclipse_WorkSpace1/memory_tool_hook/src/prog.out
0804a000-0804b000 rw-p 00001000 fd:00 31854551   /export/home/joshis1/Eclipse_WorkSpace1/memory_tool_hook/src/prog.out
0804b000-0804d000 rw-p 00000000 00:00 0 
0999a000-099bf000 rw-p 00000000 00:00 0          [heap]
4bf28000-4bf49000 r-xp 00000000 fd:00 41030167   /lib/ld-2.14.90.so
4bf49000-4bf4a000 r--p 00020000 fd:00 41030167   /lib/ld-2.14.90.so
4bf4a000-4bf4b000 rw-p 00021000 fd:00 41030167   /lib/ld-2.14.90.so
4bf51000-4c0fb000 r-xp 00000000 fd:00 41030168   /lib/libc-2.14.90.so
4c0fb000-4c0fc000 ---p 001aa000 fd:00 41030168   /lib/libc-2.14.90.so
4c0fc000-4c0fe000 r--p 001aa000 fd:00 41030168   /lib/libc-2.14.90.so
4c0fe000-4c0ff000 rw-p 001ac000 fd:00 41030168   /lib/libc-2.14.90.so
4c0ff000-4c102000 rw-p 00000000 00:00 0 
4c104000-4c12d000 r-xp 00000000 fd:00 41030181   /lib/libm-2.14.90.so
4c12d000-4c12e000 r--p 00028000 fd:00 41030181   /lib/libm-2.14.90.so
4c12e000-4c12f000 rw-p 00029000 fd:00 41030181   /lib/libm-2.14.90.so
4c161000-4c17d000 r-xp 00000000 fd:00 41030182   /lib/libgcc_s-4.6.3-20120306.so.1
4c17d000-4c17e000 rw-p 0001b000 fd:00 41030182   /lib/libgcc_s-4.6.3-20120306.so.1
4c4d1000-4c5b3000 r-xp 00000000 fd:00 48761002   /usr/lib/libstdc++.so.6.0.16
4c5b3000-4c5b7000 r--p 000e1000 fd:00 48761002   /usr/lib/libstdc++.so.6.0.16
4c5b7000-4c5b9000 rw-p 000e5000 fd:00 48761002   /usr/lib/libstdc++.so.6.0.16
4c5b9000-4c5bf000 rw-p 00000000 00:00 0 
b76fa000-b76fd000 rw-p 00000000 00:00 0 
b7728000-b772b000 rw-p 00000000 00:00 0 
b772b000-b772c000 r-xp 00000000 00:00 0          [vdso]
bf9e9000-bfacd000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

最佳答案

我猜,我得到了答案。我不能在这里使用 Ofstream。我应该使用基于 C 的 fopen 和 fprintf。 fopen 和 frprintf 不使用 new()。因此,它将在这里工作。 这是我的代码,现在好了。

/** Headers needed for the tool **/

#include <cstdlib>
#include <stdio.h>
#include <fstream>
#include  <execinfo.h>
#include  <cxxabi.h>
#include <malloc.h>
#include <string.h>

/** timer check **/
#include <signal.h>
#include <sys/time.h>
#include <time.h>
/** timer checks ends here **/

/*************NEED EXTRA MONITORING ************************/
#define TIME_STAMPING (1)
#define MEMORY_LEAK_MONITORING (1)
/***********************************************************/

/*** USE CASE HEADERS ***/
#include "memOperation.h"
#include  "DumpMemory.h"
/*** USE CASE HEADERS ENDS ***/


/** Buffer for adding Pattern - Signature **/
#define BUFFER (4)

/*** Array Assume-- map of pointers and size  *********/
struct pointerBlkSizeInfo
{
	unsigned long int m_PointerAddress;
	unsigned long int m_blkSize;
	int reportedFaulty;
};


/*** String for File Name path ***/
const char *FileName = "/export/home/joshis1/DBG_REC.log";

/*** DUMP Corrupted Memory details **/
const char *FileCorruptDetails = "/export/home/joshis1/DBG_CORRUPT.log";


/** Log files to record **/
FILE  *dumpfile;
FILE *corruptMemFile;

/**** Maintain array of pointerBlkSizeInfo **/
#define MONITOR_MEM_SIZE  (1024)
/**** Map created **************************/
pointerBlkSizeInfo ptrSizeMap[MONITOR_MEM_SIZE];

/*** Prototype *********/
static void startMonitorMem();
/*****************Prototype ends here **/


/**********Prints the caller needs rdynamic***********************/
static void printCaller( unsigned long int memPointerRec )
{
	void *array[ 50 ];
	int size = backtrace( array, 50 );
	char **messages = backtrace_symbols( array, size );

	/* skip first and second stack frame (points here) */
	for ( int frame = 0; frame < size  && messages != NULL; ++frame )
	{
		char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;

		/* find parantheses and +address offset surrounding mangled name */
		for ( char *msg = messages[frame]; *msg; ++msg )
		{
			if ( *msg == '(' )
			{
				mangled_name = msg;
			}
			else if ( *msg == '+' )
			{
				offset_begin = msg;
			}
			else if ( *msg == ')' )
			{
				offset_end = msg;
				break;
			}
		}

		/* if the line could be processed, attempt to demangle the symbol */
		if ( mangled_name && offset_begin && offset_end &&
				mangled_name < offset_begin )
		{
			*mangled_name++ = '\0';
			*offset_begin++ = '\0';
			*offset_end++ = '\0';

			int status;
			char * real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);

			/* if demangling is successful, output the demangled function name */
			if ( status == 0 )
			{
				fprintf(dumpfile,"demangled name %s\r\n",real_name);
				fflush(dumpfile);
			}
			else
			{
				fprintf(dumpfile,"mangled name %s\r\n",real_name);
				fflush(dumpfile);
			}
			free( real_name );
		}
	}
	free( messages );

	struct mallinfo freeblockAvailable;

	freeblockAvailable = mallinfo();

	fprintf(dumpfile,"Avail free bytes = %lu\r\n",freeblockAvailable.fordblks);
	fflush(dumpfile);
}

/** Overloaded new Operator **/
void* operator new(std::size_t sz)
{
	unsigned int index = 0;

#ifdef TIME_STAMPING
	struct timeval ts;

#endif

	char buff[4] = "ACE";

#ifdef TIME_STAMPING
	gettimeofday (&ts, NULL);
#endif

	void *mem = std::malloc(sz + BUFFER );
	std::cout<<"Strcpy Started"<<std::endl;
	strncpy((char *)((unsigned long int )mem + sz),buff,4);
	std::cout<<"Strcpy done"<<std::endl;


	unsigned long int memPointerRec = (unsigned long int)mem;

	for(index = 0; index <= MONITOR_MEM_SIZE; index++ )
	{
		if( ptrSizeMap[index].m_PointerAddress == 0 )
		{
			ptrSizeMap[index].m_PointerAddress =  ( unsigned long int)mem;
			ptrSizeMap[index].m_blkSize = sz;
#ifdef TIME_STAMPING
			fprintf(dumpfile,"Ptr alloc = %lu , Time = %d.%ds , PID = %5d \r\n",ptrSizeMap[index].m_PointerAddress,(int)(ts.tv_sec)%10000, (int)ts.tv_usec/1000,getpid());
#else
			fprintf(dumpfile,"Ptr alloc = %lu \r\n",ptrSizeMap[index].m_PointerAddress);
#endif
			fflush(dumpfile);
			printCaller(ptrSizeMap[index].m_PointerAddress);
			break;
		}
	}

	if(index  > MONITOR_MEM_SIZE )
	{
		std::cout<<"MemoryTool..MapSize Increase"<<std::endl;
	}

	return mem;
}

/** Overloaded free Operator **/
void operator delete(void* ptr)
{
	std::free(ptr);

	for(unsigned int index = 0; index <= MONITOR_MEM_SIZE; index++ )
	{
		if( ptrSizeMap[index].m_PointerAddress == (unsigned long int)ptr )
		{
			ptrSizeMap[index].m_PointerAddress =  0;
			ptrSizeMap[index].m_blkSize = 0;
			break;
		}
	}
}


/**************Memory Monitor Routine--Every 10 seconds executes *******************************/
void monitorMem (int temp)
{
	struct itimerval tout_val;

#ifdef TIME_STAMPING
	struct timeval ts;
	gettimeofday (&ts, NULL);
#endif

	std::cout<<"Monitoring Memory!!!"<<std::endl;
	tout_val.it_interval.tv_sec = 0;
	tout_val.it_interval.tv_usec = 0;
	tout_val.it_value.tv_sec = 10; /* 10 seconds timer */
	tout_val.it_value.tv_usec = 0;

	/**** check if the memory buffer overflow occurred or not **/

	for(unsigned int index = 0; index <= MONITOR_MEM_SIZE; index++ )
	{
		if (ptrSizeMap[index].m_PointerAddress != 0 )
		{
			const char *temp = (char *) (ptrSizeMap[index].m_PointerAddress + ptrSizeMap[index].m_blkSize);

			if(strncmp(temp,"ACE",3) == 0 )
			{
				/** Matched **/
			}
			else
			{
				/** Un -Matched ***/
				if(ptrSizeMap[index].reportedFaulty == 0 )
				{
					/** reported not **/
					ptrSizeMap[index].reportedFaulty = 1;
#ifdef TIME_STAMPING
					fprintf(corruptMemFile,"Pointer corrupted =  = %lu and size = %lu , Time = %d.%ds , PID = %5d \r\n",ptrSizeMap[index].m_PointerAddress,ptrSizeMap[index].m_blkSize,(int)(ts.tv_sec)%10000, (int)ts.tv_usec/1000,getpid());
#else
					fprintf(corruptMemFile,"Pointer corrupted =  = %lu and size = %lu \r\n",ptrSizeMap[index].m_PointerAddress,ptrSizeMap[index].m_blkSize );
#endif
					fflush(corruptMemFile);
					std::cout<<"Shreyas..the memory is corrupted"<<std::endl;
				}
			}
		}

	}

	/** Monitor Mem Status for Memory Leaks -- can disable this **/
#if defined (MEMORY_LEAK_MONITORING) && defined (TIME_STAMPING)

	struct mallinfo freeblockAvailable;
	freeblockAvailable = mallinfo();
	fprintf(corruptMemFile,"Avail free bytes = %lu, Time = %d.%ds , PID = %5d\r\n",freeblockAvailable.fordblks,(int)(ts.tv_sec)%10000, (int)ts.tv_usec/1000,getpid());
	fflush(corruptMemFile);

#elif MEMORY_LEAK_MONITORING
	    struct mallinfo freeblockAvailable;
		freeblockAvailable = mallinfo();
		fprintf(corruptMemFile,"Avail free bytes = %lu\r\n",freeblockAvailable.fordblks);
		fflush(corruptMemFile);
#endif



	signal(SIGALRM,monitorMem);
	setitimer(ITIMER_REAL, &tout_val,0);

}

/*** Start Monitoring the Mem -- Timer Initialization ***/
static void startMonitorMem()
{
	/** initialize the memory lookup map to zero **/
	memset(&ptrSizeMap,0,sizeof(pointerBlkSizeInfo)*MONITOR_MEM_SIZE);

	dumpfile = fopen(FileName,"w");
	corruptMemFile = fopen(FileCorruptDetails,"w");

	/** initialize the memory lookup map to zero **/
	memset(&ptrSizeMap,0,sizeof(pointerBlkSizeInfo)*MONITOR_MEM_SIZE);

	struct itimerval tout_val;
	tout_val.it_interval.tv_sec = 0;
	tout_val.it_interval.tv_usec = 0;
	tout_val.it_value.tv_sec = 10; /* 10 seconds timer */
	tout_val.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &tout_val,0);
	signal(SIGALRM,monitorMem); /* set the Alarm signal capture */
}



/********************Main routine ************************/
int main(int argc, char *argv[])
{

	/** Install the memory monitoring now **/
	startMonitorMem();

	/** USE CASE STARTS HERE **/

	MemPlay *pCorruptMem = new MemPlay();
	pCorruptMem->MyMemPlay();

	DumpMemory *pSafeMem = new DumpMemory();
	pSafeMem->MyDumpMemory();

	/** delete the memory now **/
	//pCorruptMem->clearMem();

	/*** USE CASE ENDS HERE **/

	while(1)
	{

	}


	return 0;
}

关于c++ - 如何阻止重载的 new() 从 C++/Linux 中的 Ostream 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28715052/

相关文章:

linux - LINUX 中的串行通信 (RS232)

c++ - 拔掉以太网时没有出现 Winsock 错误

c++ - 将 MATLAB 单元格类型转换为 C++

c++ - int 限制与 long 限制

c++ - MSVC 2017 下缺少 C11 strerrorlen_s 函数

c# - 更改扩展 Controller 中 ViewData 的类型

c - 如何在GDB模式下传递输入数据进行编程 C. 已传递参数并运行程序

c - xv6 中的 cgaputc(int c)/uartputc(int c)/constputc(int c) 有什么区别?

linux - 通过终端安装eclipse

linux - 将 "standalone"版本的 Wine 安装到 Ubuntu 目录