윈도우 플랫폼 컴파일러 사용 구글 breakpad

원본 : https://blog.csdn.net/bingzhongdehuoyan/article/details/53860433

간략한 소개

  breakpad은 사고보고 시스템을 구현하는 데 사용되는 클라이언트 및 서버 구성 요소의 집합입니다,하지만 난 단지 파일 만 업로드 충돌, 사물의 서비스 측면을 제공하는 것 같지 않았어요 클라이언트 및 온라인 공식 구글, 구글 공식에서 사용을 찾을 수 있습니다 방법 (소스 코드의 src \ 도구에 설명 된대로 윈도우 \ symupload 폴더 \).

  신맛 breakpad https://chromium.googlesource.com/breakpad/breakpad을 . 또한 어떻게 자신의 바이두에 벽을 통해 벽을 통해 소스 코드를 다운로드 할 필요가 자식을 사용하여, 벽을 통해 액세스 할 수 있어야합니다.

  또한 자신을 적용 윈도우 10 및 Visual Studio 2015, Win7에 환경과 VS2013에 대한 본 연구 환경은 Win7에와 VS2013 환경 때 회사입니다. (주 : 이하, 명령 $의 자식 번호는 명령 프롬프트, 명령 줄에 입력하지 않고 bash는 자식을 참조하십시오.)

프로젝트 파일을 생성 breakpad 1 개 패키지

1.1 소스 가져 오기 breakpad

breakpad 소스 수 https://chromium.googlesource.com/breakpad/breakpad 에 직접 설치 윈도우 자식에서, 자식과 다운로드 추천 다운로드 하는 자식 공식 웹 사이트 를 다운로드하고 다음 명령을 breakpad 소스를 얻기 위해 설치 :

$ git clone https://chromium.googlesource.com/breakpad/breakpad

  
  
  • 1

벽에 대한 이유는, 클론이 breakpad 소스를 다운로드하려면 다음 링크에서 사용할 수없는 벽을 통해 자신의 바이두 그것에 실패 할 수 있습니다
http://download.csdn.net/detail/bingzhongdehuoyan/9716434
breakpad 소스 폴더는 breakpad입니다 .

1.2 속이다 수집 도구

GYP (프로젝트 생성) 크롬은 크로스 플랫폼 자동화 프로젝트 빌드 도구들로 구성된 팀에 의해 개발 된, 크롬 프로젝트는 GYP 빌드 관리에 의해 수행된다.
사기꾼 도구 https://chromium.googlesource.com/external/gyp/ , 자식에 의해 인수 제안을 사용할 수 :

$ git clone https://chromium.googlesource.com/external/gyp

  
  
  • 1

: 또한 우리는 벽은 다음 링크에서 다운로드 할 수없는 이상, 벽을 통해 필요
http://download.csdn.net/detail/bingzhongdehuoyan/9720517
\ SRC \ 도구 \ 폴더를 breakpad을 획득 활력 폴더.

1.3 python2.7를 설치

breakpad 파이썬을 지원 잡을 필요 활력와 함께 제공하면, 파이썬이있을 수 있습니다 공식 웹 사이트의 다운로드를 직접 설치하고 구체적으로 자신의 바이두에 경로를 추가했지만, python3.x을 설치 그렇지 않으면 다음과 같은 오류 할 수 없습니다

설치에만 설치 될 수 있습니다 python2.7.x 최신 2.7.13.

1.4 획득 된 googletest

또한 googletest을 받아야합니다, 그렇지 않으면 다음과 같은 경고가 나타납니다 :

GitHub의 (에 GoogleTest 사용할 수 https://github.com/google/googletest ), 다음과 같이 :

$ git clone https://github.com/google/googletest.git

  
  
  • 1

아래 그림과 같이 두 개의 폴더, googlemock 및 googletest이됩니다 googletest 폴더로 내려 것 :

의 \ SRC \ 디렉토리 breakpad에 googlemock 폴더 중 하나가 될 것입니다 및 테스트의 이름을 변경 한 후 googletest 파일을 인수 폴더 아래 googletest 폴더 \ SRC \ 테스트 \ 폴더를 breakpad하고 gtest의 이름을 변경합니다.

활력과 프로젝트 파일의 1.5 건설

오픈 breakpad의 \의 SRC 폴더의 명령 창에서 두 가지 방법이 있습니다 : 하나의 오픈 런 승리 + R입니다, 명령 줄 입력을 열고 breakpad의 \ SRC 카탈로그의 cd 명령을 입력 cmd 만든 두 번째는 breakpad \의 src 폴더에있다 Shift + 마우스 오른쪽 버튼, 여기에 공개 명령 창을 클릭합니다. 그런 다음 명령 창에 다음 명령을 입력합니다 :

tools\gyp\gyp.bat --no-circular-check client\windows\breakpad_client.gyp

  
  
  • 1


프로젝트의 성공은 \ 디렉토리 breakpad의 \의 src \ 클라이언트 \ 창에 breakpad_client.sln 파일을 생성 한 후.

2 breakpad를 사용하여 샘플 프로그램을 제공

breakpad가 내장 된 샘플 프로그램은 breakpad 기어의이 예제 프로그램을 사용하여 간단하게 다음과 같은 방법 충돌 보고서를 느낄 수 있습니다.
비주얼 스튜디오 breakpad 열기 \ SRC \ 솔루션 탐색기 그림을 열고, 클라이언트 \ 윈도우 \ 디렉토리 아래에 작동 breakpad_client.sln :

: 오른쪽 build_all 프로젝트는 VS2015 다음과 같은 오류가 나타납니다 생성을 클릭

경고를 고려해야 무엇 오류로,이 솔루션은 다음과 같습니다 바로 프로젝트 이름 (예 : crash_generation_client 등)와 같은 옵션이 없음 선택되어 "오류와 같은 경고"의 오른쪽에, 일반을 클릭 한 C / C ++를 확장 속성을 엽니 다 :

작업 다른 build_all 프로젝트를 설정 각 속성은 C 프로젝트 / C ++ 탭을 클릭 한 다음 마우스 오른쪽 build_all 프로젝트를 가지고 외부 다시 클릭하거나 Win7에를, 실패 Win10 및 VS2015의 일이 정말 내가 사용하고 VS2013 너무 많은 일을했을 때, 다음과 같은 오류 메시지가 :

오류를 두 번 클릭 오류 라인을 위치 후 :

거친 행 오류는 삭제 :

다시 한번 잘 build_all 프로젝트를 클릭 재 구축, 그리고 마지막으로, 쉬운 일이 아니다 성공 :

성공이 breakpad 것입니다 후 \ SRC \ \ 클라이언트 \ 창 디버그 \의 폴더 프로그램이 crash_generation_app.exe 열려면 더블 클릭, 클라이언트 -> DEREF 제로를 클릭, 프로그램은 C 모양의 루트 디렉토리에, 후자의 붕괴를 축소한다 크래시 덤프 파일 a9414977-693d - 4013-89c1-9c7c4ef81689.dmp 비슷한 이름을 가지고 있으며, VS에서 파일을 열어 폴더가 덤프 여부 :

오류 메시지를 볼 수 있습니다, 당신이 할 수있는, 디버깅은이 기계를 사용 클릭 자세한 내용은 코드의 특정 라인에서 발생한 오류 및 오류를 참조하십시오

프로그램 코드의주의 깊은 연구는, 당신은 아마 breakpad는 C ++ 프로그램 충돌 보고서를 잡아 사용하는 방법을 이해할 수있다.

3 물을 시도하는 작은 프로그램을 작성

下面就写个简单的小程序试试用breakpad抓取崩溃报告。
用VS 2015新建一个Visual C++控制台程序,本文程序起名为wincrash。
然后在VS的wincrash解决方案中添加common、crash_generation_client、crash_generation_server、exception_handler等四个项目,右键解决方案->添加->现有项目,选中breakpad\src\client\windows\目录中和crash_generation、handler子目录中扩展名为.vcxproj的文件即可:


然后在wincrash项目中添加包含目录breakpad\src目录的全路径,本人的路径是D:\breakpad\src,添加方法是:右键wincrash->属性->VC++目录->包含目录->编辑:


之后分别右键common、crash_generation_client、crash_generation_server、exception_handler等四个项目点击生成,以编译出lib库文件:

在wincrash项目中包含生成的四个.lib库文件:右键wincrash->属性->链接器->输入->附加依赖项->编辑:

在附加依赖项编辑框中输入:

..\Debug\lib\common.lib
..\Debug\lib\crash_generation_client.lib
..\Debug\lib\crash_generation_server.lib
..\Debug\lib\exception_handler.lib

  
  
  • 1
  • 2
  • 3
  • 4


wincrash主程序代码如下:

#include <cstdio>
#include "client/windows/handler/exception_handler.h"

bool callback(const wchar_t *dump_path, const wchar_t *id,
    void *context, EXCEPTION_POINTERS *exinfo,
    MDRawAssertionInfo *assertion,
    bool succeeded)
{
    if (succeeded) {
        printf("dump guid is %ws\n", id);
    }
    else {
        printf("dump failed\n");
    }
    system("pause");
    return succeeded;
}

int mydiv(int x, int y)
{
    int z;
    z = x / y;
    return z;
}

int main()
{
    google_breakpad::ExceptionHandler eh(
        L".", NULL, callback, NULL,
        google_breakpad::ExceptionHandler::HANDLER_ALL);
    printf("9/3=%d\n", mydiv(9, 3));
    printf("9/0=%d\n", mydiv(9, 0));  //程序将在此崩溃
    printf("8/2=%d\n", mydiv(8, 2));
    system("pause");
    return 0;
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

编译程序,可能会有如下错误:

原因是common、crash_generation_client、crash_generation_server、exception_handler等四个项目的代码生成运行库为“多线程调试 (/MTd)”,跟wincrash的不一样,将wincrash的改为“多线程调试 (/MTd)”即可:右键wincrash->属性->C/C++->代码生成->运行库->多线程调试 (/MTd),如图:

再次编译程序,这次应该能在Debug目录下成功生成wincrash.exe程序,双击打开运行:

成功抓取崩溃文件!!
在wincrash.exe程序所在目录下可看到生成的.dmp扩展名的崩溃转储文件(名称类似1a4ecf76-1df3-46de-be69-88df37bb1b11.dmp),用VS打开该文件:

可以看到错误信息,点击使用 仅限本机 进行调试,可以看到错误详情及错误具体发生在哪行代码:

准确定位26行和36行!!
下面简单解析一下这个小程序,使用breakpad抓取C++程序的崩溃报告,需要包含exception_handler.h头文件,并在程序所有错误之前创建一个google_breakpad::ExceptionHandler对象,建议在main()函数开头创建该对象,当程序出错时,该对象会捕捉到错误,输出dump文件,还可通过回调函数作一些必要的处理操作。
本程序所用google_breakpad::ExceptionHandler的其中一个构造函数定义如下(见exception_handler.h文件):

  // Creates a new ExceptionHandler instance to handle writing minidumps.
  // Before writing a minidump, the optional filter callback will be called.
  // Its return value determines whether or not Breakpad should write a
  // minidump.  Minidump files will be written to dump_path, and the optional
  // callback is called after writing the dump file, as described above.
  // handler_types specifies the types of handlers that should be installed.
  ExceptionHandler(const wstring& dump_path,
                   FilterCallback filter,
                   MinidumpCallback callback,
                   void* callback_context,
                   int handler_types);
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • const wstring& dump_path:宽字符串类型的dump_path用于定义.dmp扩展名的崩溃转储文件生成路径。
  • FilterCallback filter:程序崩溃时用于过滤的回调函数,通过返回ture/false来继续/停止 异常处理,其定义如下:
  // A callback function to run before Breakpad performs any substantial
  // processing of an exception.  A FilterCallback is called before writing
  // a minidump.  context is the parameter supplied by the user as
  // callback_context when the handler was created.  exinfo points to the
  // exception record, if any; assertion points to assertion information,
  // if any.
  //
  // If a FilterCallback returns true, Breakpad will continue processing,
  // attempting to write a minidump.  If a FilterCallback returns false,
  // Breakpad will immediately report the exception as unhandled without
  // writing a minidump, allowing another handler the opportunity to handle it.
  typedef bool (*FilterCallback)(void* context, EXCEPTION_POINTERS* exinfo,
                                 MDRawAssertionInfo* assertion);
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • MinidumpCallback callback:输出dump文件后的回调函数,可做一些必要的处理操作,不过不建议太复杂,毕竟程序崩溃后堆栈已被破坏,其定义如下:
  // A callback function to run after the minidump has been written.
  // minidump_id is a unique id for the dump, so the minidump
  // file is <dump_path>\<minidump_id>.dmp.  context is the parameter supplied
  // by the user as callback_context when the handler was created.  exinfo
  // points to the exception record, or NULL if no exception occurred.
  // succeeded indicates whether a minidump file was successfully written.
  // assertion points to information about an assertion if the handler was
  // invoked by an assertion.
  //
  // If an exception occurred and the callback returns true, Breakpad will treat
  // the exception as fully-handled, suppressing any other handlers from being
  // notified of the exception.  If the callback returns false, Breakpad will
  // treat the exception as unhandled, and allow another handler to handle it.
  // If there are no other handlers, Breakpad will report the exception to the
  // system as unhandled, allowing a debugger or native crash dialog the
  // opportunity to handle the exception.  Most callback implementations
  // should normally return the value of |succeeded|, or when they wish to
  // not report an exception of handled, false.  Callbacks will rarely want to
  // return true directly (unless |succeeded| is true).
  //
  // For out-of-process dump generation, dump path and minidump ID will always
  // be NULL. In case of out-of-process dump generation, the dump path and
  // minidump id are controlled by the server process and are not communicated
  // back to the crashing process.
  typedef bool (*MinidumpCallback)(const wchar_t* dump_path,
                                   const wchar_t* minidump_id,
                                   void* context,
                                   EXCEPTION_POINTERS* exinfo,
                                   MDRawAssertionInfo* assertion,
                                   bool succeeded);
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • void* callback_context:设备上下文,回调使用的。
  • int handler_types:HandlerType异常类型,可在exception_handler.h查看。

google_breakpad::ExceptionHandler的详细使用方法就自己参考官方文档或源码中的注释。

추천

출처blog.csdn.net/a844651990/article/details/85316627