1eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Copyright (c) 2008, Google Inc.
2eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// All rights reserved.
3eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
4eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Redistribution and use in source and binary forms, with or without
5eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// modification, are permitted provided that the following conditions are
6eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// met:
7eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
8eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//     * Redistributions of source code must retain the above copyright
9eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// notice, this list of conditions and the following disclaimer.
10eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//     * Redistributions in binary form must reproduce the above
11eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// copyright notice, this list of conditions and the following disclaimer
12eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// in the documentation and/or other materials provided with the
13eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// distribution.
14eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//     * Neither the name of Google Inc. nor the names of its
15eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// contributors may be used to endorse or promote products derived from
16eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// this software without specific prior written permission.
17eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
18eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
308cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com#ifndef CLIENT_WINDOWS_CRASH_GENERATION_MINIDUMP_GENERATOR_H_
318cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com#define CLIENT_WINDOWS_CRASH_GENERATION_MINIDUMP_GENERATOR_H_
32eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
33eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai#include <windows.h>
34eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai#include <dbghelp.h>
356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com#include <rpc.h>
36eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai#include <list>
37de9fe36b16a45972571b9d650633fe5cb156b536ted.mielczarek@gmail.com#include <string>
38eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai#include "google_breakpad/common/minidump_format.h"
39eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
40eeca9921c563d802cccc5593bf55dcb7683e7250mmentovainamespace google_breakpad {
41eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
42eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Abstraction for various objects and operations needed to generate
43eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// minidump on Windows. This abstraction is useful to hide all the gory
44eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// details for minidump generation and provide a clean interface to
45eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// the clients to generate minidumps.
46eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiclass MinidumpGenerator {
47eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai public:
48f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Creates an instance with the given parameters.
49f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // is_client_pointers specifies whether the exception_pointers and
50f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // assert_info point into the process that is being dumped.
51f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Before calling WriteMinidump on the returned instance a dump file muct be
52f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // specified by a call to either SetDumpFile() or GenerateDumpFile().
53f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // If a full dump file will be requested via a subsequent call to either
54f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // SetFullDumpFile or GenerateFullDumpFile() dump_type must include
55f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // MiniDumpWithFullMemory.
56f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  MinidumpGenerator(const std::wstring& dump_path,
57f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org                    const HANDLE process_handle,
58f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org                    const DWORD process_id,
59f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org                    const DWORD thread_id,
60f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org                    const DWORD requesting_thread_id,
61f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org                    EXCEPTION_POINTERS* exception_pointers,
62f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org                    MDRawAssertionInfo* assert_info,
63f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org                    const MINIDUMP_TYPE dump_type,
64f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org                    const bool is_client_pointers);
65eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
66eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  ~MinidumpGenerator();
67eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
68f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  void SetDumpFile(const HANDLE dump_file) { dump_file_ = dump_file; }
69f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  void SetFullDumpFile(const HANDLE full_dump_file) {
70f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org    full_dump_file_ = full_dump_file;
71f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  }
72f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
73f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Generate the name for the dump file that will be written to once
74f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // WriteMinidump() is called. Can only be called once and cannot be called
75f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // if the dump file is set via SetDumpFile().
76f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  bool GenerateDumpFile(std::wstring* dump_path);
77f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
78f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Generate the name for the full dump file that will be written to once
79f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // WriteMinidump() is called. Cannot be called unless the minidump type
80f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // includes MiniDumpWithFullMemory. Can only be called once and cannot be
81f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // called if the dump file is set via SetFullDumpFile().
82f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  bool GenerateFullDumpFile(std::wstring* full_dump_path);
83f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
84f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  void SetAdditionalStreams(
85f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org      MINIDUMP_USER_STREAM_INFORMATION* additional_streams) {
86f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org    additional_streams_ = additional_streams;
87f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  }
88f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
89f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  void SetCallback(MINIDUMP_CALLBACK_INFORMATION* callback_info) {
90f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org    callback_info_ = callback_info;
91f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  }
92f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
939033edcd7bab5a25c748dd1979f51853bbe06f87doshimun  // Writes the minidump with the given parameters. Stores the
949033edcd7bab5a25c748dd1979f51853bbe06f87doshimun  // dump file path in the dump_path parameter if dump generation
959033edcd7bab5a25c748dd1979f51853bbe06f87doshimun  // succeeds.
96f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  bool WriteMinidump();
973bf449febe7042c1a93f262f32fa25bf310f1e66cdn@chromium.org
98eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai private:
99eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Function pointer type for MiniDumpWriteDump, which is looked up
100eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // dynamically.
101eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  typedef BOOL (WINAPI* MiniDumpWriteDumpType)(
102eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      HANDLE hProcess,
103eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      DWORD ProcessId,
104eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      HANDLE hFile,
105eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      MINIDUMP_TYPE DumpType,
106eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
107eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
108eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
109eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
110eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Function pointer type for UuidCreate, which is looked up dynamically.
111eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  typedef RPC_STATUS (RPC_ENTRY* UuidCreateType)(UUID* Uuid);
112eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
113eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Loads the appropriate DLL lazily in a thread safe way.
114eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  HMODULE GetDbghelpModule();
115eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
116eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Loads the appropriate DLL and gets a pointer to the MiniDumpWriteDump
117eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // function lazily and in a thread-safe manner.
118eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  MiniDumpWriteDumpType GetWriteDump();
119eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
120eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Loads the appropriate DLL lazily in a thread safe way.
121eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  HMODULE GetRpcrt4Module();
122eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
123eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Loads the appropriate DLL and gets a pointer to the UuidCreate
124eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // function lazily and in a thread-safe manner.
125eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  UuidCreateType GetCreateUuid();
126eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
127eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Returns the path for the file to write dump to.
128eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  bool GenerateDumpFilePath(std::wstring* file_path);
129eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
130eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Handle to dynamically loaded DbgHelp.dll.
131eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  HMODULE dbghelp_module_;
132eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
133eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Pointer to the MiniDumpWriteDump function.
134eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  MiniDumpWriteDumpType write_dump_;
135eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
136eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Handle to dynamically loaded rpcrt4.dll.
137eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  HMODULE rpcrt4_module_;
138eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
139eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Pointer to the UuidCreate function.
140eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  UuidCreateType create_uuid_;
141eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
142f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Handle for the process to dump.
143f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  HANDLE process_handle_;
144f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
145f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Process ID for the process to dump.
146f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  DWORD process_id_;
147f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
148f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // The crashing thread ID.
149f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  DWORD thread_id_;
150f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
151f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // The thread ID which is requesting the dump.
152f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  DWORD requesting_thread_id_;
153f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
154f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Pointer to the exception information for the crash. This may point to an
155f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // address in the crashing process so it should not be dereferenced.
156f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  EXCEPTION_POINTERS* exception_pointers_;
157f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
158f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Assertion info for the report.
159f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  MDRawAssertionInfo* assert_info_;
160f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
161f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Type of minidump to generate.
162f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  MINIDUMP_TYPE dump_type_;
163f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
164f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Specifies whether the exception_pointers_ reference memory in the crashing
165f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // process.
166f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  bool is_client_pointers_;
167f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
168eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Folder path to store dump files.
169eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  std::wstring dump_path_;
170eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
171f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // The file where the dump will be written.
172f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  HANDLE dump_file_;
173f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
174f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // The file where the full dump will be written.
175f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  HANDLE full_dump_file_;
176f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
177f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Tracks whether the dump file handle is managed externally.
178f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  bool dump_file_is_internal_;
179f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
180f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Tracks whether the full dump file handle is managed externally.
181f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  bool full_dump_file_is_internal_;
182f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
183f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // Additional streams to be written to the dump.
184f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  MINIDUMP_USER_STREAM_INFORMATION* additional_streams_;
185f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
186f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  // The user defined callback for the various stages of the dump process.
187f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org  MINIDUMP_CALLBACK_INFORMATION* callback_info_;
188f1cb1b4882b1b6111b922902ea7cf19730777bd0cdn@chromium.org
189eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Critical section to sychronize action of loading modules dynamically.
190eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  CRITICAL_SECTION module_load_sync_;
191eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
192eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Critical section to synchronize action of dynamically getting function
193eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // addresses from modules.
194eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  CRITICAL_SECTION get_proc_address_sync_;
195eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai};
196eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
197eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}  // namespace google_breakpad
198eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
1998cf0a52becf937650056dad55769a2d85d30f75dhansl@google.com#endif  // CLIENT_WINDOWS_CRASH_GENERATION_MINIDUMP_GENERATOR_H_
200