minidump_processor_unittest.cc revision c5e242b8cd4280db5162e5a3084f2dc9e16e8ffb
17daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// Copyright (c) 2006, Google Inc.
27daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// All rights reserved.
3cce3492afc263be86236600d41dca40be7224ee7bryner//
47daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// Redistribution and use in source and binary forms, with or without
57daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// modification, are permitted provided that the following conditions are
67daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// met:
7cce3492afc263be86236600d41dca40be7224ee7bryner//
87daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai//     * Redistributions of source code must retain the above copyright
97daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// notice, this list of conditions and the following disclaimer.
107daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai//     * Redistributions in binary form must reproduce the above
117daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// copyright notice, this list of conditions and the following disclaimer
127daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// in the documentation and/or other materials provided with the
137daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// distribution.
147daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai//     * Neither the name of Google Inc. nor the names of its
157daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// contributors may be used to endorse or promote products derived from
167daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// this software without specific prior written permission.
17cce3492afc263be86236600d41dca40be7224ee7bryner//
187daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
197daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
207daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
217daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
227daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
237daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
247daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
257daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
267daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
277daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
287daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29cce3492afc263be86236600d41dca40be7224ee7bryner
30cce3492afc263be86236600d41dca40be7224ee7bryner// Unit test for MinidumpProcessor.  Uses a pre-generated minidump and
31cce3492afc263be86236600d41dca40be7224ee7bryner// corresponding symbol file, and checks the stack frames for correctness.
32cce3492afc263be86236600d41dca40be7224ee7bryner
33e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek#include <stdlib.h>
34e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek
35cce3492afc263be86236600d41dca40be7224ee7bryner#include <string>
362ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid#include <iostream>
372ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid#include <fstream>
3819374d263649a51c8bb56f2f01d3466905847670nealsid#include <map>
39a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com#include <utility>
40e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek
41b56cfa067add059d0894433393e798fe0604970enealsid#include "breakpad_googletest_includes.h"
422cc15ba4327831f917ff55b87e6d5fc3c7750085ted.mielczarek@gmail.com#include "common/scoped_ptr.h"
434e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h"
44e5dc60822e5938fea2ae892ccddb906641ba174emmentovai#include "google_breakpad/processor/basic_source_line_resolver.h"
45e5dc60822e5938fea2ae892ccddb906641ba174emmentovai#include "google_breakpad/processor/call_stack.h"
46e5dc60822e5938fea2ae892ccddb906641ba174emmentovai#include "google_breakpad/processor/code_module.h"
47e5dc60822e5938fea2ae892ccddb906641ba174emmentovai#include "google_breakpad/processor/code_modules.h"
48b56cfa067add059d0894433393e798fe0604970enealsid#include "google_breakpad/processor/minidump.h"
49e5dc60822e5938fea2ae892ccddb906641ba174emmentovai#include "google_breakpad/processor/minidump_processor.h"
50e5dc60822e5938fea2ae892ccddb906641ba174emmentovai#include "google_breakpad/processor/process_state.h"
51e5dc60822e5938fea2ae892ccddb906641ba174emmentovai#include "google_breakpad/processor/stack_frame.h"
52e5dc60822e5938fea2ae892ccddb906641ba174emmentovai#include "google_breakpad/processor/symbol_supplier.h"
5332b802dba3d49880a0414d066e71cdc20ab09901mmentovai#include "processor/logging.h"
54e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com#include "processor/stackwalker_unittest_utils.h"
55cce3492afc263be86236600d41dca40be7224ee7bryner
5619374d263649a51c8bb56f2f01d3466905847670nealsidusing std::map;
5719374d263649a51c8bb56f2f01d3466905847670nealsid
58b56cfa067add059d0894433393e798fe0604970enealsidnamespace google_breakpad {
59b56cfa067add059d0894433393e798fe0604970enealsidclass MockMinidump : public Minidump {
60b56cfa067add059d0894433393e798fe0604970enealsid public:
61b56cfa067add059d0894433393e798fe0604970enealsid  MockMinidump() : Minidump("") {
62b56cfa067add059d0894433393e798fe0604970enealsid  }
63b56cfa067add059d0894433393e798fe0604970enealsid
64cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org  MOCK_METHOD0(Read, bool());
65b56cfa067add059d0894433393e798fe0604970enealsid  MOCK_CONST_METHOD0(path, string());
66cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org  MOCK_CONST_METHOD0(header, const MDRawHeader*());
67cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org  MOCK_METHOD0(GetThreadList, MinidumpThreadList*());
68e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_METHOD0(GetSystemInfo, MinidumpSystemInfo*());
69e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_METHOD0(GetBreakpadInfo, MinidumpBreakpadInfo*());
70e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_METHOD0(GetException, MinidumpException*());
71e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_METHOD0(GetAssertion, MinidumpAssertion*());
72e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_METHOD0(GetModuleList, MinidumpModuleList*());
7302ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  MOCK_METHOD0(GetMemoryList, MinidumpMemoryList*());
74b56cfa067add059d0894433393e798fe0604970enealsid};
75e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
76e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comclass MockMinidumpThreadList : public MinidumpThreadList {
77e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com public:
78e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidumpThreadList() : MinidumpThreadList(NULL) {}
79e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
80e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_CONST_METHOD0(thread_count, unsigned int());
81e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_CONST_METHOD1(GetThreadAtIndex, MinidumpThread*(unsigned int));
82e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com};
83e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
8402ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.comclass MockMinidumpMemoryList : public MinidumpMemoryList {
8502ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com public:
8602ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  MockMinidumpMemoryList() : MinidumpMemoryList(NULL) {}
8702ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com
8802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  MOCK_METHOD1(GetMemoryRegionForAddress, MinidumpMemoryRegion*(uint64_t));
8902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com};
9002ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com
91e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comclass MockMinidumpThread : public MinidumpThread {
92e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com public:
93e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidumpThread() : MinidumpThread(NULL) {}
94e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
956162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  MOCK_CONST_METHOD1(GetThreadID, bool(uint32_t*));
96e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_METHOD0(GetContext, MinidumpContext*());
97e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MOCK_METHOD0(GetMemory, MinidumpMemoryRegion*());
9802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  MOCK_CONST_METHOD0(GetStartOfStackMemoryRange, uint64_t());
99e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com};
100e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
101e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com// This is crappy, but MinidumpProcessor really does want a
102e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com// MinidumpMemoryRegion.
103e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comclass MockMinidumpMemoryRegion : public MinidumpMemoryRegion {
104e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com public:
1056162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  MockMinidumpMemoryRegion(uint64_t base, const string& contents) :
106e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com      MinidumpMemoryRegion(NULL) {
107e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    region_.Init(base, contents);
108e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  }
109e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
1106162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  uint64_t GetBase() const { return region_.GetBase(); }
1116162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  uint32_t GetSize() const { return region_.GetSize(); }
112e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
1136162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  bool GetMemoryAtAddress(uint64_t address, uint8_t  *value) const {
114e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    return region_.GetMemoryAtAddress(address, value);
115e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  }
1166162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const {
117e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    return region_.GetMemoryAtAddress(address, value);
118e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  }
1196162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const {
120e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    return region_.GetMemoryAtAddress(address, value);
121e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  }
1226162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const {
123e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    return region_.GetMemoryAtAddress(address, value);
124e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  }
125e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
126e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMemoryRegion region_;
127e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com};
128e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
129e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com}  // namespace google_breakpad
130b56cfa067add059d0894433393e798fe0604970enealsid
1318647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovainamespace {
1328647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovai
133e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::BasicSourceLineResolver;
134e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::CallStack;
135e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::CodeModule;
136e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comusing google_breakpad::MinidumpContext;
137e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comusing google_breakpad::MinidumpMemoryRegion;
138e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::MinidumpProcessor;
139e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comusing google_breakpad::MinidumpSystemInfo;
140b56cfa067add059d0894433393e798fe0604970enealsidusing google_breakpad::MinidumpThreadList;
141b56cfa067add059d0894433393e798fe0604970enealsidusing google_breakpad::MinidumpThread;
142b56cfa067add059d0894433393e798fe0604970enealsidusing google_breakpad::MockMinidump;
14302ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.comusing google_breakpad::MockMinidumpMemoryList;
144e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comusing google_breakpad::MockMinidumpMemoryRegion;
145e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comusing google_breakpad::MockMinidumpThread;
146e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comusing google_breakpad::MockMinidumpThreadList;
147e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::ProcessState;
148e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::scoped_ptr;
149e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::SymbolSupplier;
150e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::SystemInfo;
15119374d263649a51c8bb56f2f01d3466905847670nealsidusing ::testing::_;
15284946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.comusing ::testing::AnyNumber;
153e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comusing ::testing::DoAll;
15419374d263649a51c8bb56f2f01d3466905847670nealsidusing ::testing::Mock;
15519374d263649a51c8bb56f2f01d3466905847670nealsidusing ::testing::Ne;
15619374d263649a51c8bb56f2f01d3466905847670nealsidusing ::testing::Property;
157b56cfa067add059d0894433393e798fe0604970enealsidusing ::testing::Return;
158e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comusing ::testing::SetArgumentPointee;
15997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai
16097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistatic const char *kSystemInfoOS = "Windows NT";
16197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistatic const char *kSystemInfoOSShort = "windows";
16297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistatic const char *kSystemInfoOSVersion = "5.1.2600 Service Pack 2";
16397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistatic const char *kSystemInfoCPU = "x86";
16497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistatic const char *kSystemInfoCPUInfo =
16597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai    "GenuineIntel family 6 model 13 stepping 8";
166cce3492afc263be86236600d41dca40be7224ee7bryner
16797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai#define ASSERT_TRUE_ABORT(cond) \
16897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  if (!(cond)) {                                                        \
16997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai    fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
17097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai    abort(); \
17197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  }
17297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai
17397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai#define ASSERT_EQ_ABORT(e1, e2) ASSERT_TRUE_ABORT((e1) == (e2))
17497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai
175cce3492afc263be86236600d41dca40be7224ee7brynerclass TestSymbolSupplier : public SymbolSupplier {
176cce3492afc263be86236600d41dca40be7224ee7bryner public:
177f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  TestSymbolSupplier() : interrupt_(false) {}
178f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner
179f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  virtual SymbolResult GetSymbolFile(const CodeModule *module,
18097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai                                     const SystemInfo *system_info,
181f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner                                     string *symbol_file);
182f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner
1832ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid  virtual SymbolResult GetSymbolFile(const CodeModule *module,
1842ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid                                     const SystemInfo *system_info,
1852ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid                                     string *symbol_file,
1862ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid                                     string *symbol_data);
1872ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid
1885b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  virtual SymbolResult GetCStringSymbolData(const CodeModule *module,
1895b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com                                            const SystemInfo *system_info,
1905b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com                                            string *symbol_file,
1912d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com                                            char **symbol_data,
1922d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com                                            size_t *symbol_data_size);
1935b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com
194a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com  virtual void FreeSymbolData(const CodeModule *module);
195a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com
196f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  // When set to true, causes the SymbolSupplier to return INTERRUPT
197f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  void set_interrupt(bool interrupt) { interrupt_ = interrupt; }
198f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner
199f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner private:
200f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  bool interrupt_;
201a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com  map<string, char *> memory_buffers_;
202cce3492afc263be86236600d41dca40be7224ee7bryner};
203cce3492afc263be86236600d41dca40be7224ee7bryner
204f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3brynerSymbolSupplier::SymbolResult TestSymbolSupplier::GetSymbolFile(
20597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai    const CodeModule *module,
20697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai    const SystemInfo *system_info,
20797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai    string *symbol_file) {
20897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_TRUE_ABORT(module);
20997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_TRUE_ABORT(system_info);
21097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ_ABORT(system_info->cpu, kSystemInfoCPU);
21197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ_ABORT(system_info->cpu_info, kSystemInfoCPUInfo);
21297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ_ABORT(system_info->os, kSystemInfoOS);
21397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ_ABORT(system_info->os_short, kSystemInfoOSShort);
21497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ_ABORT(system_info->os_version, kSystemInfoOSVersion);
21597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai
216f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  if (interrupt_) {
217f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner    return INTERRUPT;
218f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  }
219f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner
220e5dc60822e5938fea2ae892ccddb906641ba174emmentovai  if (module && module->code_file() == "c:\\test_app.exe") {
221f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner      *symbol_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
222f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner                     "/src/processor/testdata/symbols/test_app.pdb/" +
223f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner                     module->debug_identifier() +
224f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner                     "/test_app.sym";
225f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner    return FOUND;
226cce3492afc263be86236600d41dca40be7224ee7bryner  }
227cce3492afc263be86236600d41dca40be7224ee7bryner
228f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  return NOT_FOUND;
229cce3492afc263be86236600d41dca40be7224ee7bryner}
230cce3492afc263be86236600d41dca40be7224ee7bryner
2312ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsidSymbolSupplier::SymbolResult TestSymbolSupplier::GetSymbolFile(
2322ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid    const CodeModule *module,
2332ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid    const SystemInfo *system_info,
2342ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid    string *symbol_file,
2352ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid    string *symbol_data) {
2362ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid  SymbolSupplier::SymbolResult s = GetSymbolFile(module, system_info,
2372ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid                                                 symbol_file);
2382ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid  if (s == FOUND) {
2392ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid    std::ifstream in(symbol_file->c_str());
2404e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com    std::getline(in, *symbol_data, string::traits_type::to_char_type(
2414e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com                     string::traits_type::eof()));
2422ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid    in.close();
2432ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid  }
2442ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid
2452ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid  return s;
2462ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid}
2472ad976ef0ba44f36842b9b7a11848f6b40fd25d5nealsid
2485b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comSymbolSupplier::SymbolResult TestSymbolSupplier::GetCStringSymbolData(
2495b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com    const CodeModule *module,
2505b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com    const SystemInfo *system_info,
2515b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com    string *symbol_file,
2522d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com    char **symbol_data,
2532d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com    size_t *symbol_data_size) {
2545b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  string symbol_data_string;
2555b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  SymbolSupplier::SymbolResult s = GetSymbolFile(module,
2565b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com                                                 system_info,
2575b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com                                                 symbol_file,
2585b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com                                                 &symbol_data_string);
2595b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  if (s == FOUND) {
2602d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com    *symbol_data_size = symbol_data_string.size() + 1;
2612d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com    *symbol_data = new char[*symbol_data_size];
262a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com    if (*symbol_data == NULL) {
263a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com      BPLOG(ERROR) << "Memory allocation failed for module: "
2642d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com                   << module->code_file() << " size: " << *symbol_data_size;
265a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com      return INTERRUPT;
266a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com    }
2672d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com    memcpy(*symbol_data, symbol_data_string.c_str(), symbol_data_string.size());
2682d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com    (*symbol_data)[symbol_data_string.size()] = '\0';
269a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com    memory_buffers_.insert(make_pair(module->code_file(), *symbol_data));
2705b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  }
2715b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com
2725b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  return s;
2735b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com}
2745b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com
275a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.comvoid TestSymbolSupplier::FreeSymbolData(const CodeModule *module) {
276a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com  map<string, char *>::iterator it = memory_buffers_.find(module->code_file());
277a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com  if (it != memory_buffers_.end()) {
278a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com    delete [] it->second;
279a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com    memory_buffers_.erase(it);
280a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com  }
281a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com}
282a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com
283e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com// A test system info stream, just returns values from the
284e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com// MDRawSystemInfo fed to it.
285e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comclass TestMinidumpSystemInfo : public MinidumpSystemInfo {
28619374d263649a51c8bb56f2f01d3466905847670nealsid public:
28702ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  explicit TestMinidumpSystemInfo(MDRawSystemInfo info) :
288e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com      MinidumpSystemInfo(NULL) {
289e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    valid_ = true;
290e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    system_info_ = info;
291e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    csd_version_ = new string("");
292e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  }
293e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com};
294e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
295e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com// A test minidump context, just returns the MDRawContextX86
296e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com// fed to it.
297e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comclass TestMinidumpContext : public MinidumpContext {
29802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com public:
29902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  explicit TestMinidumpContext(const MDRawContextX86& context) :
30002ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com      MinidumpContext(NULL) {
301e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    valid_ = true;
302c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org    SetContextX86(new MDRawContextX86(context));
303c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org    SetContextFlags(MD_CONTEXT_X86);
304e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  }
30519374d263649a51c8bb56f2f01d3466905847670nealsid};
306b56cfa067add059d0894433393e798fe0604970enealsid
307b56cfa067add059d0894433393e798fe0604970enealsidclass MinidumpProcessorTest : public ::testing::Test {
308b56cfa067add059d0894433393e798fe0604970enealsid};
309b56cfa067add059d0894433393e798fe0604970enealsid
310b56cfa067add059d0894433393e798fe0604970enealsidTEST_F(MinidumpProcessorTest, TestCorruptMinidumps) {
311b56cfa067add059d0894433393e798fe0604970enealsid  MockMinidump dump;
312b56cfa067add059d0894433393e798fe0604970enealsid  TestSymbolSupplier supplier;
313b56cfa067add059d0894433393e798fe0604970enealsid  BasicSourceLineResolver resolver;
314b56cfa067add059d0894433393e798fe0604970enealsid  MinidumpProcessor processor(&supplier, &resolver);
315b56cfa067add059d0894433393e798fe0604970enealsid  ProcessState state;
316b56cfa067add059d0894433393e798fe0604970enealsid
3179fc581226040d32b6f0d6b171378d5ea0cdf8fb1jessicag.feedback@gmail.com  EXPECT_EQ(processor.Process("nonexistent minidump", &state),
318b56cfa067add059d0894433393e798fe0604970enealsid            google_breakpad::PROCESS_ERROR_MINIDUMP_NOT_FOUND);
319b56cfa067add059d0894433393e798fe0604970enealsid
320b56cfa067add059d0894433393e798fe0604970enealsid  EXPECT_CALL(dump, path()).WillRepeatedly(Return("mock minidump"));
321b56cfa067add059d0894433393e798fe0604970enealsid  EXPECT_CALL(dump, Read()).WillRepeatedly(Return(true));
322b56cfa067add059d0894433393e798fe0604970enealsid
323b56cfa067add059d0894433393e798fe0604970enealsid  MDRawHeader fakeHeader;
324b56cfa067add059d0894433393e798fe0604970enealsid  fakeHeader.time_date_stamp = 0;
32502ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  EXPECT_CALL(dump, header()).
32602ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com      WillOnce(Return(reinterpret_cast<MDRawHeader*>(NULL))).
327b56cfa067add059d0894433393e798fe0604970enealsid      WillRepeatedly(Return(&fakeHeader));
328e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
329b56cfa067add059d0894433393e798fe0604970enealsid  EXPECT_EQ(processor.Process(&dump, &state),
330b56cfa067add059d0894433393e798fe0604970enealsid            google_breakpad::PROCESS_ERROR_NO_MINIDUMP_HEADER);
331b56cfa067add059d0894433393e798fe0604970enealsid
332b56cfa067add059d0894433393e798fe0604970enealsid  EXPECT_CALL(dump, GetThreadList()).
33302ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com      WillOnce(Return(reinterpret_cast<MinidumpThreadList*>(NULL)));
334e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, GetSystemInfo()).
33502ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com      WillRepeatedly(Return(reinterpret_cast<MinidumpSystemInfo*>(NULL)));
336e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
337b56cfa067add059d0894433393e798fe0604970enealsid  EXPECT_EQ(processor.Process(&dump, &state),
338b56cfa067add059d0894433393e798fe0604970enealsid            google_breakpad::PROCESS_ERROR_NO_THREAD_LIST);
339b56cfa067add059d0894433393e798fe0604970enealsid}
340b56cfa067add059d0894433393e798fe0604970enealsid
34119374d263649a51c8bb56f2f01d3466905847670nealsid// This test case verifies that the symbol supplier is only consulted
34219374d263649a51c8bb56f2f01d3466905847670nealsid// once per minidump per module.
34319374d263649a51c8bb56f2f01d3466905847670nealsidTEST_F(MinidumpProcessorTest, TestSymbolSupplierLookupCounts) {
34419374d263649a51c8bb56f2f01d3466905847670nealsid  MockSymbolSupplier supplier;
34519374d263649a51c8bb56f2f01d3466905847670nealsid  BasicSourceLineResolver resolver;
34619374d263649a51c8bb56f2f01d3466905847670nealsid  MinidumpProcessor processor(&supplier, &resolver);
34719374d263649a51c8bb56f2f01d3466905847670nealsid
34819374d263649a51c8bb56f2f01d3466905847670nealsid  string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
34919374d263649a51c8bb56f2f01d3466905847670nealsid                         "/src/processor/testdata/minidump2.dmp";
35019374d263649a51c8bb56f2f01d3466905847670nealsid  ProcessState state;
3515b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  EXPECT_CALL(supplier, GetCStringSymbolData(
35219374d263649a51c8bb56f2f01d3466905847670nealsid      Property(&google_breakpad::CodeModule::code_file,
35319374d263649a51c8bb56f2f01d3466905847670nealsid               "c:\\test_app.exe"),
3542d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com      _, _, _, _)).WillOnce(Return(SymbolSupplier::NOT_FOUND));
3555b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  EXPECT_CALL(supplier, GetCStringSymbolData(
35619374d263649a51c8bb56f2f01d3466905847670nealsid      Property(&google_breakpad::CodeModule::code_file,
35719374d263649a51c8bb56f2f01d3466905847670nealsid               Ne("c:\\test_app.exe")),
3582d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com      _, _, _, _)).WillRepeatedly(Return(SymbolSupplier::NOT_FOUND));
35984946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com  // Avoid GMOCK WARNING "Uninteresting mock function call - returning
36084946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com  // directly" for FreeSymbolData().
36184946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com  EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber());
36219374d263649a51c8bb56f2f01d3466905847670nealsid  ASSERT_EQ(processor.Process(minidump_file, &state),
36319374d263649a51c8bb56f2f01d3466905847670nealsid            google_breakpad::PROCESS_OK);
36419374d263649a51c8bb56f2f01d3466905847670nealsid
36519374d263649a51c8bb56f2f01d3466905847670nealsid  ASSERT_TRUE(Mock::VerifyAndClearExpectations(&supplier));
36619374d263649a51c8bb56f2f01d3466905847670nealsid
36719374d263649a51c8bb56f2f01d3466905847670nealsid  // We need to verify that across minidumps, the processor will refetch
36819374d263649a51c8bb56f2f01d3466905847670nealsid  // symbol files, even with the same symbol supplier.
3695b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  EXPECT_CALL(supplier, GetCStringSymbolData(
37019374d263649a51c8bb56f2f01d3466905847670nealsid      Property(&google_breakpad::CodeModule::code_file,
37119374d263649a51c8bb56f2f01d3466905847670nealsid               "c:\\test_app.exe"),
3722d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com      _, _, _, _)).WillOnce(Return(SymbolSupplier::NOT_FOUND));
3735b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com  EXPECT_CALL(supplier, GetCStringSymbolData(
37419374d263649a51c8bb56f2f01d3466905847670nealsid      Property(&google_breakpad::CodeModule::code_file,
37519374d263649a51c8bb56f2f01d3466905847670nealsid               Ne("c:\\test_app.exe")),
3762d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com      _, _, _, _)).WillRepeatedly(Return(SymbolSupplier::NOT_FOUND));
37784946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com  // Avoid GMOCK WARNING "Uninteresting mock function call - returning
37884946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com  // directly" for FreeSymbolData().
37984946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com  EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber());
38019374d263649a51c8bb56f2f01d3466905847670nealsid  ASSERT_EQ(processor.Process(minidump_file, &state),
38119374d263649a51c8bb56f2f01d3466905847670nealsid            google_breakpad::PROCESS_OK);
38219374d263649a51c8bb56f2f01d3466905847670nealsid}
38319374d263649a51c8bb56f2f01d3466905847670nealsid
384b56cfa067add059d0894433393e798fe0604970enealsidTEST_F(MinidumpProcessorTest, TestBasicProcessing) {
385cce3492afc263be86236600d41dca40be7224ee7bryner  TestSymbolSupplier supplier;
386fd38d48e6d5e56cb66b0fa0f7e25f840a83dac5cbryner  BasicSourceLineResolver resolver;
387fd38d48e6d5e56cb66b0fa0f7e25f840a83dac5cbryner  MinidumpProcessor processor(&supplier, &resolver);
388cce3492afc263be86236600d41dca40be7224ee7bryner
389cce3492afc263be86236600d41dca40be7224ee7bryner  string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
390cce3492afc263be86236600d41dca40be7224ee7bryner                         "/src/processor/testdata/minidump2.dmp";
391cce3492afc263be86236600d41dca40be7224ee7bryner
392f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ProcessState state;
393f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_EQ(processor.Process(minidump_file, &state),
394b56cfa067add059d0894433393e798fe0604970enealsid            google_breakpad::PROCESS_OK);
39597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ(state.system_info()->os, kSystemInfoOS);
39697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ(state.system_info()->os_short, kSystemInfoOSShort);
39797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ(state.system_info()->os_version, kSystemInfoOSVersion);
39897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ(state.system_info()->cpu, kSystemInfoCPU);
39997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ(state.system_info()->cpu_info, kSystemInfoCPUInfo);
400f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_TRUE(state.crashed());
401e4cc9b12ec2aaef10e60f50e7f55ee3881369bd6nealsid  ASSERT_EQ(state.crash_reason(), "EXCEPTION_ACCESS_VIOLATION_WRITE");
4025ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy  ASSERT_EQ(state.crash_address(), 0x45U);
4035ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy  ASSERT_EQ(state.threads()->size(), size_t(1));
404f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_EQ(state.requesting_thread(), 0);
405f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner
406f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  CallStack *stack = state.threads()->at(0);
407e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_TRUE(stack);
4085ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy  ASSERT_EQ(stack->frames()->size(), 4U);
409cce3492afc263be86236600d41dca40be7224ee7bryner
410db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai  ASSERT_TRUE(stack->frames()->at(0)->module);
4115ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy  ASSERT_EQ(stack->frames()->at(0)->module->base_address(), 0x400000U);
412e5dc60822e5938fea2ae892ccddb906641ba174emmentovai  ASSERT_EQ(stack->frames()->at(0)->module->code_file(), "c:\\test_app.exe");
41397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai  ASSERT_EQ(stack->frames()->at(0)->function_name,
41497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai            "`anonymous namespace'::CrashFunction");
415d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(0)->source_file_name, "c:\\test_app.cc");
416e5dc60822e5938fea2ae892ccddb906641ba174emmentovai  ASSERT_EQ(stack->frames()->at(0)->source_line, 58);
417cce3492afc263be86236600d41dca40be7224ee7bryner
418db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai  ASSERT_TRUE(stack->frames()->at(1)->module);
4195ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy  ASSERT_EQ(stack->frames()->at(1)->module->base_address(), 0x400000U);
420e5dc60822e5938fea2ae892ccddb906641ba174emmentovai  ASSERT_EQ(stack->frames()->at(1)->module->code_file(), "c:\\test_app.exe");
421d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(1)->function_name, "main");
422d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(1)->source_file_name, "c:\\test_app.cc");
423e5dc60822e5938fea2ae892ccddb906641ba174emmentovai  ASSERT_EQ(stack->frames()->at(1)->source_line, 65);
424cce3492afc263be86236600d41dca40be7224ee7bryner
425cce3492afc263be86236600d41dca40be7224ee7bryner  // This comes from the CRT
426db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai  ASSERT_TRUE(stack->frames()->at(2)->module);
4275ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy  ASSERT_EQ(stack->frames()->at(2)->module->base_address(), 0x400000U);
428e5dc60822e5938fea2ae892ccddb906641ba174emmentovai  ASSERT_EQ(stack->frames()->at(2)->module->code_file(), "c:\\test_app.exe");
429d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(2)->function_name, "__tmainCRTStartup");
430d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(2)->source_file_name,
431e5dc60822e5938fea2ae892ccddb906641ba174emmentovai            "f:\\sp\\vctools\\crt_bld\\self_x86\\crt\\src\\crt0.c");
432e5dc60822e5938fea2ae892ccddb906641ba174emmentovai  ASSERT_EQ(stack->frames()->at(2)->source_line, 327);
433cce3492afc263be86236600d41dca40be7224ee7bryner
434cce3492afc263be86236600d41dca40be7224ee7bryner  // No debug info available for kernel32.dll
435db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai  ASSERT_TRUE(stack->frames()->at(3)->module);
4365ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy  ASSERT_EQ(stack->frames()->at(3)->module->base_address(), 0x7c800000U);
437db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai  ASSERT_EQ(stack->frames()->at(3)->module->code_file(),
438cce3492afc263be86236600d41dca40be7224ee7bryner            "C:\\WINDOWS\\system32\\kernel32.dll");
439d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_TRUE(stack->frames()->at(3)->function_name.empty());
440d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_TRUE(stack->frames()->at(3)->source_file_name.empty());
441d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(3)->source_line, 0);
442cce3492afc263be86236600d41dca40be7224ee7bryner
4435ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy  ASSERT_EQ(state.modules()->module_count(), 13U);
444f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_TRUE(state.modules()->GetMainModule());
445e5dc60822e5938fea2ae892ccddb906641ba174emmentovai  ASSERT_EQ(state.modules()->GetMainModule()->code_file(), "c:\\test_app.exe");
446f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_FALSE(state.modules()->GetModuleForAddress(0));
447f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_EQ(state.modules()->GetMainModule(),
448f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner            state.modules()->GetModuleForAddress(0x400000));
449f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_EQ(state.modules()->GetModuleForAddress(0x7c801234)->debug_file(),
450db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai            "kernel32.pdb");
451f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_EQ(state.modules()->GetModuleForAddress(0x77d43210)->version(),
452db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai            "5.1.2600.2622");
453db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai
4548d2c518c0b1dd6e1c956340759983f0464d356d5nealsid  // Test that disabled exploitability engine defaults to
4558d2c518c0b1dd6e1c956340759983f0464d356d5nealsid  // EXPLOITABILITY_NOT_ANALYZED.
4568d2c518c0b1dd6e1c956340759983f0464d356d5nealsid  ASSERT_EQ(google_breakpad::EXPLOITABILITY_NOT_ANALYZED,
4578d2c518c0b1dd6e1c956340759983f0464d356d5nealsid            state.exploitability());
4588d2c518c0b1dd6e1c956340759983f0464d356d5nealsid
459f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  // Test that the symbol supplier can interrupt processing
460f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  state.Clear();
461f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  supplier.set_interrupt(true);
462f33b8d2d07a057fdd667c2e0db629ba7cbc37cc3bryner  ASSERT_EQ(processor.Process(minidump_file, &state),
463cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org            google_breakpad::PROCESS_SYMBOL_SUPPLIER_INTERRUPTED);
464cce3492afc263be86236600d41dca40be7224ee7bryner}
465e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
466e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comTEST_F(MinidumpProcessorTest, TestThreadMissingMemory) {
467e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidump dump;
468e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, path()).WillRepeatedly(Return("mock minidump"));
469e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, Read()).WillRepeatedly(Return(true));
470e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
471e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MDRawHeader fake_header;
472e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  fake_header.time_date_stamp = 0;
473e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, header()).WillRepeatedly(Return(&fake_header));
474e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
475e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MDRawSystemInfo raw_system_info;
476e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  memset(&raw_system_info, 0, sizeof(raw_system_info));
477e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  raw_system_info.processor_architecture = MD_CPU_ARCHITECTURE_X86;
478e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  raw_system_info.platform_id = MD_OS_WIN32_NT;
479e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  TestMinidumpSystemInfo dump_system_info(raw_system_info);
480e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
481e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, GetSystemInfo()).
482e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com      WillRepeatedly(Return(&dump_system_info));
483e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
484e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidumpThreadList thread_list;
485e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, GetThreadList()).
486e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com      WillOnce(Return(&thread_list));
487e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
48802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  MockMinidumpMemoryList memory_list;
48902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  EXPECT_CALL(dump, GetMemoryList()).
49002ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com      WillOnce(Return(&memory_list));
49102ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com
492e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  // Return a thread missing stack memory.
493e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidumpThread no_memory_thread;
494e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(no_memory_thread, GetThreadID(_)).
495e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    WillRepeatedly(DoAll(SetArgumentPointee<0>(1),
496e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com                         Return(true)));
497e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(no_memory_thread, GetMemory()).
49802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com    WillRepeatedly(Return(reinterpret_cast<MinidumpMemoryRegion*>(NULL)));
49902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com
50002ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  const uint64_t kTestStartOfMemoryRange = 0x1234;
50102ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  EXPECT_CALL(no_memory_thread, GetStartOfStackMemoryRange()).
50202ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com    WillRepeatedly(Return(kTestStartOfMemoryRange));
50302ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  EXPECT_CALL(memory_list, GetMemoryRegionForAddress(kTestStartOfMemoryRange)).
50402ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com    WillRepeatedly(Return(reinterpret_cast<MinidumpMemoryRegion*>(NULL)));
505e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
506e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MDRawContextX86 no_memory_thread_raw_context;
507e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  memset(&no_memory_thread_raw_context, 0,
508e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com         sizeof(no_memory_thread_raw_context));
509e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  no_memory_thread_raw_context.context_flags = MD_CONTEXT_X86_FULL;
5106162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  const uint32_t kExpectedEIP = 0xabcd1234;
511e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  no_memory_thread_raw_context.eip = kExpectedEIP;
512e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  TestMinidumpContext no_memory_thread_context(no_memory_thread_raw_context);
513e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(no_memory_thread, GetContext()).
514e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    WillRepeatedly(Return(&no_memory_thread_context));
515e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
516e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(thread_list, thread_count()).
517e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    WillRepeatedly(Return(1));
518e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(thread_list, GetThreadAtIndex(0)).
519e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    WillOnce(Return(&no_memory_thread));
520e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
52102ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  MinidumpProcessor processor(reinterpret_cast<SymbolSupplier*>(NULL), NULL);
522e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  ProcessState state;
523e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_EQ(processor.Process(&dump, &state),
524e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com            google_breakpad::PROCESS_OK);
525e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
526e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  // Should have a single thread with a single frame in it.
5272971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  ASSERT_EQ(1U, state.threads()->size());
5282971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  ASSERT_EQ(1U, state.threads()->at(0)->frames()->size());
529e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  ASSERT_EQ(kExpectedEIP, state.threads()->at(0)->frames()->at(0)->instruction);
530e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com}
531e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
532e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comTEST_F(MinidumpProcessorTest, TestThreadMissingContext) {
533e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidump dump;
534e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, path()).WillRepeatedly(Return("mock minidump"));
535e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, Read()).WillRepeatedly(Return(true));
536e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
537e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MDRawHeader fake_header;
538e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  fake_header.time_date_stamp = 0;
539e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, header()).WillRepeatedly(Return(&fake_header));
540e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
541e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MDRawSystemInfo raw_system_info;
542e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  memset(&raw_system_info, 0, sizeof(raw_system_info));
543e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  raw_system_info.processor_architecture = MD_CPU_ARCHITECTURE_X86;
544e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  raw_system_info.platform_id = MD_OS_WIN32_NT;
545e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  TestMinidumpSystemInfo dump_system_info(raw_system_info);
546e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
547e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, GetSystemInfo()).
548e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com      WillRepeatedly(Return(&dump_system_info));
549e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
550e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidumpThreadList thread_list;
551e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(dump, GetThreadList()).
552e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com      WillOnce(Return(&thread_list));
553e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
55402ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  MockMinidumpMemoryList memory_list;
55502ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  EXPECT_CALL(dump, GetMemoryList()).
55602ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com      WillOnce(Return(&memory_list));
55702ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com
558e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  // Return a thread missing a thread context.
559e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidumpThread no_context_thread;
560e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(no_context_thread, GetThreadID(_)).
561e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    WillRepeatedly(DoAll(SetArgumentPointee<0>(1),
562e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com                         Return(true)));
563e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(no_context_thread, GetContext()).
56402ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com    WillRepeatedly(Return(reinterpret_cast<MinidumpContext*>(NULL)));
565e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
566e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  // The memory contents don't really matter here, since it won't be used.
567e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  MockMinidumpMemoryRegion no_context_thread_memory(0x1234, "xxx");
568e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(no_context_thread, GetMemory()).
569e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    WillRepeatedly(Return(&no_context_thread_memory));
57002ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  EXPECT_CALL(no_context_thread, GetStartOfStackMemoryRange()).
57102ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com    Times(0);
57202ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  EXPECT_CALL(memory_list, GetMemoryRegionForAddress(_)).
57302ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com    Times(0);
574e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
575e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(thread_list, thread_count()).
576e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    WillRepeatedly(Return(1));
577e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_CALL(thread_list, GetThreadAtIndex(0)).
578e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com    WillOnce(Return(&no_context_thread));
579e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
58002ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com  MinidumpProcessor processor(reinterpret_cast<SymbolSupplier*>(NULL), NULL);
581e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  ProcessState state;
582e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  EXPECT_EQ(processor.Process(&dump, &state),
583e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com            google_breakpad::PROCESS_OK);
584e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
585e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com  // Should have a single thread with zero frames.
5862971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  ASSERT_EQ(1U, state.threads()->size());
5872971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  ASSERT_EQ(0U, state.threads()->at(0)->frames()->size());
588e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com}
589e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com
5908647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovai}  // namespace
5918647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovai
592cce3492afc263be86236600d41dca40be7224ee7brynerint main(int argc, char *argv[]) {
593b56cfa067add059d0894433393e798fe0604970enealsid  ::testing::InitGoogleTest(&argc, argv);
594b56cfa067add059d0894433393e798fe0604970enealsid  return RUN_ALL_TESTS();
595cce3492afc263be86236600d41dca40be7224ee7bryner}
596