는 어떻게 EXCEPTION_POINTERS
을받을 수 있나요, 즉 모두 : EExternal
예외 동안EExternal 예외가 발생하는 동안 EXCEPTION_POINTERS를받는 방법은 무엇입니까?
PEXCEPTION_RECORD
및PCONTEXT
데이터? 윈도우에서 예외가 발생하면
는 배경
는 , 그것은PEXCEPTION_POINTERS
통과
; 예외 정보에 대한 포인터 : 수행
EExternal = class(Exception)
public
ExceptionRecord: PExceptionRecord;
end;
방법 EExternal
예외 중 : 델파이이 나에게 EExternal
예외가 발생하면
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
, 그것은 절반 만 정보 만 PEXCEPTION_RECORD
을 포함 나는 둘 다 얻습니까?
내가 델파이에서 MiniDumpWriteDump
기능을 사용하여 미니 덤프를 작성하는 것을 시도하고있다
사용 예.
function MiniDumpWriteDump(
hProcess: THandle; //A handle to the process for which the information is to be generated.
ProcessID: DWORD; //The identifier of the process for which the information is to be generated.
hFile: THandle; //A handle to the file in which the information is to be written.
DumpType: MINIDUMP_TYPE; //The type of information to be generated.
{in, optional}ExceptionParam: PMinidumpExceptionInformation; //A pointer to a MINIDUMP_EXCEPTION_INFORMATION structure describing the client exception that caused the minidump to be generated.
{in, optional}UserStreamParam: PMinidumpUserStreamInformation;
{in, optional}CallbackParam: PMinidumpCallbackInformation): Boolean;
기본적인 수준에서 내가 세 개의 선택적 매개 변수를 생략 할 수 있습니다 :
기능은 몇 가지 선택적 매개 변수가
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFileHandle,
nil, //PMinidumpExceptionInformation
nil,
nil);
을 그리고 성공합니다. 단점은 미니 덤프에 예외 정보가 빠져 있다는 것입니다. 이 정보는 (선택적)는 4 miniExceptionInfo 매개 변수를 사용하여 전달 : 나는 예외가 발생하면 Windows에서 제공되는 EXCEPTION_POINTERS
에서 얻을 수있는 방법이 필요 제외하고
TMinidumpExceptionInformation = record
ThreadId: DWORD;
ExceptionPointers: PExceptionPointers;
ClientPointers: BOOL;
end;
PMinidumpExceptionInformation = ^TMinidumpExceptionInformation;
이 좋다.
TExceptionPointers
구조는 두 멤버가 포함
EXCEPTION_POINTERS = record
ExceptionRecord : PExceptionRecord;
ContextRecord : PContext;
end;
내가 델파이의 EExternal
예외가 모든 "윈도우" 예외의 기본임을 알고는 PExceptionRecord
필요 포함
EExternal = class(Exception)
public
ExceptionRecord: PExceptionRecord;
end;
하지만 관련이 없습니다. ContextRecord
.
PEXCEPTION_RECORD
은 충분하지 않습니까?
나는 EXCEPTION_POINTERS
떠나 MiniDumpWriteDump
-ContextRecord
전무 통과하려고하면 :
procedure TDataModule1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
var
ei: TExceptionPointers;
begin
if (E is EExternal) then
begin
ei.ExceptionRecord := EExternal(E).ExceptionRecord;
ei.ContextRecord := nil;
GenerateDump(@ei);
end;
...
end;
function GenerateDump(exceptionInfo: PExceptionPointers): Boolean;
var
miniEI: TMinidumpExceptionInformation;
begin
...
miniEI.ThreadID := GetCurrentThreadID();
miniEI.ExceptionPointers := exceptionInfo;
miniEI.ClientPointers := True;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFileHandle,
@miniEI, //PMinidumpExceptionInformation
nil,
nil);
end;
그런 기능이
가 ReadProcessMemory 또는 WriteProcessMemory의 요청일부만이
완료되었습니다0x8007021B
오류와 함께 실패를
약 SetUnhandledExceptionFilter
?
왜
SetUnhandledExceptionFilter
을 사용하고 필요한 포인터를 가져 오지 않습니까? 그와
SetUnhandledExceptionFilter(@DebugHelpExceptionFilter);
function DebugHelpExceptionFilter(const ExceptionInfo: TExceptionPointers): Longint; stdcall;
begin
GenerateDump(@ExceptionInfo);
Result := 1; //1 = EXCEPTION_EXECUTE_HANDLER
end;
문제는 필터링되지 예외 핸들러만을 제외하고는 필터링되지 않은 경우에 차기이다. 이 델파이이고, 나는 예외 처리 때문에 때문에 때문에 :
procedure DataModule1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
var
ei: TExceptionPointers;
begin
if (E is EExternal) then
begin
//If it's EXCEPTION_IN_PAGE_ERROR then we have to terminate *now*
if EExternal(E).ExceptionRecord.ExceptionCode = EXCEPTION_IN_PAGE_ERROR then
begin
ExitProcess(1);
Exit;
end;
//Write minidump
...
end;
{$IFDEF SaveExceptionsToDatabase}
SaveExceptionToDatabase(Sender, E);
{$ENDIF}
{$IFDEF ShowExceptionForm}
ShowExceptionForm(Sender, E);
{$ENDIF}
end;
응용 프로그램 은하지 않습니다을,도 내가 그것을하는 WER 오류로 종료 싶어.
은 EExternal
중에 어떻게 받습니까?
참고 : 모두 배경을에서 무시할 수 있습니다. 나를 더 똑똑하게 보이도록 불필요하게 필러로 설계되었습니다.
선제 snarky 헤퍼 넌 코멘트 : 당신은
보너스 독서
- MSDN: Crash Dump Analysis (Windows) (
MiniDumpWriteDump
를 호출하는 방법에 대한 자세한 예) - CodeProject: Post-Mortem Debugging Your Application with Minidumps and Visual Studio .NET (델파이 5를 사용하여 일반을 중지해야 개념, 미덕 및 미니 덤프 생성 및 사용 방법에 대해 이야기하십시오.)
- Stackoverflow: How to create minidump for my process when it crashes? (미니 덤프의 세계에 처음 소개)
- Stackoverflow: Can one prevent Microsoft Error Reporting for a single app? 직접 컨텍스트 포인터를 노출하지 않습니다 델파이 RTL 이후
후 선제 헤퍼 넌 코멘트 : 염두에두고
, 여기가 델파이 2007에 대해 수행 할 수있는 방법의 예 나는 그것이 이후 버전에서 어떤 쉽게 의심. 그리고 x64에 대해 걱정할 필요가 없습니다. –FWIW madExcept를 사용하면 컨텍스트 레코드 –
에 쉽게 액세스 할 수 있습니다. madExcept는 다소 사악한 방법으로 컨텍스트를 유지합니다. ExceptObjProc를 후크합니다. 꽤 까다로웠다. 후킹 프로세스는 파스칼 함수를 호출하기 전에 일부 레지스터를 읽어야하기 때문에. 아마도 ME를 템플릿으로 사용하는 방법을 알아낼 수 있습니다. 그러나 그것은 오래 걸릴 것입니다. 개인적으로, 나는 저를 사용하고 있습니다. 일단 당신이 나에게 당신은 더 이상 미니 덤프가 필요 없다고 생각합니다. ME 진단 프로그램은 사용하기가 더 쉬울 것입니다. –