Add ptrace exit breakpoint
This will let you stop at process exit and inspect it right before the process dies.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use alloc::sync::Arc;
|
||||
use core::mem;
|
||||
use syscall::data::PtraceEvent;
|
||||
use syscall::flag::{PTRACE_FLAG_IGNORE, PTRACE_STOP_SIGNAL, SIG_DFL, SIG_IGN, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU};
|
||||
use syscall::ptrace_event;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#![cfg_attr(feature = "clippy", allow(or_fun_call))]
|
||||
#![cfg_attr(feature = "clippy", allow(too_many_arguments))]
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(alloc)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(asm)]
|
||||
#![feature(concat_idents)]
|
||||
|
||||
@@ -209,8 +209,8 @@ pub fn set_breakpoint(pid: ContextId, flags: PtraceFlags) {
|
||||
/// Wait for the tracee to stop. If an event occurs, it returns a copy
|
||||
/// of that. It will still be available for read using recv_event.
|
||||
///
|
||||
/// Note: Don't call while holding any locks, this will switch
|
||||
/// contexts
|
||||
/// Note: Don't call while holding any locks or allocated data, this
|
||||
/// will switch contexts and may in fact just never terminate.
|
||||
pub fn wait(pid: ContextId) -> Result<()> {
|
||||
let tracer: Arc<WaitCondition> = {
|
||||
let sessions = sessions();
|
||||
@@ -238,7 +238,9 @@ pub fn wait(pid: ContextId) -> Result<()> {
|
||||
}
|
||||
|
||||
/// Notify the tracer and await green flag to continue.
|
||||
/// Note: Don't call while holding any locks, this will switch contexts
|
||||
///
|
||||
/// Note: Don't call while holding any locks or allocated data, this
|
||||
/// will switch contexts and may in fact just never terminate.
|
||||
pub fn breakpoint_callback(match_flags: PtraceFlags, event: Option<PtraceEvent>) -> Option<PtraceFlags> {
|
||||
// Can't hold any locks when executing wait()
|
||||
let (tracee, flags) = {
|
||||
|
||||
@@ -173,7 +173,7 @@ impl SchemeList {
|
||||
Ok(to)
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> ::alloc::collections::btree_map::Iter<SchemeId, Arc<Box<Scheme + Send + Sync>>> {
|
||||
pub fn iter(&self) -> ::alloc::collections::btree_map::Iter<SchemeId, Arc<Box<dyn Scheme + Send + Sync>>> {
|
||||
self.map.iter()
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ impl SchemeList {
|
||||
self.map.get(&id)
|
||||
}
|
||||
|
||||
pub fn get_name(&self, ns: SchemeNamespace, name: &[u8]) -> Option<(SchemeId, &Arc<Box<Scheme + Send + Sync>>)> {
|
||||
pub fn get_name(&self, ns: SchemeNamespace, name: &[u8]) -> Option<(SchemeId, &Arc<Box<dyn Scheme + Send + Sync>>)> {
|
||||
if let Some(names) = self.names.get(&ns) {
|
||||
if let Some(&id) = names.get(name) {
|
||||
return self.get(id).map(|scheme| (id, scheme));
|
||||
@@ -199,7 +199,7 @@ impl SchemeList {
|
||||
|
||||
/// Create a new scheme.
|
||||
pub fn insert<F>(&mut self, ns: SchemeNamespace, name: Box<[u8]>, scheme_fn: F) -> Result<SchemeId>
|
||||
where F: Fn(SchemeId) -> Arc<Box<Scheme + Send + Sync>>
|
||||
where F: Fn(SchemeId) -> Arc<Box<dyn Scheme + Send + Sync>>
|
||||
{
|
||||
if let Some(names) = self.names.get(&ns) {
|
||||
if names.contains_key(&name) {
|
||||
|
||||
@@ -27,7 +27,7 @@ struct Handle {
|
||||
seek: usize
|
||||
}
|
||||
|
||||
type SysFn = Fn() -> Result<Vec<u8>> + Send + Sync;
|
||||
type SysFn = dyn Fn() -> Result<Vec<u8>> + Send + Sync;
|
||||
|
||||
/// System information scheme
|
||||
pub struct SysScheme {
|
||||
|
||||
@@ -21,12 +21,13 @@ use crate::paging::{ActivePageTable, InactivePageTable, Page, VirtualAddress, PA
|
||||
use crate::{ptrace, syscall};
|
||||
use crate::scheme::FileHandle;
|
||||
use crate::start::usermode;
|
||||
use crate::syscall::data::{PtraceEvent, SigAction, Stat};
|
||||
use crate::syscall::data::{SigAction, Stat};
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::flag::{CloneFlags, CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND,
|
||||
CLONE_STACK, MapFlags, PROT_EXEC, PROT_READ, PROT_WRITE, PTRACE_EVENT_CLONE,
|
||||
SigActionFlags, SIG_DFL, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK, SIGCONT, SIGTERM,
|
||||
WaitFlags, WCONTINUED, WNOHANG, WUNTRACED, wifcontinued, wifstopped};
|
||||
PTRACE_STOP_EXIT, SigActionFlags, SIG_DFL, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK,
|
||||
SIGCONT, SIGTERM, WaitFlags, WCONTINUED, WNOHANG, WUNTRACED, wifcontinued,
|
||||
wifstopped};
|
||||
use crate::syscall::ptrace_event;
|
||||
use crate::syscall::validate::{validate_slice, validate_slice_mut};
|
||||
|
||||
@@ -1064,6 +1065,8 @@ pub fn exit(status: usize) -> ! {
|
||||
Arc::clone(&context_lock)
|
||||
};
|
||||
|
||||
ptrace::breakpoint_callback(PTRACE_STOP_EXIT, Some(ptrace_event!(PTRACE_STOP_EXIT, status)));
|
||||
|
||||
let mut close_files = Vec::new();
|
||||
let pid = {
|
||||
let mut context = context_lock.write();
|
||||
|
||||
2
syscall
2
syscall
Submodule syscall updated: 0e1e7d5d36...6ba71e7e06
Reference in New Issue
Block a user