// Copyright (c) 2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// microdump_processor.cc: A microdump processor.
//
// See microdump_processor.h for documentation.

#include "google_breakpad/processor/microdump_processor.h"

#include <assert.h>

#include <string>

#include "common/using_std_string.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/microdump.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/stackwalker.h"
#include "google_breakpad/processor/stack_frame_symbolizer.h"
#include "processor/logging.h"

namespace google_breakpad {

MicrodumpProcessor::MicrodumpProcessor(StackFrameSymbolizer* frame_symbolizer)
    : frame_symbolizer_(frame_symbolizer) {
  assert(frame_symbolizer);
}

MicrodumpProcessor::~MicrodumpProcessor() {}

ProcessResult MicrodumpProcessor::Process(Microdump *microdump,
                                          ProcessState* process_state) {
  assert(process_state);

  process_state->Clear();

  process_state->modules_ = microdump->GetModules()->Copy();
  scoped_ptr<Stackwalker> stackwalker(
      Stackwalker::StackwalkerForCPU(
                            &process_state->system_info_,
                            microdump->GetContext(),
                            microdump->GetMemory(),
                            process_state->modules_,
                            /* unloaded_modules= */ NULL,
                            frame_symbolizer_));

  scoped_ptr<CallStack> stack(new CallStack());
  if (stackwalker.get()) {
    if (!stackwalker->Walk(stack.get(),
                           &process_state->modules_without_symbols_,
                           &process_state->modules_with_corrupt_symbols_)) {
      BPLOG(INFO) << "Processing was interrupted.";
      return PROCESS_SYMBOL_SUPPLIER_INTERRUPTED;
    }
  } else {
    BPLOG(ERROR) << "No stackwalker found for microdump.";
    return PROCESS_ERROR_NO_THREAD_LIST;
  }

  process_state->threads_.push_back(stack.release());
  process_state->thread_memory_regions_.push_back(microdump->GetMemory());
  process_state->crashed_ = true;
  process_state->requesting_thread_ = 0;
  process_state->system_info_ = *microdump->GetSystemInfo();
  process_state->crash_reason_ = microdump->GetCrashReason();
  process_state->crash_address_ = microdump->GetCrashAddress();

  return PROCESS_OK;
}

}  // namespace google_breakpad
