mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +08:00
Some plumbing for the beginning of getting handles into snapshot/minidump
Follows https://codereview.chromium.org/1400413002/. R=mark@chromium.org BUG=crashpad:21, crashpad:46, crashpad:52 Review URL: https://codereview.chromium.org/1407643004 .
This commit is contained in:
parent
7de04b02f8
commit
4600643a78
@ -621,6 +621,71 @@ struct __attribute__((packed, aligned(4))) MINIDUMP_MEMORY_LIST {
|
||||
MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges[0];
|
||||
};
|
||||
|
||||
//! \brief Contains the state of an individual system handle at the time the
|
||||
//! snapshot was taken. This structure is Windows-specific.
|
||||
//!
|
||||
//! \sa MINIDUMP_HANDLE_DESCRIPTOR_2
|
||||
struct __attribute__((packed, aligned(4))) MINIDUMP_HANDLE_DESCRIPTOR {
|
||||
//! \brief The Windows `HANDLE` value.
|
||||
uint64_t Handle;
|
||||
|
||||
//! \brief An RVA to a MINIDUMP_STRING structure that specifies the object
|
||||
//! type of the handle. This member can be zero.
|
||||
RVA TypeNameRva;
|
||||
|
||||
//! \brief An RVA to a MINIDUMP_STRING structure that specifies the object
|
||||
//! name of the handle. This member can be zero.
|
||||
RVA ObjectNameRva;
|
||||
|
||||
//! \brief The attributes for the handle, this corresponds to `OBJ_INHERIT`,
|
||||
//! `OBJ_CASE_INSENSITIVE`, etc.
|
||||
uint32_t Attributes;
|
||||
|
||||
//! \brief The `ACCESS_MASK` for the handle.
|
||||
uint32_t GrantedAccess;
|
||||
|
||||
//! \brief This is the number of open handles to the object that this handle
|
||||
//! refers to.
|
||||
uint32_t HandleCount;
|
||||
|
||||
//! \brief This is the number kernel references to the object that this
|
||||
//! handle refers to.
|
||||
uint32_t PointerCount;
|
||||
};
|
||||
|
||||
//! \brief Contains the state of an individual system handle at the time the
|
||||
//! snapshot was taken. This structure is Windows-specific.
|
||||
//!
|
||||
//! \sa MINIDUMP_HANDLE_DESCRIPTOR
|
||||
struct __attribute__((packed, aligned(4))) MINIDUMP_HANDLE_DESCRIPTOR_2
|
||||
: public MINIDUMP_HANDLE_DESCRIPTOR {
|
||||
//! \brief An RVA to a MINIDUMP_HANDLE_OBJECT_INFORMATION structure that
|
||||
//! specifies object-specific information. This member can be zero if
|
||||
//! there is no extra information.
|
||||
RVA ObjectInfoRva;
|
||||
|
||||
//! \brief Must be zero.
|
||||
uint32_t Reserved0;
|
||||
};
|
||||
|
||||
//! \brief Represents the header for a handle data stream.
|
||||
struct __attribute((packed, aligned(4))) MINIDUMP_HANDLE_DATA_STREAM {
|
||||
//! \brief The size of the header information for the stream, in bytes. This
|
||||
//! value is `sizeof(MINIDUMP_HANDLE_DATA_STREAM)`.
|
||||
uint32_t SizeOfHeader;
|
||||
|
||||
//! \brief The size of a descriptor in the stream, in bytes. This value is
|
||||
//! `sizeof(MINIDUMP_HANDLE_DESCRIPTOR)` or
|
||||
//! `sizeof(MINIDUMP_HANDLE_DESCRIPTOR_2)`.
|
||||
uint32_t SizeOfDescriptor;
|
||||
|
||||
//! \brief The number of descriptors in the stream.
|
||||
uint32_t NumberOfDescriptors;
|
||||
|
||||
//! \brief Must be zero.
|
||||
uint32_t Reserved;
|
||||
};
|
||||
|
||||
//! \anchor MINIDUMP_MISCx
|
||||
//! \name MINIDUMP_MISC*
|
||||
//!
|
||||
|
31
snapshot/handle_snapshot.cc
Normal file
31
snapshot/handle_snapshot.cc
Normal file
@ -0,0 +1,31 @@
|
||||
// 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/handle_snapshot.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
HandleSnapshot::HandleSnapshot()
|
||||
: type_name(),
|
||||
handle(0),
|
||||
attributes(0),
|
||||
granted_access(0),
|
||||
pointer_count(0),
|
||||
handle_count(0) {
|
||||
}
|
||||
|
||||
HandleSnapshot::~HandleSnapshot() {
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
56
snapshot/handle_snapshot.h
Normal file
56
snapshot/handle_snapshot.h
Normal file
@ -0,0 +1,56 @@
|
||||
// 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_HANDLE_SNAPSHOT_H_
|
||||
#define CRASHPAD_SNAPSHOT_HANDLE_SNAPSHOT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
struct HandleSnapshot {
|
||||
HandleSnapshot();
|
||||
~HandleSnapshot();
|
||||
|
||||
//! \brief A string representation of the handle's type.
|
||||
std::wstring type_name;
|
||||
|
||||
//! \brief The handle's value.
|
||||
uint32_t handle;
|
||||
|
||||
//! \brief The attributes for the handle, e.g. `OBJ_INHERIT`,
|
||||
//! `OBJ_CASE_INSENSITIVE`, etc.
|
||||
uint32_t attributes;
|
||||
|
||||
//! \brief The ACCESS_MASK for the handle in this process.
|
||||
//!
|
||||
//! See
|
||||
//! http://blogs.msdn.com/b/openspecification/archive/2010/04/01/about-the-access-mask-structure.aspx
|
||||
//! for more information.
|
||||
uint32_t granted_access;
|
||||
|
||||
//! \brief The number of kernel references to the object that this handle
|
||||
//! refers to.
|
||||
uint32_t pointer_count;
|
||||
|
||||
//! \brief The number of open handles to the object that this handle refers
|
||||
//! to.
|
||||
uint32_t handle_count;
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_HANDLE_SNAPSHOT_H_
|
@ -184,6 +184,12 @@ std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotMinidump::MemoryMap()
|
||||
return std::vector<const MemoryMapRegionSnapshot*>();
|
||||
}
|
||||
|
||||
std::vector<HandleSnapshot> ProcessSnapshotMinidump::Handles() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED(); // https://code.google.com/p/crashpad/issues/detail?id=10
|
||||
return std::vector<HandleSnapshot>();
|
||||
}
|
||||
|
||||
std::vector<const MemorySnapshot*> ProcessSnapshotMinidump::ExtraMemory()
|
||||
const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
@ -70,6 +70,7 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot {
|
||||
std::vector<const ModuleSnapshot*> Modules() const override;
|
||||
const ExceptionSnapshot* Exception() const override;
|
||||
std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const override;
|
||||
std::vector<HandleSnapshot> Handles() const override;
|
||||
std::vector<const MemorySnapshot*> ExtraMemory() const override;
|
||||
|
||||
private:
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "snapshot/handle_snapshot.h"
|
||||
#include "util/misc/uuid.h"
|
||||
|
||||
namespace crashpad {
|
||||
@ -171,6 +172,12 @@ class ProcessSnapshot {
|
||||
//! the ProcessSnapshot object that they were obtained from.
|
||||
virtual std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const = 0;
|
||||
|
||||
//! \brief Returns HandleSnapshot objects reflecting the open handles in the
|
||||
//! snapshot process at the time of the snapshot.
|
||||
//!
|
||||
//! \return A vector of HandleSnapshot objects.
|
||||
virtual std::vector<HandleSnapshot> Handles() const = 0;
|
||||
|
||||
//! \brief Returns a vector of additional memory blocks that should be
|
||||
//! included in a minidump.
|
||||
//!
|
||||
|
@ -36,6 +36,8 @@
|
||||
'crashpad_info_client_options.cc',
|
||||
'crashpad_info_client_options.h',
|
||||
'exception_snapshot.h',
|
||||
'handle_snapshot.cc',
|
||||
'handle_snapshot.h',
|
||||
'mac/cpu_context_mac.cc',
|
||||
'mac/cpu_context_mac.h',
|
||||
'mac/exception_snapshot_mac.cc',
|
||||
|
@ -34,6 +34,7 @@ TestProcessSnapshot::TestProcessSnapshot()
|
||||
modules_(),
|
||||
exception_(),
|
||||
memory_map_(),
|
||||
handles_(),
|
||||
extra_memory_() {
|
||||
}
|
||||
|
||||
@ -107,6 +108,10 @@ std::vector<const MemoryMapRegionSnapshot*> TestProcessSnapshot::MemoryMap()
|
||||
return memory_map;
|
||||
}
|
||||
|
||||
std::vector<HandleSnapshot> TestProcessSnapshot::Handles() const {
|
||||
return handles_;
|
||||
}
|
||||
|
||||
std::vector<const MemorySnapshot*> TestProcessSnapshot::ExtraMemory() const {
|
||||
std::vector<const MemorySnapshot*> extra_memory;
|
||||
for (const auto& em : extra_memory_)
|
||||
|
@ -106,6 +106,13 @@ class TestProcessSnapshot final : public ProcessSnapshot {
|
||||
memory_map_.push_back(region.release());
|
||||
}
|
||||
|
||||
//! \brief Adds a handle snapshot to be returned by Handles().
|
||||
//!
|
||||
//! \param[in] region The handle snapshot that will be included in Handles().
|
||||
void AddHandle(const HandleSnapshot& handle) {
|
||||
handles_.push_back(handle);
|
||||
}
|
||||
|
||||
//! \brief Add a memory snapshot to be returned by ExtraMemory().
|
||||
//!
|
||||
//! \param[in] extra_memory The memory snapshot that will be included in
|
||||
@ -131,6 +138,7 @@ class TestProcessSnapshot final : public ProcessSnapshot {
|
||||
std::vector<const ModuleSnapshot*> Modules() const override;
|
||||
const ExceptionSnapshot* Exception() const override;
|
||||
std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const override;
|
||||
std::vector<HandleSnapshot> Handles() const override;
|
||||
std::vector<const MemorySnapshot*> ExtraMemory() const override;
|
||||
|
||||
private:
|
||||
@ -148,6 +156,7 @@ class TestProcessSnapshot final : public ProcessSnapshot {
|
||||
PointerVector<ModuleSnapshot> modules_;
|
||||
scoped_ptr<ExceptionSnapshot> exception_;
|
||||
PointerVector<MemoryMapRegionSnapshot> memory_map_;
|
||||
std::vector<HandleSnapshot> handles_;
|
||||
PointerVector<MemorySnapshot> extra_memory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TestProcessSnapshot);
|
||||
|
@ -207,6 +207,21 @@ std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotWin::MemoryMap()
|
||||
return memory_map;
|
||||
}
|
||||
|
||||
std::vector<HandleSnapshot> ProcessSnapshotWin::Handles() const {
|
||||
std::vector<HandleSnapshot> result;
|
||||
for (const auto& handle : process_reader_.GetProcessInfo().Handles()) {
|
||||
HandleSnapshot snapshot;
|
||||
snapshot.type_name = handle.type_name;
|
||||
snapshot.handle = handle.handle;
|
||||
snapshot.attributes = handle.attributes;
|
||||
snapshot.granted_access = handle.granted_access;
|
||||
snapshot.pointer_count = handle.pointer_count;
|
||||
snapshot.handle_count = handle.handle_count;
|
||||
result.push_back(snapshot);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<const MemorySnapshot*> ProcessSnapshotWin::ExtraMemory() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
std::vector<const MemorySnapshot*> extra_memory;
|
||||
|
@ -135,6 +135,7 @@ class ProcessSnapshotWin final : public ProcessSnapshot {
|
||||
std::vector<const ModuleSnapshot*> Modules() const override;
|
||||
const ExceptionSnapshot* Exception() const override;
|
||||
std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const override;
|
||||
std::vector<HandleSnapshot> Handles() const override;
|
||||
std::vector<const MemorySnapshot*> ExtraMemory() const override;
|
||||
|
||||
private:
|
||||
|
@ -602,7 +602,7 @@ ProcessInfo::GetReadableRanges(
|
||||
return GetReadableRangesOfMemoryMap(range, MemoryInfo());
|
||||
}
|
||||
|
||||
const std::vector<ProcessInfo::Handle>& ProcessInfo::Handles() {
|
||||
const std::vector<ProcessInfo::Handle>& ProcessInfo::Handles() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
if (handles_.empty())
|
||||
handles_ = BuildHandleVector(process_);
|
||||
|
@ -140,7 +140,7 @@ class ProcessInfo {
|
||||
const CheckedRange<WinVMAddress, WinVMSize>& range) const;
|
||||
|
||||
//! \brief Retrieves information about open handles in the target process.
|
||||
const std::vector<Handle>& Handles();
|
||||
const std::vector<Handle>& Handles() const;
|
||||
|
||||
private:
|
||||
template <class Traits>
|
||||
@ -168,7 +168,11 @@ class ProcessInfo {
|
||||
WinVMSize peb_size_;
|
||||
std::vector<Module> modules_;
|
||||
std::vector<MEMORY_BASIC_INFORMATION64> memory_info_;
|
||||
std::vector<Handle> handles_;
|
||||
|
||||
// Handles() is logically const, but updates this member on first retrieval.
|
||||
// See https://code.google.com/p/crashpad/issues/detail?id=9.
|
||||
mutable std::vector<Handle> handles_;
|
||||
|
||||
bool is_64_bit_;
|
||||
bool is_wow64_;
|
||||
InitializationStateDcheck initialized_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user