示例#1
0
//******************************************************************
void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, 
						   const CONTEXT* context_record, 
						   LLSD& info)
//******************************************************************
// Fill Str with call stack info.
// pException can be either GetExceptionInformation() or NULL.
// If pException = NULL - get current call stack.
{
	LPWSTR	Module_Name = new WCHAR[MAX_PATH];
	PBYTE	Module_Addr = 0;
	LLSD params;
	PBYTE	Esp = NULL;
	LLSD tmp_info;

	bool fake_frame = false;
	bool ebp_used = false;
	const int HEURISTIC_MAX_WALK = 20;
	int heuristic_walk_i = 0;
	int Ret_Addr_I = 0;

	WSTACK	Stack = {0, 0};
	PSTACK	Ebp;

	if (exception_record && context_record)		//fake frame for exception address
	{
		Stack.Ebp = (PSTACK)(context_record->Ebp);
		Stack.Ret_Addr = (PBYTE)exception_record->ExceptionAddress;
		Ebp = &Stack;
		Esp = (PBYTE) context_record->Esp;
		fake_frame = true;
	}
	else if(context_record)
	{
        Ebp = (PSTACK)(context_record->Ebp);
		Esp = (PBYTE)(context_record->Esp);
	}
	else
	{
		Ebp = (PSTACK)&exception_record - 1;	//frame addr of Get_Call_Stack()
		Esp = (PBYTE)&exception_record;

		// Skip frame of Get_Call_Stack().
		if (!IsBadReadPtr(Ebp, sizeof(PSTACK)))
			Ebp = Ebp->Ebp;		//caller ebp
	}

	// Trace CALL_TRACE_MAX calls maximum - not to exceed DUMP_SIZE_MAX.
	// Break trace on wrong stack frame.
	for (Ret_Addr_I = 0;
		heuristic_walk_i < HEURISTIC_MAX_WALK && 
		Ret_Addr_I < CALL_TRACE_MAX && !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr));
		Ret_Addr_I++)
	{
		// If module with Ebp->Ret_Addr found.
		if (Get_Module_By_Ret_Addr(Ebp->Ret_Addr, Module_Name, Module_Addr))
		{
			// Save module's address and full path.
			tmp_info["CallStack"][Ret_Addr_I]["ModuleName"] = ll_convert_wide_to_string(Module_Name);
			tmp_info["CallStack"][Ret_Addr_I]["ModuleAddress"] = (int)Module_Addr;
			tmp_info["CallStack"][Ret_Addr_I]["CallOffset"] = (int)(Ebp->Ret_Addr - Module_Addr);

			// Save 5 params of the call. We don't know the real number of params.
			if (fake_frame && !Ret_Addr_I)	//fake frame for exception address
				params[0] = "Exception Offset";
			else if (!IsBadReadPtr(Ebp, sizeof(PSTACK) + 5 * sizeof(DWORD)))
			{
				for(int j = 0; j < 5; ++j)
				{
					params[j] = (int)Ebp->Param[j];
				}
			}
			tmp_info["CallStack"][Ret_Addr_I]["Parameters"] = params;
		}

		tmp_info["CallStack"][Ret_Addr_I]["ReturnAddress"] = (int)Ebp->Ret_Addr;

		// get ready for next frame
		// Set ESP to just after return address.  Not the real esp, but just enough after the return address
		if(!fake_frame) {
			Esp = (PBYTE)Ebp + 8;
		} 
		else
		{
			fake_frame = false;
		}

		// is next ebp valid?
		// only run if we've never found a good ebp
		// and make sure the one after is valid as well
		if(	!ebp_used && 
			shouldUseStackWalker(Ebp, 2))
		{
			heuristic_walk_i++;
			PBYTE new_ebp = get_valid_frame(Esp);
			if (new_ebp != NULL)
			{
				Ebp = (PSTACK)new_ebp;
			}
		}
		else
		{
			ebp_used = true;
			Ebp = Ebp->Ebp;
		}
	}
/* TODO remove or turn this code back on to edit the stack after i see a few raw ones. -Palmer
	// Now go back through and edit out heuristic stacks that could very well be bogus.
	// Leave the top and the last 3 stack chosen by the heuristic, however.
	if(heuristic_walk_i > 2)
	{
		info["CallStack"][0] = tmp_info["CallStack"][0];
		std::string ttest = info["CallStack"][0]["ModuleName"];
		for(int cur_frame = 1; 
			(cur_frame + heuristic_walk_i - 2 < Ret_Addr_I); 
			++cur_frame)
		{
			// edit out the middle heuristic found frames
			info["CallStack"][cur_frame] = tmp_info["CallStack"][cur_frame + heuristic_walk_i - 2];
		}
	}
	else
	{
		info = tmp_info;
	}
*/
	info = tmp_info;
	info["HeuristicWalkI"] = heuristic_walk_i;
	info["EbpUsed"] = ebp_used;

} //Get_Call_Stack
示例#2
0
//*************************************************************
LLSD WINAPI Get_Exception_Info(PEXCEPTION_POINTERS pException)
//*************************************************************
// Allocate Str[DUMP_SIZE_MAX] and return Str with dump, if !pException - just return call stack in Str.
{
	LLSD info;
	LPWSTR		Str;
	int			Str_Len;
//	int			i;
	LPWSTR		Module_Name = new WCHAR[MAX_PATH];
	PBYTE		Module_Addr;
	HANDLE		hFile;
	FILETIME	Last_Write_Time;
	FILETIME	Local_File_Time;
	SYSTEMTIME	T;

	Str = new WCHAR[DUMP_SIZE_MAX];
	Str_Len = 0;
	if (!Str)
		return NULL;
	
	Get_Version_Str(info);
	
	GetModuleFileName(NULL, Str, MAX_PATH);
	info["Process"] = ll_convert_wide_to_string(Str);
	info["ThreadID"] = (S32)GetCurrentThreadId();

	// If exception occurred.
	if (pException)
	{
		EXCEPTION_RECORD &	E = *pException->ExceptionRecord;
		CONTEXT &			C = *pException->ContextRecord;

		// If module with E.ExceptionAddress found - save its path and date.
		if (Get_Module_By_Ret_Addr((PBYTE)E.ExceptionAddress, Module_Name, Module_Addr))
		{
			info["Module"] = ll_convert_wide_to_string(Module_Name);

			if ((hFile = CreateFile(Module_Name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
			{
				if (GetFileTime(hFile, NULL, NULL, &Last_Write_Time))
				{
					FileTimeToLocalFileTime(&Last_Write_Time, &Local_File_Time);
					FileTimeToSystemTime(&Local_File_Time, &T);

					info["DateModified"] = llformat("%02d/%02d/%d", T.wMonth, T.wDay, T.wYear);
				}
				CloseHandle(hFile);
			}
		}
		else
		{
			info["ExceptionAddr"] = (int)E.ExceptionAddress;
		}
		
		info["ExceptionCode"] = (int)E.ExceptionCode;
		
		/*
		//TODO: Fix this
		if (E.ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
		{
			// Access violation type - Write/Read.
			LLSD exception_info;
			exception_info["Type"] = E.ExceptionInformation[0] ? "Write" : "Read";
			exception_info["Address"] = llformat("%08x", E.ExceptionInformation[1]);
			info["Exception Information"] = exception_info;
		}
		*/

		
		// Save instruction that caused exception.
		/*
		std::string str;
		for (i = 0; i < 16; i++)
			str += llformat(" %02X", PBYTE(E.ExceptionAddress)[i]);
		info["Instruction"] = str;
		*/
		LLSD registers;
		registers["EAX"] = (int)C.Eax;
		registers["EBX"] = (int)C.Ebx;
		registers["ECX"] = (int)C.Ecx;
		registers["EDX"] = (int)C.Edx;
		registers["ESI"] = (int)C.Esi;
		registers["EDI"] = (int)C.Edi;
		registers["ESP"] = (int)C.Esp;
		registers["EBP"] = (int)C.Ebp;
		registers["EIP"] = (int)C.Eip;
		registers["EFlags"] = (int)C.EFlags;
		info["Registers"] = registers;
	} //if (pException)
	
	// Save call stack info.
	Get_Call_Stack(pException->ExceptionRecord, pException->ContextRecord, info);

	return info;
} //Get_Exception_Info
示例#3
0
	U32 cycles = seconds * CYCLES_PER_SECOND;
	while( cycles-- )
	{
		update_messages();
		ms_sleep(1000 / CYCLES_PER_SECOND);
	}
}

// Include product name in the window caption.
void LLCrashLoggerWindows::ProcessCaption(HWND hWnd)
{
	TCHAR templateText[MAX_STRING];		/* Flawfinder: ignore */
	TCHAR header[MAX_STRING];
	std::string final;
	GetWindowText(hWnd, templateText, sizeof(templateText));
	final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str());
	ConvertLPCSTRToLPWSTR(final.c_str(), header);
	SetWindowText(hWnd, header);
}


// Include product name in the diaog item text.
void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem)
{
	TCHAR templateText[MAX_STRING];		/* Flawfinder: ignore */
	TCHAR header[MAX_STRING];
	std::string final;
	GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText));
	final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str());
	ConvertLPCSTRToLPWSTR(final.c_str(), header);
	SetDlgItemText(hWnd, nIDDlgItem, header);