diff --git a/src/acconfig.h b/src/acconfig.h index 7428fb4bed18e043138d5c7fe58d78b487b769e8..4a325585f2c113d13a9c71b8d26e3cd5b38b717f 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: acconfig.h,v 1.119 2003/02/27 12:36:26 mirar Exp $ +|| $Id: acconfig.h,v 1.120 2003/03/06 12:50:21 grubba Exp $ */ #ifndef MACHINE_H @@ -244,9 +244,12 @@ /* Define if you have ualarm. */ #undef HAVE_UALARM -/* Define if your ualarm takes two args.. */ +/* Define if your ualarm takes two args. */ #undef UALARM_TAKES_TWO_ARGS +/* Define if your ptrace takes four args. */ +#undef PTRACE_TAKES_FOUR_ARGS + /* Define if gettimeofday takes to arguments */ #undef GETTIMEOFDAY_TAKES_TWO_ARGS diff --git a/src/configure.in b/src/configure.in index a10bf4e77130793a5bb69c1f9d123611db643134..eacce4468c67b997bc3362d2383b45b1dbc0d07d 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,4 +1,4 @@ -AC_REVISION("$Id: configure.in,v 1.706 2003/03/05 16:18:30 mast Exp $") +AC_REVISION("$Id: configure.in,v 1.707 2003/03/06 12:50:21 grubba Exp $") AC_INIT(interpret.c) AC_CONFIG_HEADER(machine.h) @@ -3797,6 +3797,34 @@ if test "x$ac_cv_func_ualarm" = "xyes"; then fi fi +if test "x$ac_cv_func_ptrace" = "xyes"; then + AC_MSG_CHECKING(no of arguments to ptrace) + AC_CACHE_VAL(pike_cv_ptrace_takes_four_args, + [ + AC_TRY_COMPILE([ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif /* HAVE_SYS_TYPES_H */ +#ifdef HAVE_SYS_PTRACE_H +#include <sys/ptrace.h> +#endif /* HAVE_SYS_PTRACE_H */ + ],[ + ptrace(0,0,NULL,NULL); + ],pike_cv_ptrace_takes_four_args=yes,pike_cv_ptrace_takes_four_args=no) + ]) + if test "$pike_cv_ptrace_takes_four_args" = yes; then + AC_MSG_RESULT(4) + AC_DEFINE(PTRACE_TAKES_FOUR_ARGS) + else + AC_MSG_RESULT(5) + fi +fi + + + ######################################################################## AC_MSG_CHECKING(stack direction) AC_CACHE_VAL(pike_cv_hardware_stack_direction, diff --git a/src/signal_handler.c b/src/signal_handler.c index 540fcdf8594652cc10daa980f03e86f7818a97af..e10f75bcff8e8efb102ab64ecb0bfce974bc2802 100644 --- a/src/signal_handler.c +++ b/src/signal_handler.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: signal_handler.c,v 1.244 2003/03/03 12:43:56 grubba Exp $ +|| $Id: signal_handler.c,v 1.245 2003/03/06 12:50:22 grubba Exp $ */ #include "global.h" @@ -26,7 +26,7 @@ #include "main.h" #include <signal.h> -RCSID("$Id: signal_handler.c,v 1.244 2003/03/03 12:43:56 grubba Exp $"); +RCSID("$Id: signal_handler.c,v 1.245 2003/03/06 12:50:22 grubba Exp $"); #ifdef HAVE_PASSWD_H # include <passwd.h> @@ -101,6 +101,10 @@ RCSID("$Id: signal_handler.c,v 1.244 2003/03/03 12:43:56 grubba Exp $"); #include <sys/ptrace.h> #endif +#ifdef HAVE_SYS_USER_H +#include <sys/user.h> +#endif + #ifdef __amigaos__ #define timeval amigaos_timeval #include <exec/types.h> @@ -146,19 +150,56 @@ RCSID("$Id: signal_handler.c,v 1.244 2003/03/03 12:43:56 grubba Exp $"); #ifdef HAVE_PTRACE /* BSDs have different names for these constants... * - * And Solaris 2.x doesn't name them at all... + * ... and so does HPUX... + * + * And Solaris 2.9 and later don't name them at all... + * + * Requests 0 - 9 are standardized by AT&T/SVID as follows: + * + * PTRACE_TRACEME 0 Enter trace mode. Stop at exec() and signals. + * PTRACE_PEEKTEXT 1 Read a word from the text area. + * PTRACE_PEEKDATA 2 Read a word from the data area. + * PTRACE_PEEKUSER 3 Read a word from the user area. + * PTRACE_POKETEXT 4 Set a word in the text area. + * PTRACE_POKEDATA 5 Set a word in the data area. + * PTRACE_POKEUSER 6 Set a word in the user area. + * PTRACE_CONT 7 Continue process with specified signal. + * PTRACE_KILL 8 Exit process. + * PTRACE_SINGLESTEP 9 Execute a single instruction. + * + * NB: In Solaris 2.x ptrace() is simulated by libc. */ #ifndef PTRACE_TRACEME #ifdef PT_TRACE_ME +/* BSD */ #define PTRACE_TRACEME PT_TRACE_ME +#elif defined(PT_SETTRC) +/* HPUX */ +#define PTRACE_TRACEME PT_SETTRC #else #define PTRACE_TRACEME 0 #endif #endif +#ifndef PTRACE_PEEKUSER +#ifdef PT_READ_U +/* BSD */ +#define PTRACE_PEEKUSER PT_READ_U +#elif defined(PT_RUAREA) +/* HPUX */ +#define PTRACE_PEEKUSER PT_RUAREA +#else +#define PTRACE_PEEKUSER 3 +#endif +#endif + #ifndef PTRACE_CONT #ifdef PT_CONTINUE +/* BSD */ #define PTRACE_CONT PT_CONTINUE +#elif defined(PT_CONTIN) +/* HPUX */ +#define PTRACE_CONT PT_CONTIN #else #define PTRACE_CONT 7 #endif @@ -166,12 +207,20 @@ RCSID("$Id: signal_handler.c,v 1.244 2003/03/03 12:43:56 grubba Exp $"); #ifndef PTRACE_KILL #ifdef PT_KILL +/* BSD */ #define PTRACE_KILL PT_KILL +#elif defined(PT_EXIT) +#define PTRACE_KILL PT_EXIT #else #define PTRACE_KILL 8 #endif #endif +#ifndef PTRACE_TAKES_FOUR_ARGS +/* HPUX and SunOS 4 have a fifth argument "addr2". */ +#define ptrace(R,P,A,D) ptrace(R,P,A,D,NULL) +#endif + #endif /* HAVE_PTRACE */ /* Number of EBADF's before the set_close_on_exec() loop terminates. */ @@ -1631,7 +1680,8 @@ static void f_trace_process_cont(INT32 args) THIS->state = PROCESS_RUNNING; - if (ptrace(PTRACE_CONT, THIS->pid, NULL, cont_signal) == -1) { + /* The addr argument must be 1 for this request. */ + if (ptrace(PTRACE_CONT, THIS->pid, (void *)(ptrdiff_t)1, cont_signal) == -1) { int err = errno; THIS->state = PROCESS_STOPPED; /* FIXME: Better diagnostics. */ @@ -1675,6 +1725,67 @@ static void f_trace_process_exit(INT32 args) push_int(0); } +#if 0 /* Disabled for now. */ + +/*! @class Registers + *! Interface to the current register contents of + *! a stopped process. + *! + *! @seealso + *! @[TraceProcess] + */ + +/* NB: No storage needed, all state is in the parent object. */ + +#define THIS_PROC_REG_PROC_ID ((struct pid_status *)parent_storage(1)) + +/*! @decl int `[](int regno) + *! Get the contents of register @[regno]. + */ +static void f_proc_reg_index(INT32 args) +{ + struct pid_status *proc = THIS_PROC_REG_PROC_ID; + INT32 regno = 0; + long val; + +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + Pike_error("`[](): permission denied.\n"); +#endif + if(proc->pid == -1) + Pike_error("This process object has no process associated with it.\n"); + + if (proc->state != PROCESS_STOPPED) { + if (proc->state == PROCESS_EXITED) { + Pike_error("Process has exited.\n"); + } + Pike_error("Process not stopped.\n"); + } + + get_all_args("`[]", args, "%i", ®no); + + if ((regno < 0) || + (regno * sizeof(long) > sizeof(((struct user *)NULL)->regs))) { + SIMPLE_BAD_ARG_ERROR("`[]", 1, "register number"); + } + + if ((val = ptrace(PTRACE_PEEKUSER, proc->pid, + ((long *)(((struct user *)0)->regs)) + regno, 0)) == -1) { + int err = errno; + /* FIXME: Better diagnostics. */ + if (errno) { + Pike_error("Failed to exit process. errno:%d\n", err); + } + } + pop_n_elems(args); + push_int64(val); +} + +/*! @endclass + */ + +#endif /* 0 */ + /*! @endclass */ @@ -1886,7 +1997,6 @@ extern int pike_make_pipe(int *); #define PROCE_DUP 10 #define PROCE_SETSID 11 #define PROCE_SETCTTY 12 -#define PROCE_PTRACE 13 #define PROCERROR(err, id) do { int _l, _i; \ buf[0] = err; buf[1] = errno; buf[2] = id; \ @@ -2343,9 +2453,6 @@ static void internal_add_limit( struct perishables *storage, *! The modifiers @tt{"fds"@}, @tt{"uid"@}, @tt{"gid"@}, @tt{"nice"@}, *! @tt{"noinitgroups"@}, @tt{"setgroups"@}, @tt{"keep_signals"@} *! and @tt{"rlimit"@} only exist on unix. - *! - *! The modifier @tt{"trace"@} currently only exists on OS's that - *! implement @tt{ptrace()@}. */ /*! @endclass */ @@ -3362,9 +3469,6 @@ void f_create_process(INT32 args) case PROCE_SETCTTY: Pike_error("Process.create_process(): failed to set controlling TTY. errno:%d\n", buf[1]); break; - case PROCE_PTRACE: - Pike_error("Process.TraceProcess(): failed to enter trace mode. errno:%d\n", buf[1]); - break; case PROCE_EXEC: switch(buf[1]) { case ENOENT: @@ -3691,10 +3795,8 @@ void f_create_process(INT32 args) #ifdef HAVE_PTRACE if (do_trace) { - long code = ptrace(PTRACE_TRACEME, 0, NULL, NULL); - if (code == -1) { - PROCERROR(PROCE_PTRACE, 0); - } + /* NB: A return value is not defined for this ptrace request! */ + ptrace(PTRACE_TRACEME, 0, NULL, NULL); } #endif /* HAVE_PTRACE */ @@ -4422,6 +4524,15 @@ void init_signals(void) ADD_FUNCTION("exit", f_trace_process_exit, tFunc(tNone, tVoid), 0); +#if 0 /* Disabled for now. */ + + start_new_program(); + Pike_compiler->new_program->flags |= PROGRAM_USES_PARENT; + ADD_FUNCTION("`[]", f_proc_reg_index, tFunc(tMix, tInt), ID_STATIC); + end_class("Registers", 0); + +#endif /* 0 */ + end_class("TraceProcess", 0); #endif /* HAVE_PTRACE */ @@ -4467,7 +4578,7 @@ void init_signals(void) void exit_signals(void) { int e; -#ifndef __NT__ +#ifdef USE_PID_MAPPING if(pid_mapping) { free_mapping(pid_mapping);