Merge of David's ptrace branch. Summary:
o Support for ptrace T_ATTACH/T_DETACH and T_SYSCALL o PM signal handling logic should now work properly, even with debuggers being present o Asynchronous PM/VFS protocol, full IPC support for senda(), and AMF_NOREPLY senda() flag DETAILS Process stop and delay call handling of PM: o Added sys_runctl() kernel call with sys_stop() and sys_resume() aliases, for PM to stop and resume a process o Added exception for sending/syscall-traced processes to sys_runctl(), and matching SIGKREADY pseudo-signal to PM o Fixed PM signal logic to deal with requests from a process after stopping it (so-called "delay calls"), using the SIGKREADY facility o Fixed various PM panics due to race conditions with delay calls versus VFS calls o Removed special PRIO_STOP priority value o Added SYS_LOCK RTS kernel flag, to stop an individual process from running while modifying its process structure Signal and debugger handling in PM: o Fixed debugger signals being dropped if a second signal arrives when the debugger has not retrieved the first one o Fixed debugger signals being sent to the debugger more than once o Fixed debugger signals unpausing process in VFS; removed PM_UNPAUSE_TR protocol message o Detached debugger signals from general signal logic and from being blocked on VFS calls, meaning that even VFS can now be traced o Fixed debugger being unable to receive more than one pending signal in one process stop o Fixed signal delivery being delayed needlessly when multiple signals are pending o Fixed wait test for tracer, which was returning for children that were not waited for o Removed second parallel pending call from PM to VFS for any process o Fixed process becoming runnable between exec() and debugger trap o Added support for notifying the debugger before the parent when a debugged child exits o Fixed debugger death causing child to remain stopped forever o Fixed consistently incorrect use of _NSIG Extensions to ptrace(): o Added T_ATTACH and T_DETACH ptrace request, to attach and detach a debugger to and from a process o Added T_SYSCALL ptrace request, to trace system calls o Added T_SETOPT ptrace request, to set trace options o Added TO_TRACEFORK trace option, to attach automatically to children of a traced process o Added TO_ALTEXEC trace option, to send SIGSTOP instead of SIGTRAP upon a successful exec() of the tracee o Extended T_GETUSER ptrace support to allow retrieving a process's priv structure o Removed T_STOP ptrace request again, as it does not help implementing debuggers properly o Added MINIX3-specific ptrace test (test42) o Added proper manual page for ptrace(2) Asynchronous PM/VFS interface: o Fixed asynchronous messages not being checked when receive() is called with an endpoint other than ANY o Added AMF_NOREPLY senda() flag, preventing such messages from satisfying the receive part of a sendrec() o Added asynsend3() that takes optional flags; asynsend() is now a #define passing in 0 as third parameter o Made PM/VFS protocol asynchronous; reintroduced tell_fs() o Made PM_BASE request/reply number range unique o Hacked in a horrible temporary workaround into RS to deal with newly revealed RS-PM-VFS race condition triangle until VFS is asynchronous System signal handling: o Fixed shutdown logic of device drivers; removed old SIGKSTOP signal o Removed is-superuser check from PM's do_procstat() (aka getsigset()) o Added sigset macros to allow system processes to deal with the full signal set, rather than just the POSIX subset Miscellaneous PM fixes: o Split do_getset into do_get and do_set, merging common code and making structure clearer o Fixed setpriority() being able to put to sleep processes using an invalid parameter, or revive zombie processes o Made find_proc() global; removed obsolete proc_from_pid() o Cleanup here and there Also included: o Fixed false-positive boot order kernel warning o Removed last traces of old NOTIFY_FROM code THINGS OF POSSIBLE INTEREST o It should now be possible to run PM at any priority, even lower than user processes o No assumptions are made about communication speed between PM and VFS, although communication must be FIFO o A debugger will now receive incoming debuggee signals at kill time only; the process may not yet be fully stopped o A first step has been made towards making the SYSTEM task preemptible
This commit is contained in:
@@ -64,20 +64,10 @@
|
||||
/* FIXME will be is_notify(a) ((a) == NOTIFY_MESSAGE) */
|
||||
#define is_notify(a) ((a) & NOTIFY_MESSAGE)
|
||||
#define NOTIFY_FROM(p_nr) (NOTIFY_MESSAGE | ((p_nr) + NR_TASKS))
|
||||
# define PROC_EVENT NOTIFY_FROM(PM_PROC_NR) /* process status change */
|
||||
# define SYN_ALARM NOTIFY_FROM(CLOCK) /* synchronous alarm */
|
||||
# define SYS_SIG NOTIFY_FROM(SYSTEM) /* system signal */
|
||||
# define HARD_INT NOTIFY_FROM(HARDWARE) /* hardware interrupt */
|
||||
# define FKEY_PRESSED NOTIFY_FROM(TTY_PROC_NR)/* function key press */
|
||||
# define DEV_PING NOTIFY_FROM(RS_PROC_NR) /* driver liveness ping */
|
||||
# define DS_UPDATE NOTIFY_FROM(DS_PROC_NR) /* subscription update */
|
||||
|
||||
/* Shorthands for message parameters passed with notifications. */
|
||||
#define NOTIFY_SOURCE m_source
|
||||
#define NOTIFY_TYPE m_type
|
||||
#define NOTIFY_ARG m2_l1
|
||||
#define NOTIFY_TIMESTAMP m2_l2
|
||||
#define NOTIFY_FLAGS m2_i1
|
||||
|
||||
/*===========================================================================*
|
||||
* Messages for BUS controller drivers *
|
||||
@@ -330,8 +320,9 @@
|
||||
# define SYS_SYSCTL (KERNEL_CALL + 44) /* sys_sysctl() */
|
||||
|
||||
# define SYS_VTIMER (KERNEL_CALL + 45) /* sys_vtimer() */
|
||||
# define SYS_RUNCTL (KERNEL_CALL + 46) /* sys_runctl() */
|
||||
|
||||
#define NR_SYS_CALLS 46 /* number of system calls */
|
||||
#define NR_SYS_CALLS 47 /* number of system calls */
|
||||
|
||||
/* Pseudo call for use in kernel/table.c. */
|
||||
#define SYS_ALL_CALLS (NR_SYS_CALLS)
|
||||
@@ -621,6 +612,12 @@
|
||||
#define VT_VALUE m2_l1 /* new/previous value of the timer */
|
||||
#define VT_ENDPT m2_l2 /* process to set/retrieve the timer for */
|
||||
|
||||
/* Field names for SYS_RUNCTL. */
|
||||
#define RC_ENDPT m1_i1 /* which process to stop or resume */
|
||||
#define RC_ACTION m1_i2 /* set or clear stop flag */
|
||||
# define RC_STOP 0 /* stop the process, unless delaying */
|
||||
# define RC_RESUME 1 /* clear the stop flag */
|
||||
|
||||
/*===========================================================================*
|
||||
* Messages for the Reincarnation Server *
|
||||
*===========================================================================*/
|
||||
@@ -696,52 +693,57 @@
|
||||
|
||||
#define DIAG_REPL_OLD (DIAG_BASE+0x80+0) /* reply to DIAGNOSTICS(_S) */
|
||||
|
||||
#define PM_BASE 0x900
|
||||
#define PM_GET_WORK (PM_BASE + 1) /* Get work from PM */
|
||||
#define PM_IDLE (PM_BASE + 2) /* PM doesn't have any more work */
|
||||
#define PM_BUSY (PM_BASE + 3) /* A reply from FS is needed */
|
||||
#define PM_SETSID (PM_BASE + 5) /* Tell FS about the session leader */
|
||||
#define PM_SETSID_PROC m1_i1 /* process */
|
||||
#define PM_SETGID (PM_BASE + 6) /* Tell FS about the new group IDs */
|
||||
#define PM_SETGID_PROC m1_i1 /* process */
|
||||
#define PM_SETGID_EGID m1_i2 /* effective group id */
|
||||
#define PM_SETGID_RGID m1_i3 /* real group id */
|
||||
#define PM_SETUID (PM_BASE + 7) /* Tell FS about the new user IDs */
|
||||
#define PM_SETUID_PROC m1_i1 /* process */
|
||||
#define PM_SETUID_EGID m1_i2 /* effective user id */
|
||||
#define PM_SETUID_RGID m1_i3 /* real user id */
|
||||
#define PM_FORK (PM_BASE + 8) /* Tell FS about the new process */
|
||||
#define PM_FORK_PPROC m1_i1 /* parent process */
|
||||
#define PM_FORK_CPROC m1_i2 /* child process */
|
||||
#define PM_FORK_CPID m1_i3 /* child pid */
|
||||
#define PM_EXIT (PM_BASE + 9) /* Tell FS about the exiting process */
|
||||
#define PM_EXIT_PROC m1_i1 /* process */
|
||||
#define PM_UNPAUSE (PM_BASE + 10) /* interrupted process */
|
||||
#define PM_UNPAUSE_PROC m1_i1 /* process */
|
||||
#define PM_REBOOT (PM_BASE + 11) /* Tell FS that we about to reboot */
|
||||
#define PM_EXEC (PM_BASE + 12) /* Forward exec call to FS */
|
||||
#define PM_EXEC_PROC m1_i1 /* process */
|
||||
#define PM_EXEC_PATH m1_p1 /* executable */
|
||||
#define PM_EXEC_PATH_LEN m1_i2 /* length of path including
|
||||
* terminating nul
|
||||
*/
|
||||
#define PM_EXEC_FRAME m1_p2 /* arguments and environment */
|
||||
#define PM_EXEC_FRAME_LEN m1_i3 /* size of frame */
|
||||
#define PM_FORK_NB (PM_BASE + 13) /* Tell FS about the fork_nb call */
|
||||
#define PM_DUMPCORE (PM_BASE + 14) /* Ask FS to generate a core dump */
|
||||
#define PM_CORE_PROC m1_i1
|
||||
#define PM_CORE_SEGPTR m1_p1
|
||||
#define PM_UNPAUSE_TR (PM_BASE + 15) /* interrupted process (for tracing) */
|
||||
/*===========================================================================*
|
||||
* Messages used between PM and VFS *
|
||||
*===========================================================================*/
|
||||
|
||||
/* Replies */
|
||||
#define PM_EXIT_REPLY (PM_BASE + 20) /* Reply from FS */
|
||||
#define PM_REBOOT_REPLY (PM_BASE + 21) /* Reply from FS */
|
||||
#define PM_EXEC_REPLY (PM_BASE + 22) /* Reply from FS */
|
||||
/* PM_EXEC_PROC m1_i1 */
|
||||
#define PM_EXEC_STATUS m1_i2 /* OK or failure */
|
||||
#define PM_CORE_REPLY (PM_BASE + 23) /* Reply from FS */
|
||||
/* PM_CORE_PROC m1_i1 */
|
||||
#define PM_CORE_STATUS m1_i2 /* OK or failure */
|
||||
#define PM_BASE 0xE00
|
||||
|
||||
/* Requests from PM to VFS */
|
||||
#define PM_SETUID (PM_BASE + 1) /* Tell FS about the new user IDs */
|
||||
#define PM_SETGID (PM_BASE + 2) /* Tell FS about the new group IDs */
|
||||
#define PM_SETSID (PM_BASE + 3) /* Tell FS about the session leader */
|
||||
#define PM_EXIT (PM_BASE + 4) /* Tell FS about the exiting process */
|
||||
#define PM_DUMPCORE (PM_BASE + 5) /* Ask FS to generate a core dump */
|
||||
#define PM_EXEC (PM_BASE + 6) /* Forward exec call to FS */
|
||||
#define PM_FORK (PM_BASE + 7) /* Tell FS about the new process */
|
||||
#define PM_FORK_NB (PM_BASE + 8) /* Tell FS about the fork_nb call */
|
||||
#define PM_UNPAUSE (PM_BASE + 9) /* interrupted process */
|
||||
#define PM_REBOOT (PM_BASE + 10) /* Tell FS that we about to reboot */
|
||||
|
||||
/* Replies from VFS to PM */
|
||||
#define PM_SETUID_REPLY (PM_BASE + 21)
|
||||
#define PM_SETGID_REPLY (PM_BASE + 22)
|
||||
#define PM_SETSID_REPLY (PM_BASE + 23)
|
||||
#define PM_EXIT_REPLY (PM_BASE + 24)
|
||||
#define PM_CORE_REPLY (PM_BASE + 25)
|
||||
#define PM_EXEC_REPLY (PM_BASE + 26)
|
||||
#define PM_FORK_REPLY (PM_BASE + 27)
|
||||
#define PM_FORK_NB_REPLY (PM_BASE + 28)
|
||||
#define PM_UNPAUSE_REPLY (PM_BASE + 29)
|
||||
#define PM_REBOOT_REPLY (PM_BASE + 30)
|
||||
|
||||
/* Standard parameters for all requests and replies, except PM_REBOOT */
|
||||
# define PM_PROC m1_i1 /* process */
|
||||
|
||||
/* Additional parameters for PM_SETUID and PM_SETGID */
|
||||
# define PM_EID m1_i2 /* effective user/group id */
|
||||
# define PM_RID m1_i3 /* real user/group id */
|
||||
|
||||
/* Additional parameters for PM_EXEC */
|
||||
# define PM_PATH m1_p1 /* executable */
|
||||
# define PM_PATH_LEN m1_i2 /* length of path including
|
||||
* terminating nul
|
||||
*/
|
||||
# define PM_FRAME m1_p2 /* arguments and environment */
|
||||
# define PM_FRAME_LEN m1_i3 /* size of frame */
|
||||
|
||||
/* Additional parameters for PM_EXEC_REPLY and PM_CORE_REPLY */
|
||||
# define PM_STATUS m1_i2 /* OK or failure */
|
||||
|
||||
/* Additional parameters for PM_FORK and PM_FORK_NB */
|
||||
# define PM_PPROC m1_i2 /* parent process */
|
||||
# define PM_CPID m1_i3 /* child pid */
|
||||
|
||||
/* Parameters for the EXEC_NEWMEM call */
|
||||
#define EXC_NM_PROC m1_i1 /* process that needs new map */
|
||||
|
||||
@@ -133,6 +133,7 @@ typedef struct asynmsg
|
||||
* result is stored in 'result'
|
||||
*/
|
||||
#define AMF_NOTIFY 4 /* Send a notification when AMF_DONE is set */
|
||||
#define AMF_NOREPLY 8 /* Not a reply message for a SENDREC */
|
||||
|
||||
/* Hide names to avoid name space pollution. */
|
||||
#define echo _echo
|
||||
|
||||
@@ -40,6 +40,11 @@ _PROTOTYPE( int sys_newmap, (endpoint_t proc_ep, struct mem_map *ptr));
|
||||
_PROTOTYPE( int sys_exit, (endpoint_t proc_ep));
|
||||
_PROTOTYPE( int sys_trace, (int req, endpoint_t proc_ep, long addr, long *data_p));
|
||||
|
||||
/* Shorthands for sys_runctl() system call. */
|
||||
#define sys_stop(proc_ep) sys_runctl(proc_ep, RC_STOP)
|
||||
#define sys_resume(proc_ep) sys_runctl(proc_ep, RC_RESUME)
|
||||
_PROTOTYPE( int sys_runctl, (endpoint_t proc_ep, int action));
|
||||
|
||||
_PROTOTYPE( int sys_privctl, (endpoint_t proc_ep, int req, void *p));
|
||||
_PROTOTYPE( int sys_setgrant, (cp_grant_t *grants, int ngrants));
|
||||
_PROTOTYPE( int sys_nice, (endpoint_t proc_ep, int priority));
|
||||
|
||||
@@ -56,10 +56,11 @@ _PROTOTYPE( void util_nstrcat, (char *str, unsigned long n) );
|
||||
_PROTOTYPE( void util_stacktrace_strcat, (char *));
|
||||
_PROTOTYPE( int micro_delay, (u32_t micros));
|
||||
_PROTOTYPE( u32_t micros_to_ticks, (u32_t micros));
|
||||
_PROTOTYPE( int asynsend, (endpoint_t ep, message *msg));
|
||||
_PROTOTYPE( void ser_putc, (char c));
|
||||
_PROTOTYPE( void get_randomness, (struct k_randomness *, int));
|
||||
|
||||
#define asynsend(ep, msg) asynsend3(ep, msg, 0)
|
||||
_PROTOTYPE( int asynsend3, (endpoint_t ep, message *msg, int flags));
|
||||
|
||||
#define ASSERT(c) if(!(c)) { panic(__FILE__, "assert " #c " failed at line", __LINE__); }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
_PROTOTYPE( int vm_exit, (endpoint_t ep));
|
||||
_PROTOTYPE( int vm_fork, (endpoint_t ep, int slotno, int *child_ep));
|
||||
_PROTOTYPE( int vm_fork, (endpoint_t ep, int slotno, endpoint_t *child_ep));
|
||||
_PROTOTYPE( int vm_brk, (endpoint_t ep, char *newaddr));
|
||||
_PROTOTYPE( int vm_exec_newmem, (endpoint_t ep, struct exec_newmem *args,
|
||||
int args_bytes, char **ret_stack_top, int *ret_flags));
|
||||
|
||||
@@ -66,7 +66,7 @@ typedef unsigned long sigset_t;
|
||||
*/
|
||||
#define SIGKMESS 29 /* new kernel message */
|
||||
#define SIGKSIG 30 /* kernel signal pending */
|
||||
#define SIGKSTOP 31 /* kernel shutting down */
|
||||
#define SIGKREADY 31 /* ready for signal delivery */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -113,15 +113,29 @@ _PROTOTYPE( int kill, (pid_t _pid, int _sig) );
|
||||
_PROTOTYPE( int killpg, (pid_t _pgrp, int _sig) );
|
||||
_PROTOTYPE( int sigaction,
|
||||
(int _sig, const struct sigaction *_act, struct sigaction *_oact) );
|
||||
_PROTOTYPE( int sigpending, (sigset_t *_set) );
|
||||
_PROTOTYPE( int sigprocmask,
|
||||
(int _how, const sigset_t *_set, sigset_t *_oset) );
|
||||
_PROTOTYPE( int sigsuspend, (const sigset_t *_sigmask) );
|
||||
|
||||
/* For the sigset functions, only use the library version with error
|
||||
* checking from user programs. System programs need to be able to use
|
||||
* nonstanard signals.
|
||||
*/
|
||||
#ifndef _SYSTEM
|
||||
_PROTOTYPE( int sigaddset, (sigset_t *_set, int _sig) );
|
||||
_PROTOTYPE( int sigdelset, (sigset_t *_set, int _sig) );
|
||||
_PROTOTYPE( int sigemptyset, (sigset_t *_set) );
|
||||
_PROTOTYPE( int sigfillset, (sigset_t *_set) );
|
||||
_PROTOTYPE( int sigismember, (const sigset_t *_set, int _sig) );
|
||||
_PROTOTYPE( int sigpending, (sigset_t *_set) );
|
||||
_PROTOTYPE( int sigprocmask,
|
||||
(int _how, const sigset_t *_set, sigset_t *_oset) );
|
||||
_PROTOTYPE( int sigsuspend, (const sigset_t *_sigmask) );
|
||||
#else
|
||||
#define sigaddset(set, sig) ((int) ((*(set) |= (1 << (sig))) && 0))
|
||||
#define sigdelset(set, sig) ((int) ((*(set) &= ~(1 << (sig))) && 0))
|
||||
#define sigemptyset(set) ((int) (*(set) = 0))
|
||||
#define sigfillset(set) ((int) ((*(set) = ~0) && 0))
|
||||
#define sigismember(set, sig) ((*(set) & (1 << (sig))) ? 1 : 0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SIGNAL_H */
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef _PTRACE_H
|
||||
#define _PTRACE_H
|
||||
|
||||
/* Trace requests. */
|
||||
#define T_STOP -1 /* stop the process */
|
||||
#define T_OK 0 /* enable tracing by parent for this process */
|
||||
#define T_GETINS 1 /* return value from instruction space */
|
||||
@@ -16,6 +17,10 @@
|
||||
#define T_RESUME 7 /* resume execution */
|
||||
#define T_EXIT 8 /* exit */
|
||||
#define T_STEP 9 /* set trace bit */
|
||||
#define T_SYSCALL 10 /* trace system call */
|
||||
#define T_ATTACH 11 /* attach to a running process */
|
||||
#define T_DETACH 12 /* detach from a traced process */
|
||||
#define T_SETOPT 13 /* set trace options */
|
||||
|
||||
#define T_READB_INS 100 /* Read a byte from the text segment of an
|
||||
* untraced process (only for root)
|
||||
@@ -24,6 +29,10 @@
|
||||
* untraced process (only for root)
|
||||
*/
|
||||
|
||||
/* Trace options. */
|
||||
#define TO_TRACEFORK 0x1 /* automatically attach to forked children */
|
||||
#define TO_ALTEXEC 0x2 /* send SIGSTOP on successful exec() */
|
||||
|
||||
/* Function Prototypes. */
|
||||
#ifndef _ANSI_H
|
||||
#include <ansi.h>
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
#define PRIO_MIN -20
|
||||
#define PRIO_MAX 20
|
||||
|
||||
/* Magic, invalid priority to stop the process. */
|
||||
#define PRIO_STOP 76
|
||||
|
||||
#define PRIO_PROCESS 0
|
||||
#define PRIO_PGRP 1
|
||||
#define PRIO_USER 2
|
||||
|
||||
Reference in New Issue
Block a user