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

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

?? backtrace.cpp

?? 一套DDR OL 游戲源碼.也就是所謂的SMO.內置SQL 及其完善的源碼 可以用作2次開發等
?? CPP
字號:

#include "Backtrace.h"
#include "../crashDefines.h"

#include <unistd.h>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <cerrno>
#include <fcntl.h>

#if defined(LINUX)
#include "LinuxThreadHelpers.h"

static const char *itoa(unsigned n)
{
	static char ret[32];
	char *p = ret;
	for( int div = 1000000000; div > 0; div /= 10 )
	{
		*p++ = (n / div) + '0';
		n %= div;
	}
	*p = 0;
	p = ret;
	while( p[0] == '0' && p[1] )
		++p;
	return p;
}

static intptr_t xtoi( const char *hex )
{
	intptr_t ret = 0;
	while( 1 )
	{
		int val = -1;
		if( *hex >= '0' && *hex <= '9' )
			val = *hex - '0';
		else if( *hex >= 'A' && *hex <= 'F' )
			val = *hex - 'A' + 10;
		else if( *hex >= 'a' && *hex <= 'f' )
			val = *hex - 'a' + 10;
		else
			break;
		hex++;

		ret *= 16;
		ret += val;
	}
	return ret;
}

enum { READABLE_ONLY=1, EXECUTABLE_ONLY=2 };
static int get_readable_ranges( const void **starts, const void **ends, int size, int type=READABLE_ONLY )
{
	char path[PATH_MAX] = "/proc/";
	strcat( path, itoa(getpid()) );
	strcat( path, "/maps" );

	int fd = open(path, O_RDONLY);
	if( fd == -1 )
		return false;

	/* Format:
	 *
	 * 402dd000-402de000 rw-p 00010000 03:03 16815669   /lib/libnsl-2.3.1.so
	 * or
	 * bfffb000-c0000000 rwxp ffffc000 00:00 0
	 *
	 * Look for the range that includes the stack pointer. */
	char file[1024];
	int file_used = 0;
	bool eof = false;
	int got = 0;
	while( !eof && got < size-1 )
	{
		int ret = read( fd, file+file_used, sizeof(file) - file_used);
		if( ret < int(sizeof(file)) - file_used)
			eof = true;

		file_used += ret;

		/* Parse lines. */
		while( got < size )
		{
			char *p = (char *) memchr( file, '\n', file_used );
			if( p == NULL )
				break;
			*p++ = 0;

			char line[1024];
			strcpy( line, file );
			memmove(file, p, file_used);
			file_used -= p-file;

			/* Search for the hyphen. */
			char *hyphen = strchr( line, '-' );
			if( hyphen == NULL )
				continue; /* Parse error. */


			/* Search for the space. */
			char *space = strchr( hyphen, ' ' );
			if( space == NULL )
				continue; /* Parse error. */

			/* " rwxp".  If space[1] isn't 'r', then the block isn't readable. */
			if( type & READABLE_ONLY )
				if( strlen(space) < 2 || space[1] != 'r' )
					continue;
			/* " rwxp".  If space[3] isn't 'x', then the block isn't readable. */
			if( type & EXECUTABLE_ONLY )
				if( strlen(space) < 4 || space[3] != 'x' )
					continue;

			/* If, for some reason, either end is NULL, skip it; that's our terminator. */
			const void *start = (const void *) xtoi( line );
			const void *end = (const void *) xtoi( hyphen+1 );
			if( start != NULL && end != NULL )
			{
				*starts++ = start;
				*ends++ = end;
			}

			++got;
		}

		if( file_used == sizeof(file) )
		{
			/* Line longer than the buffer.  Weird; bail. */
			break;
		}
	}

	close(fd);

	*starts++ = NULL;
	*ends++ = NULL;

	return got;
}

/* If the address is readable (eg. reading it won't cause a segfault), return
 * the block it's in.  Otherwise, return -1. */
static int find_address( const void *p, const void **starts, const void **ends )
{
	for( int i = 0; starts[i]; ++i )
	{
		/* Found it. */
		if( starts[i] <= p && p < ends[i] )
			return i;
	}

	return -1;
}

static void *SavedStackPointer = NULL;

void InitializeBacktrace()
{
	static bool bInitialized = false;
	if( bInitialized )
		return;
	bInitialized = true;

	/* We might have a different stack in the signal handler.  Record a pointer
	 * that lies in the real stack, so we can look it up later. */
	SavedStackPointer = __builtin_frame_address(0);
}

/* backtrace() for x86 Linux, tested with kernel 2.4.18, glibc 2.3.1. */
const void *g_ReadableBegin[1024], *g_ReadableEnd[1024];
const void *g_ExecutableBegin[1024], *g_ExecutableEnd[1024];
/* Indexes in g_ReadableBegin of the stack(s), or -1: */
int g_StackBlock1, g_StackBlock2;

/* This matches the layout of the stack.  The frame pointer makes the
 * stack a linked list. */
struct StackFrame
{
	const StackFrame *link;
	const void *return_address;
};

/* Return true if the given pointer is in readable memory, and on the stack. */
bool IsOnStack( const void *p )
{
	int val = find_address( p, g_ReadableBegin, g_ReadableEnd );
	return val != -1 && (val == g_StackBlock1 || val == g_StackBlock2 );
}

/* Return true if the given pointer is in executable memory. */
bool IsExecutableAddress( const void *p )
{
	int val = find_address( p, g_ExecutableBegin, g_ExecutableEnd );
	return val != -1;
}

/* Return true if the given stack frame is in readable memory. */
bool IsReadableFrame( const StackFrame *frame )
{
	if( !IsOnStack( &frame->link ) )
		return false;
	if( !IsOnStack( &frame->return_address ) )
		return false;
	return true;
}

/* The following from VirtualDub: */
/* ptr points to a return address, and does not have to be word-aligned. */
static bool PointsToValidCall( const void *ptr )
{
	const char *buf = (char *) ptr;

	/* We're reading buf backwards, between buf[-7] and buf[-1].  Find out how
	 * far we can read. */
	int len = 7;
	while( len )
	{
		int val = find_address( buf-len, g_ReadableBegin, g_ReadableEnd );
		if( val != -1 )
			break;
		--len;
	}

	// Permissible CALL sequences that we care about:
	//
	//	E8 xx xx xx xx			CALL near relative
	//	FF (group 2)			CALL near absolute indirect
	//
	// Minimum sequence is 2 bytes (call eax).
	// Maximum sequence is 7 bytes (call dword ptr [eax+disp32]).

	if (len >= 5 && buf[-5] == '\xe8')
		return true;

	// FF 14 xx					CALL [reg32+reg32*scale]
	if (len >= 3 && buf[-3] == '\xff' && buf[-2]=='\x14')
		return true;

	// FF 15 xx xx xx xx		CALL disp32
	if (len >= 6 && buf[-6] == '\xff' && buf[-5]=='\x15')
		return true;

	// FF 00-3F(!14/15)			CALL [reg32]
	if (len >= 2 && buf[-2] == '\xff' && (unsigned char)buf[-1] < '\x40')
		return true;

	// FF D0-D7					CALL reg32
	if (len >= 2 && buf[-2] == '\xff' && char(buf[-1]&0xF8) == '\xd0')
		return true;

	// FF 50-57 xx				CALL [reg32+reg32*scale+disp8]
	if (len >= 3 && buf[-3] == '\xff' && char(buf[-2]&0xF8) == '\x50')
		return true;

	// FF 90-97 xx xx xx xx xx	CALL [reg32+reg32*scale+disp32]
	if (len >= 7 && buf[-7] == '\xff' && char(buf[-6]&0xF8) == '\x90')
		return true;

	return false;
}


/* Return true if frame appears to be a legitimate, readable stack frame. */
bool IsValidFrame( const StackFrame *frame )
{
	if( !IsReadableFrame( frame ) )
		return false;

	/* The frame link should only go upwards. */
	if( frame->link <= frame )
		return false;

	/* The link should be on the stack. */
	if( !IsOnStack( frame->link ) )
		return false;

	/* The return address should be in a readable, executable page. */
	if( !IsExecutableAddress( frame->return_address ) )
		return false;

	/* The return address should follow a CALL opcode. */
	if( !PointsToValidCall(frame->return_address) )
		return false;

	return true;
}

/* This x86 backtracer attempts to walk the stack frames.  If we come to a
 * place that doesn't look like a valid frame, we'll look forward and try
 * to find one again. */
static void do_backtrace( const void **buf, size_t size, const BacktraceContext *ctx )
{
	/* Read /proc/pid/maps to find the address range of the stack. */
	get_readable_ranges( g_ReadableBegin, g_ReadableEnd, 1024 );
	get_readable_ranges( g_ExecutableBegin, g_ExecutableEnd, 1024, READABLE_ONLY|EXECUTABLE_ONLY );

	/* Find the stack memory blocks. */
	g_StackBlock1 = find_address( ctx->sp, g_ReadableBegin, g_ReadableEnd );
	g_StackBlock2 = find_address( SavedStackPointer, g_ReadableBegin, g_ReadableEnd );

	/* Put eip at the top of the backtrace. */
	/* XXX: We want EIP even if it's not valid, but we can't put NULL on the
	 * list, since it's NULL-terminated.  Hmm. */
	unsigned i=0;
	if( i < size-1 && ctx->ip ) // -1 for NULL
		buf[i++] = ctx->ip;

	/* If we did a CALL to an invalid address (eg. call a NULL callback), then
	 * we won't have a stack frame for the function that called it (since the
	 * stack frame is set up by the called function), but if esp hasn't been
	 * changed after the CALL, the return address will be esp[0].  Grab it. */
	if( IsOnStack( ctx->sp ) )
	{
		const void *p = ((const void **) ctx->sp)[0];
		if( IsExecutableAddress( p ) && PointsToValidCall( p ) && i < size-1 ) // -1 for NULL
			buf[i++] = p;
	}

#if 0
	/* ebp is usually the frame pointer. */
	const StackFrame *frame = (StackFrame *) ctx->bp;

	/* If ebp doesn't point to a valid stack frame, we're probably in
	 * -fomit-frame-pointer code.  Ignore it; use esp instead.  It probably
	 * won't point to a stack frame, but it should at least give us a starting
	 * point in the stack. */
	if( !IsValidFrame( frame ) )
		frame = (StackFrame *) ctx->sp;
#endif

	/* Actually, let's just use esp.  Even if ebp points to a valid stack frame, there might be
	 * -fomit-frame-pointer calls in front of it, and we want to get those. */
	const StackFrame *frame = (StackFrame *) ctx->sp;

	while( i < size-1 ) // -1 for NULL
	{
		/* Make sure that this frame address is readable, and is on the stack. */
		if( !IsReadableFrame( frame ) )
			break;

		if( !IsValidFrame( frame ) )
		{
			/* We've lost the frame.  We might have crashed while in a call in -fomit-frame-pointer
			 * code.  Iterate through the stack word by word.  If a word is possibly a valid return
			 * address, record it.  This is important; if we don't do this, we'll lose too many
			 * stack frames at the top of the trace.  This can have false positives, and introduce
			 * garbage into the trace, but we should eventually find a real stack frame. */
			void **p = (void **) frame;
			if( IsExecutableAddress( *p ) && PointsToValidCall( *p ) )
				buf[i++] = *p;

			/* The frame pointer is invalid.  Just move forward one word. */
			frame = (StackFrame *) (((char *)frame)+4);
			continue;
		}

		/* Valid frame.  Store the return address, and hop forward. */
		buf[i++] = frame->return_address;
		frame = frame->link;
	}

	buf[i] = NULL;
}

#if defined(CPU_X86)
void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc )
{
	ctx->ip = (void *) uc->uc_mcontext.gregs[REG_EIP];
	ctx->bp = (void *) uc->uc_mcontext.gregs[REG_EBP];
	ctx->sp = (void *) uc->uc_mcontext.gregs[REG_ESP];
	ctx->pid = GetCurrentThreadId();
}
#elif defined(CPU_X86_64)
void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc )
{
	ctx->ip = (void *) uc->uc_mcontext.gregs[REG_RIP];
	ctx->bp = (void *) uc->uc_mcontext.gregs[REG_RBP];
	ctx->sp = (void *) uc->uc_mcontext.gregs[REG_RSP];
	ctx->pid = GetCurrentThreadId();
}
#else
#error
#endif

void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
{
	InitializeBacktrace();
	
	BacktraceContext CurrentCtx;
	if( ctx == NULL )
	{
		ctx = &CurrentCtx;

		CurrentCtx.ip = NULL;
		CurrentCtx.bp = __builtin_frame_address(0);
		CurrentCtx.sp = __builtin_frame_address(0);
		CurrentCtx.pid = GetCurrentThreadId();
	}


	do_backtrace( buf, size, ctx );
}
#elif defined(BACKTRACE_METHOD_POWERPC_DARWIN)
typedef struct Frame
{
    Frame *stackPointer;
    long conditionReg;
    void *linkReg;
} *FramePtr;

void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc )
{
	ctx->PC = (void *) uc->uc_mcontext->ss.srr0;
	ctx->FramePtr = (void *) uc->uc_mcontext->ss.r1;
}

void InitializeBacktrace() { }

void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
{
	BacktraceContext CurrentCtx;
	if( ctx == NULL )
	{
		ctx = &CurrentCtx;

		/* __builtin_frame_address is broken on OS X; it sometimes returns bogus results. */
		register void *r1 __asm__ ("r1");
		CurrentCtx.FramePtr = (void *) r1;
		CurrentCtx.PC = NULL;
	}
	
	const Frame *frame = (Frame *) ctx->FramePtr;

	unsigned i = 0;
	if( ctx->PC && i < size-1 )
		buf[i++] = ctx->PC;

	while( frame && i < size-1 ) // -1 for NULL
	{
		if( frame->linkReg )
			buf[i++] = frame->linkReg;
		
		frame = frame->stackPointer;
	}

	buf[i] = NULL;
}

#else

#warning Undefined BACKTRACE_METHOD_*
void InitializeBacktrace() { }

void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
{
    buf[0] = BACKTRACE_METHOD_NOT_AVAILABLE;
    buf[1] = NULL;
}

#endif

/*
 * (c) 2003-2004 Glenn Maynard
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, and/or sell copies of the Software, and to permit persons to
 * whom the Software is furnished to do so, provided that the above
 * copyright notice(s) and this permission notice appear in all copies of
 * the Software and that both the above copyright notice(s) and this
 * permission notice appear in supporting documentation.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
综合久久一区二区三区| 中文字幕欧美一| 亚洲少妇中出一区| 麻豆精品久久久| 91免费在线播放| 精品对白一区国产伦| 亚洲va天堂va国产va久| 成人一区二区视频| 久久婷婷国产综合精品青草| 婷婷激情综合网| 91精品福利视频| 中文字幕av资源一区| 麻豆国产91在线播放| 欧美日韩的一区二区| 亚洲天堂2014| www.成人在线| 国产欧美精品国产国产专区 | 国产欧美一区二区精品仙草咪| 五月天亚洲婷婷| 欧美综合天天夜夜久久| 亚洲欧洲日产国码二区| 国产寡妇亲子伦一区二区| 日韩三级免费观看| 日韩精品一卡二卡三卡四卡无卡| 色狠狠综合天天综合综合| 国产精品三级av| 懂色av噜噜一区二区三区av| 久久美女高清视频| 精品中文av资源站在线观看| 日韩写真欧美这视频| 视频一区二区三区中文字幕| 欧美亚洲丝袜传媒另类| 亚洲精品久久久蜜桃| 色综合久久久久| 亚洲免费av观看| 色婷婷综合久久久中文一区二区| 国产精品无遮挡| 粉嫩在线一区二区三区视频| 国产无一区二区| 成人午夜又粗又硬又大| 国产亲近乱来精品视频| 国产宾馆实践打屁股91| 中文字幕乱码一区二区免费| 成人午夜视频网站| 国产精品白丝在线| 91免费精品国自产拍在线不卡| 中文字幕一区二区三区乱码在线| zzijzzij亚洲日本少妇熟睡| 国产精品国产成人国产三级| 91热门视频在线观看| 亚洲黄色免费电影| 欧美日韩视频一区二区| 日韩在线观看一区二区| 日韩欧美在线综合网| 精品写真视频在线观看| 国产片一区二区| 一本色道久久综合亚洲aⅴ蜜桃| 亚洲精品高清视频在线观看| 欧美三电影在线| 蜜臀91精品一区二区三区| 亚洲精品一线二线三线| 国产 日韩 欧美大片| 日韩理论片在线| 欧美日韩国产乱码电影| 麻豆一区二区99久久久久| 国产日韩欧美精品一区| 91在线看国产| 亚洲不卡av一区二区三区| 日韩免费成人网| 成人免费看的视频| 一区二区三区精密机械公司| 日韩一区二区麻豆国产| 国产在线精品一区二区夜色| 欧美国产日韩亚洲一区| 色狠狠综合天天综合综合| 琪琪一区二区三区| 中文字幕精品一区二区三区精品| 91免费观看视频| 秋霞成人午夜伦在线观看| 国产偷国产偷精品高清尤物| 91黄色免费网站| 久久国产尿小便嘘嘘| 日韩毛片精品高清免费| 欧美一级日韩免费不卡| 成人一级黄色片| 日韩av二区在线播放| 中文字幕精品一区二区三区精品| 欧美日韩国产综合一区二区三区| 国产在线精品免费| 亚洲一区二区三区四区在线 | 91精品国产综合久久久久久久久久| 极品少妇xxxx精品少妇| 亚洲人123区| 欧美成人精品高清在线播放 | 麻豆国产一区二区| 日韩一区日韩二区| 欧美一区二区精品| 99re视频精品| 久久99精品久久久久| 亚洲免费av网站| 国产午夜精品一区二区三区嫩草| 欧美日韩久久不卡| 成人app网站| 免费看日韩a级影片| 国产精品久久久久久久第一福利| 日韩一区二区三区电影| 一本色道久久综合精品竹菊| 国产精品一区二区果冻传媒| 午夜精品123| 亚洲男人电影天堂| 国产嫩草影院久久久久| 日韩午夜激情免费电影| 在线看一区二区| 高清久久久久久| 久久精品国产秦先生| 一区二区三区中文在线| 国产亚洲一区二区三区| 这里只有精品99re| 日本乱人伦aⅴ精品| 国产成a人无v码亚洲福利| 蜜桃久久久久久| 亚洲国产日韩一级| 亚洲激情自拍视频| 中文字幕乱码亚洲精品一区| 精品国产一区二区三区久久影院 | 国产精品亚洲人在线观看| 视频一区二区不卡| 伊人婷婷欧美激情| 国产精品护士白丝一区av| 精品1区2区在线观看| 日韩三级.com| 欧美日韩国产中文| 欧美在线视频全部完| 色综合天天综合色综合av| 成人免费视频网站在线观看| 国产在线麻豆精品观看| 久久99热狠狠色一区二区| 天天色天天爱天天射综合| 亚洲自拍与偷拍| 亚洲精品成a人| 亚洲人吸女人奶水| 亚洲欧美视频一区| 综合久久一区二区三区| 成人免费小视频| 国产精品久久影院| 国产精品久久夜| 中文字幕一区二区在线观看 | 91麻豆精品国产91久久久久久久久| 91国偷自产一区二区使用方法| 91丨porny丨国产| 99精品国产99久久久久久白柏| 白白色 亚洲乱淫| www.日韩大片| 99精品视频在线观看| 不卡一区二区中文字幕| www.在线欧美| 97久久精品人人做人人爽 | 久久超碰97人人做人人爱| 日韩精品三区四区| 日韩高清在线电影| 日本美女一区二区三区| 免费国产亚洲视频| 激情综合色播激情啊| 国精品**一区二区三区在线蜜桃| 国产一区二区三区免费观看| 国产精品99久久久久久似苏梦涵| 国产一区二区三区| 丁香六月久久综合狠狠色| 成人av片在线观看| 色综合咪咪久久| 欧美性色aⅴ视频一区日韩精品| 欧美日韩精品三区| 91精品国产综合久久福利软件| 日韩欧美第一区| 久久精品一区二区三区不卡| 国产精品欧美极品| 亚洲视频狠狠干| 午夜亚洲国产au精品一区二区| 日韩黄色小视频| 国精产品一区一区三区mba桃花 | 粉嫩高潮美女一区二区三区| 成人18视频在线播放| 色哟哟欧美精品| 欧美二区在线观看| www国产亚洲精品久久麻豆| 欧美国产国产综合| 一区二区三区日韩| 热久久免费视频| 丁香婷婷深情五月亚洲| 日本乱人伦一区| 日韩视频在线你懂得| 国产精品拍天天在线| 亚洲成人1区2区| 蜜臀a∨国产成人精品| 成人国产精品免费网站| 在线观看欧美黄色| 精品日韩一区二区| 亚洲美女精品一区| 美脚の诱脚舐め脚责91| 成人av电影在线网|