minidump_processor_unittest.cc revision 8647dde8cc03ef16b565dccc75574ee5f0d9cf72
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
33cce3492afc263be86236600d41dca40be7224ee7bryner#include <string>
34fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai#include "google_airbag/processor/call_stack.h"
35fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai#include "google_airbag/processor/minidump.h"
36fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai#include "google_airbag/processor/minidump_processor.h"
37fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai#include "google_airbag/processor/process_state.h"
38fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai#include "google_airbag/processor/stack_frame.h"
39fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai#include "google_airbag/processor/symbol_supplier.h"
402466d8e993a800a17e00deda2f3a27e0505140e1mmentovai#include "processor/scoped_ptr.h"
41cce3492afc263be86236600d41dca40be7224ee7bryner
428647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovainamespace {
438647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovai
44cce3492afc263be86236600d41dca40be7224ee7brynerusing std::string;
45246f4068280b5b191303ff13671e43a0522987demmentovaiusing google_airbag::CallStack;
468647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovaiusing google_airbag::MinidumpModule;
47cce3492afc263be86236600d41dca40be7224ee7brynerusing google_airbag::MinidumpProcessor;
48e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovaiusing google_airbag::ProcessState;
492466d8e993a800a17e00deda2f3a27e0505140e1mmentovaiusing google_airbag::scoped_ptr;
508647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovaiusing google_airbag::SymbolSupplier;
51cce3492afc263be86236600d41dca40be7224ee7bryner
52cce3492afc263be86236600d41dca40be7224ee7bryner#define ASSERT_TRUE(cond) \
53cce3492afc263be86236600d41dca40be7224ee7bryner  if (!(cond)) {                                                        \
54cce3492afc263be86236600d41dca40be7224ee7bryner    fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
55cce3492afc263be86236600d41dca40be7224ee7bryner    return false; \
56cce3492afc263be86236600d41dca40be7224ee7bryner  }
57cce3492afc263be86236600d41dca40be7224ee7bryner
58cce3492afc263be86236600d41dca40be7224ee7bryner#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2))
59cce3492afc263be86236600d41dca40be7224ee7bryner
60cce3492afc263be86236600d41dca40be7224ee7brynerclass TestSymbolSupplier : public SymbolSupplier {
61cce3492afc263be86236600d41dca40be7224ee7bryner public:
620170bea32f3b6745a924c04899d0dae563e078f6bryner  virtual string GetSymbolFile(MinidumpModule *module);
63cce3492afc263be86236600d41dca40be7224ee7bryner};
64cce3492afc263be86236600d41dca40be7224ee7bryner
650170bea32f3b6745a924c04899d0dae563e078f6brynerstring TestSymbolSupplier::GetSymbolFile(MinidumpModule *module) {
66cce3492afc263be86236600d41dca40be7224ee7bryner  if (*(module->GetName()) == "c:\\test_app.exe") {
67c34850a2023442a22fa653ab8546e72738ed2dd4mmentovai    // The funny-looking pathname is so that the symbol file can also be
68c34850a2023442a22fa653ab8546e72738ed2dd4mmentovai    // reached by a SimpleSymbolSupplier.
69cce3492afc263be86236600d41dca40be7224ee7bryner    return string(getenv("srcdir") ? getenv("srcdir") : ".") +
70c34850a2023442a22fa653ab8546e72738ed2dd4mmentovai      "/src/processor/testdata/symbols/"
7176f052f8fbf8864dee5992b857229d06560a766ammentovai      "test_app.pdb/8DDB7E9A365748938D6EB08B1DCA31AA1/test_app.sym";
72cce3492afc263be86236600d41dca40be7224ee7bryner  }
73cce3492afc263be86236600d41dca40be7224ee7bryner
74cce3492afc263be86236600d41dca40be7224ee7bryner  return "";
75cce3492afc263be86236600d41dca40be7224ee7bryner}
76cce3492afc263be86236600d41dca40be7224ee7bryner
77cce3492afc263be86236600d41dca40be7224ee7brynerstatic bool RunTests() {
78cce3492afc263be86236600d41dca40be7224ee7bryner  TestSymbolSupplier supplier;
79cce3492afc263be86236600d41dca40be7224ee7bryner  MinidumpProcessor processor(&supplier);
80cce3492afc263be86236600d41dca40be7224ee7bryner
81cce3492afc263be86236600d41dca40be7224ee7bryner  string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
82cce3492afc263be86236600d41dca40be7224ee7bryner                         "/src/processor/testdata/minidump2.dmp";
83cce3492afc263be86236600d41dca40be7224ee7bryner
84e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  scoped_ptr<ProcessState> state(processor.Process(minidump_file));
85e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_TRUE(state.get());
86e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_EQ(state->cpu(), "x86");
87e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_EQ(state->cpu_info(), "GenuineIntel family 6 model 13 stepping 8");
88e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_EQ(state->os(), "Windows NT");
89e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_EQ(state->os_version(), "5.1.2600 Service Pack 2");
90e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_TRUE(state->crashed());
91e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_EQ(state->crash_reason(), "EXCEPTION_ACCESS_VIOLATION");
9276f052f8fbf8864dee5992b857229d06560a766ammentovai  ASSERT_EQ(state->crash_address(), 0x45);
93e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_EQ(state->threads()->size(), 1);
9476f052f8fbf8864dee5992b857229d06560a766ammentovai  ASSERT_EQ(state->requesting_thread(), 0);
95e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  CallStack *stack = state->threads()->at(0);
96e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai  ASSERT_TRUE(stack);
97d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->size(), 4);
98cce3492afc263be86236600d41dca40be7224ee7bryner
99d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(0)->module_base, 0x400000);
100d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(0)->module_name, "c:\\test_app.exe");
101d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(0)->function_name, "CrashFunction()");
102d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(0)->source_file_name, "c:\\test_app.cc");
10376f052f8fbf8864dee5992b857229d06560a766ammentovai  ASSERT_EQ(stack->frames()->at(0)->source_line, 51);
104cce3492afc263be86236600d41dca40be7224ee7bryner
105d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(1)->module_base, 0x400000);
106d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(1)->module_name, "c:\\test_app.exe");
107d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(1)->function_name, "main");
108d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(1)->source_file_name, "c:\\test_app.cc");
10976f052f8fbf8864dee5992b857229d06560a766ammentovai  ASSERT_EQ(stack->frames()->at(1)->source_line, 56);
110cce3492afc263be86236600d41dca40be7224ee7bryner
111cce3492afc263be86236600d41dca40be7224ee7bryner  // This comes from the CRT
112d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(2)->module_base, 0x400000);
113d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(2)->module_name, "c:\\test_app.exe");
114d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(2)->function_name, "__tmainCRTStartup");
115d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(2)->source_file_name,
116cce3492afc263be86236600d41dca40be7224ee7bryner            "f:\\rtm\\vctools\\crt_bld\\self_x86\\crt\\src\\crt0.c");
117d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(2)->source_line, 318);
118cce3492afc263be86236600d41dca40be7224ee7bryner
119cce3492afc263be86236600d41dca40be7224ee7bryner  // No debug info available for kernel32.dll
120d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(3)->module_base, 0x7c800000);
121d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(3)->module_name,
122cce3492afc263be86236600d41dca40be7224ee7bryner            "C:\\WINDOWS\\system32\\kernel32.dll");
123d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_TRUE(stack->frames()->at(3)->function_name.empty());
124d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_TRUE(stack->frames()->at(3)->source_file_name.empty());
125d119a921ea611dc38cfcb7411759ddf2c688603fmmentovai  ASSERT_EQ(stack->frames()->at(3)->source_line, 0);
126cce3492afc263be86236600d41dca40be7224ee7bryner
127cce3492afc263be86236600d41dca40be7224ee7bryner  return true;
128cce3492afc263be86236600d41dca40be7224ee7bryner}
129cce3492afc263be86236600d41dca40be7224ee7bryner
1308647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovai}  // namespace
1318647dde8cc03ef16b565dccc75574ee5f0d9cf72mmentovai
132cce3492afc263be86236600d41dca40be7224ee7brynerint main(int argc, char *argv[]) {
133cce3492afc263be86236600d41dca40be7224ee7bryner  if (!RunTests()) {
134cce3492afc263be86236600d41dca40be7224ee7bryner    return 1;
135cce3492afc263be86236600d41dca40be7224ee7bryner  }
136cce3492afc263be86236600d41dca40be7224ee7bryner
137cce3492afc263be86236600d41dca40be7224ee7bryner  return 0;
138cce3492afc263be86236600d41dca40be7224ee7bryner}
139