mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:26:06 +00:00
win: Retrieve "simple map" annotations from modules
Follows https://codereview.chromium.org/1126273003/. R=rsesek@chromium.org, cpu@chromium.org TBR=mark@chromium.org BUG=crashpad:1 Review URL: https://codereview.chromium.org/1138923004
This commit is contained in:
parent
44727e9c79
commit
58df54fffb
@ -31,7 +31,7 @@ class ProcessReader;
|
||||
//! process.
|
||||
//!
|
||||
//! These annotations are stored for the benefit of crash reporters, and provide
|
||||
//! information though to be potentially useful for crash analysis. This class
|
||||
//! information thought to be potentially useful for crash analysis. This class
|
||||
//! can decode annotations stored in these formats:
|
||||
//! - CrashpadInfo. This format is used by Crashpad clients. The “simple
|
||||
//! annotations” are recovered from any module with a compatible data
|
||||
|
@ -87,10 +87,12 @@
|
||||
'process_snapshot.h',
|
||||
'system_snapshot.h',
|
||||
'thread_snapshot.h',
|
||||
'win/module_snapshot_win.cc',
|
||||
'win/memory_snapshot_win.cc',
|
||||
'win/memory_snapshot_win.h',
|
||||
'win/module_snapshot_win.cc',
|
||||
'win/module_snapshot_win.h',
|
||||
'win/pe_image_annotations_reader.cc',
|
||||
'win/pe_image_annotations_reader.h',
|
||||
'win/pe_image_reader.cc',
|
||||
'win/pe_image_reader.h',
|
||||
'win/process_reader_win.cc',
|
||||
|
@ -74,6 +74,7 @@
|
||||
'mac/process_types_test.cc',
|
||||
'mac/system_snapshot_mac_test.cc',
|
||||
'minidump/process_snapshot_minidump_test.cc',
|
||||
'win/pe_image_annotations_reader_test.cc',
|
||||
'win/process_reader_win_test.cc',
|
||||
'win/system_snapshot_win_test.cc',
|
||||
],
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "snapshot/win/module_snapshot_win.h"
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "snapshot/win/pe_image_annotations_reader.h"
|
||||
#include "snapshot/win/pe_image_reader.h"
|
||||
#include "util/misc/tri_state.h"
|
||||
#include "util/misc/uuid.h"
|
||||
@ -152,15 +153,18 @@ void ModuleSnapshotWin::UUID(crashpad::UUID* uuid) const {
|
||||
|
||||
std::vector<std::string> ModuleSnapshotWin::AnnotationsVector() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
CHECK(false) << "TODO(scottmg)";
|
||||
// These correspond to system-logged things on Mac. We don't currently track
|
||||
// any of these on Windows, but could in the future.
|
||||
// See https://code.google.com/p/crashpad/issues/detail?id=38.
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> ModuleSnapshotWin::AnnotationsSimpleMap()
|
||||
const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
CHECK(false) << "TODO(scottmg)";
|
||||
return std::map<std::string, std::string>();
|
||||
PEImageAnnotationsReader annotations_reader(
|
||||
process_reader_, pe_image_reader_.get(), name_);
|
||||
return annotations_reader.SimpleMap();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
74
snapshot/win/pe_image_annotations_reader.cc
Normal file
74
snapshot/win/pe_image_annotations_reader.cc
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "snapshot/win/pe_image_annotations_reader.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "client/simple_string_dictionary.h"
|
||||
#include "snapshot/win/pe_image_reader.h"
|
||||
#include "snapshot/win/process_reader_win.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
PEImageAnnotationsReader::PEImageAnnotationsReader(
|
||||
ProcessReaderWin* process_reader,
|
||||
const PEImageReader* pe_image_reader,
|
||||
const std::wstring& name)
|
||||
: name_(name),
|
||||
process_reader_(process_reader),
|
||||
pe_image_reader_(pe_image_reader) {
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> PEImageAnnotationsReader::SimpleMap() const {
|
||||
std::map<std::string, std::string> simple_map_annotations;
|
||||
ReadCrashpadSimpleAnnotations(&simple_map_annotations);
|
||||
return simple_map_annotations;
|
||||
}
|
||||
|
||||
void PEImageAnnotationsReader::ReadCrashpadSimpleAnnotations(
|
||||
std::map<std::string, std::string>* simple_map_annotations) const {
|
||||
process_types::CrashpadInfo crashpad_info;
|
||||
if (!pe_image_reader_->GetCrashpadInfo(&crashpad_info))
|
||||
return;
|
||||
|
||||
if (!crashpad_info.simple_annotations)
|
||||
return;
|
||||
|
||||
std::vector<SimpleStringDictionary::Entry>
|
||||
simple_annotations(SimpleStringDictionary::num_entries);
|
||||
if (!process_reader_->ReadMemory(
|
||||
crashpad_info.simple_annotations,
|
||||
simple_annotations.size() * sizeof(simple_annotations[0]),
|
||||
&simple_annotations[0])) {
|
||||
LOG(WARNING) << "could not read simple annotations from "
|
||||
<< base::UTF16ToUTF8(name_);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& entry : simple_annotations) {
|
||||
size_t key_length = strnlen(entry.key, sizeof(entry.key));
|
||||
if (key_length) {
|
||||
std::string key(entry.key, key_length);
|
||||
std::string value(entry.value, strnlen(entry.value, sizeof(entry.value)));
|
||||
if (!simple_map_annotations->insert(std::make_pair(key, value)).second) {
|
||||
LOG(INFO) << "duplicate simple annotation " << key << " in "
|
||||
<< base::UTF16ToUTF8(name_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
71
snapshot/win/pe_image_annotations_reader.h
Normal file
71
snapshot/win/pe_image_annotations_reader.h
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_SNAPSHOT_WIN_PE_IMAGE_ANNOTATIONS_READER_H_
|
||||
#define CRASHPAD_SNAPSHOT_WIN_PE_IMAGE_ANNOTATIONS_READER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
class PEImageReader;
|
||||
class ProcessReaderWin;
|
||||
|
||||
//! \brief A reader of annotations stored in a PE image mapped into another
|
||||
//! process.
|
||||
//!
|
||||
//! These annotations are stored for the benefit of crash reporters, and provide
|
||||
//! information thought to be potentially useful for crash analysis.
|
||||
//!
|
||||
//! Currently, this class can decode information stored only in the CrashpadInfo
|
||||
//! structure. This format is used by Crashpad clients. The "simple annotations"
|
||||
//! are recovered from any module with a compatible data section, and are
|
||||
//! included in the annotations returned by SimpleMap().
|
||||
class PEImageAnnotationsReader {
|
||||
public:
|
||||
//! \brief Constructs the object.
|
||||
//!
|
||||
//! \param[in] process_reader The reader for the remote process.
|
||||
//! \param[in] image_reader The PEImageReader for the PE image file contained
|
||||
//! within the remote process.
|
||||
//! \param[in] name The module's name, a string to be used in logged messages.
|
||||
//! This string is for diagnostic purposes only, and may be empty.
|
||||
PEImageAnnotationsReader(ProcessReaderWin* process_reader,
|
||||
const PEImageReader* pe_image_reader,
|
||||
const std::wstring& name);
|
||||
~PEImageAnnotationsReader() {}
|
||||
|
||||
//! \brief Returns the module's annotations that are organized as key-value
|
||||
//! pairs, where all keys and values are strings.
|
||||
std::map<std::string, std::string> SimpleMap() const;
|
||||
|
||||
private:
|
||||
// Reads CrashpadInfo::simple_annotations_ on behalf of SimpleMap().
|
||||
void ReadCrashpadSimpleAnnotations(
|
||||
std::map<std::string, std::string>* simple_map_annotations) const;
|
||||
|
||||
std::wstring name_;
|
||||
ProcessReaderWin* process_reader_; // weak
|
||||
const PEImageReader* pe_image_reader_; // weak
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PEImageAnnotationsReader);
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_WIN_PE_IMAGE_ANNOTATIONS_READER_H_
|
147
snapshot/win/pe_image_annotations_reader_test.cc
Normal file
147
snapshot/win/pe_image_annotations_reader_test.cc
Normal file
@ -0,0 +1,147 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "snapshot/win/pe_image_annotations_reader.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "client/crashpad_info.h"
|
||||
#include "client/simple_string_dictionary.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "snapshot/win/pe_image_reader.h"
|
||||
#include "snapshot/win/process_reader_win.h"
|
||||
#include "test/win/win_multiprocess.h"
|
||||
#include "util/file/file_io.h"
|
||||
#include "util/win/process_info.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
class TestPEImageAnnotationsReader final : public WinMultiprocess {
|
||||
public:
|
||||
enum TestType {
|
||||
// Don't crash, just test the CrashpadInfo interface.
|
||||
kDontCrash = 0,
|
||||
|
||||
// The child process should crash by __debugbreak().
|
||||
kCrashDebugBreak,
|
||||
};
|
||||
|
||||
explicit TestPEImageAnnotationsReader(TestType test_type)
|
||||
: WinMultiprocess(), test_type_(test_type) {}
|
||||
|
||||
~TestPEImageAnnotationsReader() {}
|
||||
|
||||
private:
|
||||
// WinMultiprocess:
|
||||
|
||||
void WinMultiprocessParent() override {
|
||||
ProcessReaderWin process_reader;
|
||||
ASSERT_TRUE(process_reader.Initialize(ChildProcess()));
|
||||
|
||||
// Wait for the child process to indicate that it's done setting up its
|
||||
// annotations via the CrashpadInfo interface.
|
||||
char c;
|
||||
CheckedReadFile(ReadPipeHandle(), &c, sizeof(c));
|
||||
|
||||
// Verify the "simple map" annotations set via the CrashpadInfo interface.
|
||||
const std::vector<ProcessInfo::Module>& modules = process_reader.Modules();
|
||||
std::map<std::string, std::string> all_annotations_simple_map;
|
||||
for (const ProcessInfo::Module& module : modules) {
|
||||
PEImageReader pe_image_reader;
|
||||
pe_image_reader.Initialize(&process_reader,
|
||||
module.dll_base,
|
||||
module.size,
|
||||
base::UTF16ToUTF8(module.name));
|
||||
PEImageAnnotationsReader module_annotations_reader(
|
||||
&process_reader, &pe_image_reader, module.name);
|
||||
std::map<std::string, std::string> module_annotations_simple_map =
|
||||
module_annotations_reader.SimpleMap();
|
||||
all_annotations_simple_map.insert(module_annotations_simple_map.begin(),
|
||||
module_annotations_simple_map.end());
|
||||
}
|
||||
|
||||
EXPECT_GE(all_annotations_simple_map.size(), 5u);
|
||||
EXPECT_EQ("crash", all_annotations_simple_map["#TEST# pad"]);
|
||||
EXPECT_EQ("value", all_annotations_simple_map["#TEST# key"]);
|
||||
EXPECT_EQ("y", all_annotations_simple_map["#TEST# x"]);
|
||||
EXPECT_EQ("shorter", all_annotations_simple_map["#TEST# longer"]);
|
||||
EXPECT_EQ("", all_annotations_simple_map["#TEST# empty_value"]);
|
||||
|
||||
if (test_type_ == kCrashDebugBreak)
|
||||
SetExpectedChildExitCode(STATUS_BREAKPOINT);
|
||||
|
||||
// Tell the child process to continue.
|
||||
CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
|
||||
}
|
||||
|
||||
void WinMultiprocessChild() override {
|
||||
CrashpadInfo* crashpad_info = CrashpadInfo::GetCrashpadInfo();
|
||||
|
||||
// This is "leaked" to crashpad_info.
|
||||
SimpleStringDictionary* simple_annotations = new SimpleStringDictionary();
|
||||
simple_annotations->SetKeyValue("#TEST# pad", "break");
|
||||
simple_annotations->SetKeyValue("#TEST# key", "value");
|
||||
simple_annotations->SetKeyValue("#TEST# pad", "crash");
|
||||
simple_annotations->SetKeyValue("#TEST# x", "y");
|
||||
simple_annotations->SetKeyValue("#TEST# longer", "shorter");
|
||||
simple_annotations->SetKeyValue("#TEST# empty_value", "");
|
||||
|
||||
crashpad_info->set_simple_annotations(simple_annotations);
|
||||
|
||||
// Tell the parent that the environment has been set up.
|
||||
char c = '\0';
|
||||
CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
|
||||
|
||||
// Wait for the parent to indicate that it's safe to continue/crash.
|
||||
CheckedReadFile(ReadPipeHandle(), &c, sizeof(c));
|
||||
|
||||
switch (test_type_) {
|
||||
case kDontCrash:
|
||||
break;
|
||||
|
||||
case kCrashDebugBreak:
|
||||
__debugbreak();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TestType test_type_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TestPEImageAnnotationsReader);
|
||||
};
|
||||
|
||||
TEST(PEImageAnnotationsReader, DontCrash) {
|
||||
TestPEImageAnnotationsReader test_pe_image_annotations_reader(
|
||||
TestPEImageAnnotationsReader::kDontCrash);
|
||||
test_pe_image_annotations_reader.Run();
|
||||
}
|
||||
|
||||
TEST(PEImageAnnotationsReader, CrashDebugBreak) {
|
||||
TestPEImageAnnotationsReader test_pe_image_annotations_reader(
|
||||
TestPEImageAnnotationsReader::kCrashDebugBreak);
|
||||
test_pe_image_annotations_reader.Run();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
@ -69,6 +69,13 @@
|
||||
],
|
||||
},
|
||||
}],
|
||||
['OS=="win"', {
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-lshell32.lib',
|
||||
],
|
||||
},
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
|
Loading…
x
Reference in New Issue
Block a user