crashpad/snapshot/linux/process_reader_linux.h
Mark Mentovai 6278690abe Update copyright boilerplate, 2022 edition (Crashpad)
sed -i '' -E -e 's/Copyright (.+) The Crashpad Authors\. All rights reserved\.$/Copyright \1 The Crashpad Authors/' $(git grep -El 'Copyright (.+) The Crashpad Authors\. All rights reserved\.$')

Bug: chromium:1098010
Change-Id: I8d6138469ddbe3d281a5d83f64cf918ec2491611
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3878262
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
2022-09-06 23:54:07 +00:00

187 lines
6.4 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2017 The Crashpad Authors
//
// 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_LINUX_PROCESS_READER_LINUX_H_
#define CRASHPAD_SNAPSHOT_LINUX_PROCESS_READER_LINUX_H_
#include <sys/time.h>
#include <sys/types.h>
#include <memory>
#include <string>
#include <vector>
#include "snapshot/elf/elf_image_reader.h"
#include "snapshot/module_snapshot.h"
#include "util/linux/address_types.h"
#include "util/linux/memory_map.h"
#include "util/linux/ptrace_connection.h"
#include "util/linux/thread_info.h"
#include "util/misc/initialization_state_dcheck.h"
#include "util/posix/process_info.h"
#include "util/process/process_memory.h"
namespace crashpad {
//! \brief Accesses information about another process, identified by a process
//! ID.
class ProcessReaderLinux {
public:
//! \brief Contains information about a thread that belongs to a process.
struct Thread {
Thread();
~Thread();
//! \brief Initializes the thread's stack using \a stack_pointer instead of
//! the stack pointer in \a thread_info.
//!
//! This method initializes \a stack_region_address and \a stack_region_size
//! overwriting any values they previously contained. This is useful, for
//! example, if the thread is currently in a signal handler context, which
//! may execute on a different stack than was used before the signal was
//! received.
//!
//! \param[in] reader A process reader for the target process.
//! \param[in] stack_pointer The stack pointer for the stack to initialize.
void InitializeStackFromSP(ProcessReaderLinux* reader,
LinuxVMAddress stack_pointer);
ThreadInfo thread_info;
LinuxVMAddress stack_region_address;
LinuxVMSize stack_region_size;
std::string name;
pid_t tid;
int sched_policy;
int static_priority;
int nice_value;
//! \brief `true` if `sched_policy`, `static_priority`, and `nice_value` are
//! all valid.
bool have_priorities;
private:
friend class ProcessReaderLinux;
bool InitializePtrace(PtraceConnection* connection);
void InitializeStack(ProcessReaderLinux* reader);
};
//! \brief Contains information about a module loaded into a process.
struct Module {
Module();
~Module();
//! \brief The pathname used to load the module from disk.
std::string name;
//! \brief An image reader for the module.
//!
//! The lifetime of this ElfImageReader is scoped to the lifetime of the
//! ProcessReaderLinux that created it.
//!
//! This field may be `nullptr` if a reader could not be created for the
//! module.
ElfImageReader* elf_reader;
//! \brief The module's type.
ModuleSnapshot::ModuleType type;
};
ProcessReaderLinux();
ProcessReaderLinux(const ProcessReaderLinux&) = delete;
ProcessReaderLinux& operator=(const ProcessReaderLinux&) = delete;
~ProcessReaderLinux();
//! \brief Initializes this object.
//!
//! This method must be successfully called before calling any other method in
//! this class and may only be called once.
//!
//! \param[in] connection A PtraceConnection to the target process.
//! \return `true` on success. `false` on failure with a message logged.
bool Initialize(PtraceConnection* connection);
//! \brief Return `true` if the target task is a 64-bit process.
bool Is64Bit() const { return is_64_bit_; }
//! \brief Return the target process' process ID.
pid_t ProcessID() const { return process_info_.ProcessID(); }
//! \brief Return the target process' parent process ID.
pid_t ParentProcessID() const { return process_info_.ParentProcessID(); }
//! \brief Return a memory reader for the target process.
const ProcessMemoryLinux* Memory() const { return connection_->Memory(); }
//! \brief Return a memory map of the target process.
MemoryMap* GetMemoryMap() { return &memory_map_; }
//! \brief Determines the target process start time.
//!
//! \param[out] start_time The time that the process started.
//! \return `true` on success with \a start_time set. Otherwise `false` with a
//! message logged.
bool StartTime(timeval* start_time) const;
//! \brief Determines the target process execution time.
//!
//! \param[out] user_time The amount of time the process has executed code in
//! user mode.
//! \param[out] system_time The amount of time the process has executed code
//! in system mode.
//!
//! \return `true` on success, `false` on failure, with a warning logged. On
//! failure, \a user_time and \a system_time will be set to represent no
//! time spent executing code in user or system mode.
bool CPUTimes(timeval* user_time, timeval* system_time) const;
//! \brief Return a vector of threads that are in the task process. If the
//! main thread is able to be identified and traced, it will be placed at
//! index `0`.
const std::vector<Thread>& Threads();
//! \return The modules loaded in the process. The first element (at index
//! `0`) corresponds to the main executable.
const std::vector<Module>& Modules();
//! \return On Android, the abort message that was passed to
//! android_set_abort_message(). This is only available on Q or later.
const std::string& AbortMessage();
private:
void InitializeThreads();
void InitializeModules();
void InitializeAbortMessage();
template <bool Is64Bit>
void ReadAbortMessage(const MemoryMap::Mapping* mapping);
PtraceConnection* connection_; // weak
ProcessInfo process_info_;
MemoryMap memory_map_;
std::vector<Thread> threads_;
std::vector<Module> modules_;
std::string abort_message_;
std::vector<std::unique_ptr<ElfImageReader>> elf_readers_;
bool is_64_bit_;
bool initialized_threads_;
bool initialized_modules_;
InitializationStateDcheck initialized_;
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_LINUX_PROCESS_READER_LINUX_H_