Fix HandleInvalidParameter/HandlePureVirtualCall to dynamically lookup the RtlCaptureContext symbol so the Windows exception handler will continue to work on Windows 2000. Patch by Jim Mathies <jmathies@mozilla.com> and Timothy Nikkel <tnikkel@gmail.com>. r=ted
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@637 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
		@@ -37,6 +37,8 @@
 | 
			
		||||
#include "client/windows/handler/exception_handler.h"
 | 
			
		||||
#include "common/windows/guid_string.h"
 | 
			
		||||
 | 
			
		||||
typedef VOID (WINAPI *RtlCaptureContextPtr) (PCONTEXT pContextRecord);
 | 
			
		||||
 | 
			
		||||
namespace google_breakpad {
 | 
			
		||||
 | 
			
		||||
static const int kWaitForHandlerThreadMs = 60000;
 | 
			
		||||
@@ -486,18 +488,28 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
 | 
			
		||||
  EXCEPTION_RECORD exception_record = {};
 | 
			
		||||
  CONTEXT exception_context = {};
 | 
			
		||||
  EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
 | 
			
		||||
  RtlCaptureContext(&exception_context);
 | 
			
		||||
  exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
  // We store pointers to the the expression and function strings,
 | 
			
		||||
  // and the line as exception parameters to make them easy to
 | 
			
		||||
  // access by the developer on the far side.
 | 
			
		||||
  exception_record.NumberParameters = 3;
 | 
			
		||||
  exception_record.ExceptionInformation[0] =
 | 
			
		||||
      reinterpret_cast<ULONG_PTR>(&assertion.expression);
 | 
			
		||||
  exception_record.ExceptionInformation[1] =
 | 
			
		||||
      reinterpret_cast<ULONG_PTR>(&assertion.file);
 | 
			
		||||
  exception_record.ExceptionInformation[2] = assertion.line;
 | 
			
		||||
  EXCEPTION_POINTERS* exinfo = NULL;
 | 
			
		||||
 | 
			
		||||
  RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr)
 | 
			
		||||
    GetProcAddress(GetModuleHandleW(L"kernel32"), "RtlCaptureContext");
 | 
			
		||||
  if (fnRtlCaptureContext) {
 | 
			
		||||
    fnRtlCaptureContext(&exception_context);
 | 
			
		||||
 | 
			
		||||
    exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
    // We store pointers to the the expression and function strings,
 | 
			
		||||
    // and the line as exception parameters to make them easy to
 | 
			
		||||
    // access by the developer on the far side.
 | 
			
		||||
    exception_record.NumberParameters = 3;
 | 
			
		||||
    exception_record.ExceptionInformation[0] =
 | 
			
		||||
        reinterpret_cast<ULONG_PTR>(&assertion.expression);
 | 
			
		||||
    exception_record.ExceptionInformation[1] =
 | 
			
		||||
        reinterpret_cast<ULONG_PTR>(&assertion.file);
 | 
			
		||||
    exception_record.ExceptionInformation[2] = assertion.line;
 | 
			
		||||
 | 
			
		||||
    exinfo = &exception_ptrs;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool success = false;
 | 
			
		||||
  // In case of out-of-process dump generation, directly call
 | 
			
		||||
@@ -505,10 +517,10 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
 | 
			
		||||
  if (current_handler->IsOutOfProcess()) {
 | 
			
		||||
    success = current_handler->WriteMinidumpWithException(
 | 
			
		||||
        GetCurrentThreadId(),
 | 
			
		||||
        &exception_ptrs,
 | 
			
		||||
        exinfo,
 | 
			
		||||
        &assertion);
 | 
			
		||||
  } else {
 | 
			
		||||
    success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
 | 
			
		||||
    success = current_handler->WriteMinidumpOnHandlerThread(exinfo,
 | 
			
		||||
                                                            &assertion);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -564,18 +576,28 @@ void ExceptionHandler::HandlePureVirtualCall() {
 | 
			
		||||
  EXCEPTION_RECORD exception_record = {};
 | 
			
		||||
  CONTEXT exception_context = {};
 | 
			
		||||
  EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
 | 
			
		||||
  RtlCaptureContext(&exception_context);
 | 
			
		||||
  exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
  // We store pointers to the the expression and function strings,
 | 
			
		||||
  // and the line as exception parameters to make them easy to
 | 
			
		||||
  // access by the developer on the far side.
 | 
			
		||||
  exception_record.NumberParameters = 3;
 | 
			
		||||
  exception_record.ExceptionInformation[0] =
 | 
			
		||||
      reinterpret_cast<ULONG_PTR>(&assertion.expression);
 | 
			
		||||
  exception_record.ExceptionInformation[1] =
 | 
			
		||||
      reinterpret_cast<ULONG_PTR>(&assertion.file);
 | 
			
		||||
  exception_record.ExceptionInformation[2] = assertion.line;
 | 
			
		||||
  EXCEPTION_POINTERS* exinfo = NULL;
 | 
			
		||||
 | 
			
		||||
  RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr)
 | 
			
		||||
    GetProcAddress(GetModuleHandleW(L"kernel32"), "RtlCaptureContext");
 | 
			
		||||
  if (fnRtlCaptureContext) {
 | 
			
		||||
    fnRtlCaptureContext(&exception_context);
 | 
			
		||||
 | 
			
		||||
    exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
    // We store pointers to the the expression and function strings,
 | 
			
		||||
    // and the line as exception parameters to make them easy to
 | 
			
		||||
    // access by the developer on the far side.
 | 
			
		||||
    exception_record.NumberParameters = 3;
 | 
			
		||||
    exception_record.ExceptionInformation[0] =
 | 
			
		||||
        reinterpret_cast<ULONG_PTR>(&assertion.expression);
 | 
			
		||||
    exception_record.ExceptionInformation[1] =
 | 
			
		||||
        reinterpret_cast<ULONG_PTR>(&assertion.file);
 | 
			
		||||
    exception_record.ExceptionInformation[2] = assertion.line;
 | 
			
		||||
 | 
			
		||||
    exinfo = &exception_ptrs;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool success = false;
 | 
			
		||||
  // In case of out-of-process dump generation, directly call
 | 
			
		||||
@@ -584,10 +606,10 @@ void ExceptionHandler::HandlePureVirtualCall() {
 | 
			
		||||
  if (current_handler->IsOutOfProcess()) {
 | 
			
		||||
    success = current_handler->WriteMinidumpWithException(
 | 
			
		||||
        GetCurrentThreadId(),
 | 
			
		||||
        &exception_ptrs,
 | 
			
		||||
        exinfo,
 | 
			
		||||
        &assertion);
 | 
			
		||||
  } else {
 | 
			
		||||
    success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
 | 
			
		||||
    success = current_handler->WriteMinidumpOnHandlerThread(exinfo,
 | 
			
		||||
                                                            &assertion);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user