mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Adding an API to read module annotations in snapshot.gyp
Kasko needs a way to read crash keys from out of process. This API reuses the functionality of PEImageAnnotationsReader. Change-Id: I2f3bbc358212e6f50235183e9dbb4e5a2cf989cf This is a reupload of https://codereview.chromium.org/1586433003/ but for gerrit. Change-Id: I2f3bbc358212e6f50235183e9dbb4e5a2cf989cf Reviewed-on: https://chromium-review.googlesource.com/322550 Reviewed-by: Scott Graham <scottmg@chromium.org> Tested-by: Scott Graham <scottmg@chromium.org> Reviewed-by: Scott Graham <scottmg@google.com>
This commit is contained in:
parent
2e44832850
commit
4794225f22
53
snapshot/api/module_annotations_win.cc
Normal file
53
snapshot/api/module_annotations_win.cc
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2016 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/api/module_annotations_win.h"
|
||||||
|
|
||||||
|
#include "snapshot/win/pe_image_annotations_reader.h"
|
||||||
|
#include "snapshot/win/pe_image_reader.h"
|
||||||
|
#include "snapshot/win/process_reader_win.h"
|
||||||
|
#include "util/win/get_module_information.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
|
||||||
|
bool ReadModuleAnnotations(HANDLE process,
|
||||||
|
HMODULE module,
|
||||||
|
std::map<std::string, std::string>* annotations) {
|
||||||
|
ProcessReaderWin process_reader;
|
||||||
|
if (!process_reader.Initialize(process, ProcessSuspensionState::kRunning))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MODULEINFO module_info;
|
||||||
|
if (!CrashpadGetModuleInformation(
|
||||||
|
process, module, &module_info, sizeof(module_info))) {
|
||||||
|
PLOG(ERROR) << "CrashpadGetModuleInformation";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PEImageReader image_reader;
|
||||||
|
if (!image_reader.Initialize(
|
||||||
|
&process_reader,
|
||||||
|
reinterpret_cast<crashpad::WinVMAddress>(module_info.lpBaseOfDll),
|
||||||
|
module_info.SizeOfImage,
|
||||||
|
""))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PEImageAnnotationsReader annotations_reader(
|
||||||
|
&process_reader, &image_reader, L"");
|
||||||
|
|
||||||
|
*annotations = annotations_reader.SimpleMap();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace crashpad
|
42
snapshot/api/module_annotations_win.h
Normal file
42
snapshot/api/module_annotations_win.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2016 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_API_MODULE_ANNOTATIONS_WIN_H_
|
||||||
|
#define CRASHPAD_SNAPSHOT_API_MODULE_ANNOTATIONS_WIN_H_
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
|
||||||
|
//! \brief Reads the module annotations from another process.
|
||||||
|
//!
|
||||||
|
//! \param[in] process The handle to the process that hosts the \a module.
|
||||||
|
//! Requires PROCESS_QUERY_INFORMATION and PROCESS_VM_READ accesses.
|
||||||
|
//! \param[in] module The handle to the module from which the \a annotations
|
||||||
|
//! will be read. This module should be loaded in the target process.
|
||||||
|
//! \param[out] annotations The map that will be filled with the annotations.
|
||||||
|
//! Remains unchanged if the function returns 'false'.
|
||||||
|
//!
|
||||||
|
//! \return `true` if the annotations could be read succesfully, even if the
|
||||||
|
//! module doesn't contain any annotations.
|
||||||
|
bool ReadModuleAnnotations(HANDLE process,
|
||||||
|
HMODULE module,
|
||||||
|
std::map<std::string, std::string>* annotations);
|
||||||
|
|
||||||
|
} // namespace crashpad
|
||||||
|
|
||||||
|
#endif // CRASHPAD_SNAPSHOT_API_MODULE_ANNOTATIONS_WIN_H_
|
83
snapshot/api/module_annotations_win_test.cc
Normal file
83
snapshot/api/module_annotations_win_test.cc
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// Copyright 2016 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/api/module_annotations_win.h"
|
||||||
|
|
||||||
|
#include "client/crashpad_info.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "test/win/win_multiprocess.h"
|
||||||
|
#include "util/file/file_io.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
namespace test {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class ModuleAnnotationsMultiprocessTest final : public WinMultiprocess {
|
||||||
|
private:
|
||||||
|
void WinMultiprocessParent() override {
|
||||||
|
// Read the child executable module.
|
||||||
|
HMODULE module = nullptr;
|
||||||
|
CheckedReadFile(ReadPipeHandle(), &module, sizeof(module));
|
||||||
|
|
||||||
|
// Reopen the child process with necessary access.
|
||||||
|
HANDLE process_handle =
|
||||||
|
OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||||
|
FALSE,
|
||||||
|
GetProcessId(ChildProcess()));
|
||||||
|
EXPECT_TRUE(process_handle);
|
||||||
|
|
||||||
|
// Read the module annotations in the child process and verify them.
|
||||||
|
std::map<std::string, std::string> annotations;
|
||||||
|
ASSERT_TRUE(ReadModuleAnnotations(process_handle, module, &annotations));
|
||||||
|
|
||||||
|
EXPECT_GE(annotations.size(), 3u);
|
||||||
|
EXPECT_EQ("value", annotations["#APITEST# key"]);
|
||||||
|
EXPECT_EQ("y", annotations["#APITEST# x"]);
|
||||||
|
EXPECT_EQ("", annotations["#APITEST# empty_value"]);
|
||||||
|
|
||||||
|
// Signal the child process to terminate.
|
||||||
|
char c = ' ';
|
||||||
|
CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinMultiprocessChild() override {
|
||||||
|
// Set some test annotations.
|
||||||
|
crashpad::CrashpadInfo* crashpad_info =
|
||||||
|
crashpad::CrashpadInfo::GetCrashpadInfo();
|
||||||
|
|
||||||
|
crashpad::SimpleStringDictionary* simple_annotations =
|
||||||
|
new crashpad::SimpleStringDictionary();
|
||||||
|
simple_annotations->SetKeyValue("#APITEST# key", "value");
|
||||||
|
simple_annotations->SetKeyValue("#APITEST# x", "y");
|
||||||
|
simple_annotations->SetKeyValue("#APITEST# empty_value", "");
|
||||||
|
|
||||||
|
crashpad_info->set_simple_annotations(simple_annotations);
|
||||||
|
|
||||||
|
// Send the executable module.
|
||||||
|
HMODULE module = GetModuleHandle(nullptr);
|
||||||
|
CheckedWriteFile(WritePipeHandle(), &module, sizeof(module));
|
||||||
|
|
||||||
|
// Wait until a signal from the parent process to terminate.
|
||||||
|
char c;
|
||||||
|
CheckedReadFile(ReadPipeHandle(), &c, sizeof(c));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ModuleAnnotationsWin, ReadAnnotations) {
|
||||||
|
WinMultiprocess::Run<ModuleAnnotationsMultiprocessTest>();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace test
|
||||||
|
} // namespace crashpad
|
@ -129,5 +129,32 @@
|
|||||||
}],
|
}],
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'variables': {
|
||||||
|
'conditions': [
|
||||||
|
['OS == "win"', {
|
||||||
|
'snapshot_api_target_type%': 'static_library',
|
||||||
|
}, {
|
||||||
|
# There are no source files except on Windows.
|
||||||
|
'snapshot_api_target_type%': 'none',
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'target_name': 'crashpad_snapshot_api',
|
||||||
|
'type': '<(snapshot_api_target_type)',
|
||||||
|
'dependencies': [
|
||||||
|
'crashpad_snapshot',
|
||||||
|
'../compat/compat.gyp:crashpad_compat',
|
||||||
|
'../third_party/mini_chromium/mini_chromium.gyp:base',
|
||||||
|
'../util/util.gyp:crashpad_util',
|
||||||
|
],
|
||||||
|
'include_dirs': [
|
||||||
|
'..',
|
||||||
|
],
|
||||||
|
'sources': [
|
||||||
|
'api/module_annotations_win.cc',
|
||||||
|
'api/module_annotations_win.h',
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
'dependencies': [
|
'dependencies': [
|
||||||
'crashpad_snapshot_test_module',
|
'crashpad_snapshot_test_module',
|
||||||
'snapshot.gyp:crashpad_snapshot',
|
'snapshot.gyp:crashpad_snapshot',
|
||||||
|
'snapshot.gyp:crashpad_snapshot_api',
|
||||||
'../client/client.gyp:crashpad_client',
|
'../client/client.gyp:crashpad_client',
|
||||||
'../compat/compat.gyp:crashpad_compat',
|
'../compat/compat.gyp:crashpad_compat',
|
||||||
'../test/test.gyp:crashpad_test',
|
'../test/test.gyp:crashpad_test',
|
||||||
@ -68,6 +69,7 @@
|
|||||||
'sources': [
|
'sources': [
|
||||||
'cpu_context_test.cc',
|
'cpu_context_test.cc',
|
||||||
'crashpad_info_client_options_test.cc',
|
'crashpad_info_client_options_test.cc',
|
||||||
|
'api/module_annotations_win_test.cc',
|
||||||
'mac/cpu_context_mac_test.cc',
|
'mac/cpu_context_mac_test.cc',
|
||||||
'mac/mach_o_image_annotations_reader_test.cc',
|
'mac/mach_o_image_annotations_reader_test.cc',
|
||||||
'mac/mach_o_image_reader_test.cc',
|
'mac/mach_o_image_reader_test.cc',
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include "snapshot/win/process_reader_win.h"
|
#include "snapshot/win/process_reader_win.h"
|
||||||
#include "test/paths.h"
|
#include "test/paths.h"
|
||||||
#include "test/win/child_launcher.h"
|
#include "test/win/child_launcher.h"
|
||||||
#include "test/win/win_multiprocess.h"
|
|
||||||
#include "util/file/file_io.h"
|
#include "util/file/file_io.h"
|
||||||
#include "util/win/process_info.h"
|
#include "util/win/process_info.h"
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "snapshot/win/process_reader_win.h"
|
#include "snapshot/win/process_reader_win.h"
|
||||||
#include "test/errors.h"
|
#include "test/errors.h"
|
||||||
#include "util/win/get_function.h"
|
#include "util/win/get_module_information.h"
|
||||||
#include "util/win/module_version.h"
|
#include "util/win/module_version.h"
|
||||||
#include "util/win/process_info.h"
|
#include "util/win/process_info.h"
|
||||||
|
|
||||||
@ -32,15 +32,6 @@ namespace crashpad {
|
|||||||
namespace test {
|
namespace test {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
BOOL CrashpadGetModuleInformation(HANDLE process,
|
|
||||||
HMODULE module,
|
|
||||||
MODULEINFO* module_info,
|
|
||||||
DWORD cb) {
|
|
||||||
static const auto get_module_information =
|
|
||||||
GET_FUNCTION_REQUIRED(L"psapi.dll", ::GetModuleInformation);
|
|
||||||
return get_module_information(process, module, module_info, cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PEImageReader, DebugDirectory) {
|
TEST(PEImageReader, DebugDirectory) {
|
||||||
PEImageReader pe_image_reader;
|
PEImageReader pe_image_reader;
|
||||||
ProcessReaderWin process_reader;
|
ProcessReaderWin process_reader;
|
||||||
|
@ -166,6 +166,8 @@
|
|||||||
'win/exception_handler_server.h',
|
'win/exception_handler_server.h',
|
||||||
'win/get_function.cc',
|
'win/get_function.cc',
|
||||||
'win/get_function.h',
|
'win/get_function.h',
|
||||||
|
'win/get_module_information.cc',
|
||||||
|
'win/get_module_information.h',
|
||||||
'win/handle.cc',
|
'win/handle.cc',
|
||||||
'win/handle.h',
|
'win/handle.h',
|
||||||
'win/module_version.cc',
|
'win/module_version.cc',
|
||||||
|
30
util/win/get_module_information.cc
Normal file
30
util/win/get_module_information.cc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2016 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 "util/win/get_module_information.h"
|
||||||
|
|
||||||
|
#include "util/win/get_function.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
|
||||||
|
BOOL CrashpadGetModuleInformation(HANDLE process,
|
||||||
|
HMODULE module,
|
||||||
|
MODULEINFO* module_info,
|
||||||
|
DWORD cb) {
|
||||||
|
static const auto get_module_information =
|
||||||
|
GET_FUNCTION_REQUIRED(L"psapi.dll", GetModuleInformation);
|
||||||
|
return get_module_information(process, module, module_info, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace crashpad
|
33
util/win/get_module_information.h
Normal file
33
util/win/get_module_information.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2016 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_UTIL_WIN_GET_MODULE_INFORMATION_H_
|
||||||
|
#define CRASHPAD_UTIL_WIN_GET_MODULE_INFORMATION_H_
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define PSAPI_VERSION 1
|
||||||
|
#include <psapi.h>
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
|
||||||
|
//! \brief Proxy function for `GetModuleInformation()`.
|
||||||
|
BOOL CrashpadGetModuleInformation(HANDLE process,
|
||||||
|
HMODULE module,
|
||||||
|
MODULEINFO* module_info,
|
||||||
|
DWORD cb);
|
||||||
|
|
||||||
|
} // namespace crashpad
|
||||||
|
|
||||||
|
#endif // CRASHPAD_UTIL_WIN_GET_MODULE_INFORMATION_H_
|
Loading…
x
Reference in New Issue
Block a user