int syscall_entering_trace(struct tcb *tcp, unsigned int *sig) { /* Restrain from fault injection while the trace executes strace code. */ if (hide_log(tcp)) { tcp->qual_flg &= ~QUAL_INJECT; } switch (tcp->s_ent->sen) { case SEN_execve: case SEN_execveat: #if defined SPARC || defined SPARC64 case SEN_execv: #endif tcp->flags &= ~TCB_HIDE_LOG; break; } if (!traced(tcp) || (tracing_paths && !pathtrace_match(tcp))) { tcp->flags |= TCB_FILTERED; return 0; } tcp->flags &= ~TCB_FILTERED; if (hide_log(tcp)) { return 0; } if (inject(tcp)) tamper_with_syscall_entering(tcp, sig); if (cflag == CFLAG_ONLY_STATS) { return 0; } #ifdef USE_LIBUNWIND if (stack_trace_enabled) { if (tcp->s_ent->sys_flags & STACKTRACE_CAPTURE_ON_ENTER) unwind_capture_stacktrace(tcp); } #endif printleader(tcp); tprintf("%s(", tcp->s_ent->sys_name); int res = raw(tcp) ? printargs(tcp) : tcp->s_ent->sys_func(tcp); fflush(tcp->outf); return res; }
void menu_main(){ switch(current_function)//get current function and make decision based on it { case 0: //function 0 log if(!isShowingLog) show_log(); //if the log isnt showing show it if(nNxtButtonPressed == 2){ //if we are pressing left while(nNxtButtonPressed == 2); //must click and release to scroll another line scroll_down(); } if(nNxtButtonPressed == 1){ //if we are pressing right while(nNxtButtonPressed==1); //must click and release to scroll another line scroll_up(); } break; case 1: //function 1 menu display_menu(); break; } if(nNxtButtonPressed==3 && current_function!=1){ //if we press enter and are not on menu while(nNxtButtonPressed==3); //dont allow double reads. you have to release before anything happens hide_log(); //hide the menu. cant hurt previous_function=current_function; //save the old function number current_function=1; //set the current function to menu } }
/* Returns: * 0: "bail out". * 1: ok. * -1: error in one of ptrace ops. * * If not 0, call syscall_exiting_trace(tcp, res), where res is the return * value. Anyway, call syscall_exiting_finish(tcp) then. */ int syscall_exiting_decode(struct tcb *tcp, struct timeval *ptv) { /* Measure the exit time as early as possible to avoid errors. */ if ((Tflag || cflag) && !(filtered(tcp) || hide_log(tcp))) gettimeofday(ptv, NULL); #ifdef USE_LIBUNWIND if (stack_trace_enabled) { if (tcp->s_ent->sys_flags & STACKTRACE_INVALIDATE_CACHE) unwind_cache_invalidate(tcp); } #endif if (filtered(tcp) || hide_log(tcp)) return 0; get_regs(tcp->pid); #if SUPPORTED_PERSONALITIES > 1 update_personality(tcp, tcp->currpers); #endif return get_regs_error ? -1 : get_syscall_result(tcp); }
static int trace_syscall_exiting(struct tcb *tcp) { int sys_res; struct timeval tv; int res; unsigned long u_error; const char *u_error_str; /* Measure the exit time as early as possible to avoid errors. */ if (Tflag || cflag) gettimeofday(&tv, NULL); #ifdef USE_LIBUNWIND if (stack_trace_enabled) { if (tcp->s_ent->sys_flags & STACKTRACE_INVALIDATE_CACHE) unwind_cache_invalidate(tcp); } #endif #if SUPPORTED_PERSONALITIES > 1 update_personality(tcp, tcp->currpers); #endif res = (get_regs_error ? -1 : get_syscall_result(tcp)); if (filtered(tcp) || hide_log(tcp)) goto ret; if (syserror(tcp) && syscall_fault_injected(tcp)) update_syscall_fault_exiting(tcp); if (cflag) { count_syscall(tcp, &tv); if (cflag == CFLAG_ONLY_STATS) { goto ret; } } /* If not in -ff mode, and printing_tcp != tcp, * then the log currently does not end with output * of _our syscall entry_, but with something else. * We need to say which syscall's return is this. * * Forced reprinting via TCB_REPRINT is used only by * "strace -ff -oLOG test/threaded_execve" corner case. * It's the only case when -ff mode needs reprinting. */ if ((followfork < 2 && printing_tcp != tcp) || (tcp->flags & TCB_REPRINT)) { tcp->flags &= ~TCB_REPRINT; printleader(tcp); tprintf("<... %s resumed> ", tcp->s_ent->sys_name); } printing_tcp = tcp; tcp->s_prev_ent = NULL; if (res != 1) { /* There was error in one of prior ptrace ops */ tprints(") "); tabto(); tprints("= ? <unavailable>\n"); line_ended(); tcp->flags &= ~(TCB_INSYSCALL | TCB_FAULT_INJ); tcp->sys_func_rval = 0; free_tcb_priv_data(tcp); return res; } tcp->s_prev_ent = tcp->s_ent; sys_res = 0; if (tcp->qual_flg & QUAL_RAW) { /* sys_res = printargs(tcp); - but it's nop on sysexit */ } else { /* FIXME: not_failing_only (IOW, option -z) is broken: * failure of syscall is known only after syscall return. * Thus we end up with something like this on, say, ENOENT: * open("doesnt_exist", O_RDONLY <unfinished ...> * {next syscall decode} * whereas the intended result is that open(...) line * is not shown at all. */ if (not_failing_only && tcp->u_error) goto ret; /* ignore failed syscalls */ if (tcp->sys_func_rval & RVAL_DECODED) sys_res = tcp->sys_func_rval; else sys_res = tcp->s_ent->sys_func(tcp); } tprints(") "); tabto(); u_error = tcp->u_error; if (tcp->qual_flg & QUAL_RAW) { if (u_error) { tprintf("= -1 (errno %lu)", u_error); if (syscall_fault_injected(tcp)) tprints(" (INJECTED)"); } else { tprintf("= %#" PRI_klx, tcp->u_rval); } } else if (!(sys_res & RVAL_NONE) && u_error) { switch (u_error) { /* Blocked signals do not interrupt any syscalls. * In this case syscalls don't return ERESTARTfoo codes. * * Deadly signals set to SIG_DFL interrupt syscalls * and kill the process regardless of which of the codes below * is returned by the interrupted syscall. * In some cases, kernel forces a kernel-generated deadly * signal to be unblocked and set to SIG_DFL (and thus cause * death) if it is blocked or SIG_IGNed: for example, SIGSEGV * or SIGILL. (The alternative is to leave process spinning * forever on the faulty instruction - not useful). * * SIG_IGNed signals and non-deadly signals set to SIG_DFL * (for example, SIGCHLD, SIGWINCH) interrupt syscalls, * but kernel will always restart them. */ case ERESTARTSYS: /* Most common type of signal-interrupted syscall exit code. * The system call will be restarted with the same arguments * if SA_RESTART is set; otherwise, it will fail with EINTR. */ tprints("= ? ERESTARTSYS (To be restarted if SA_RESTART is set)"); break; case ERESTARTNOINTR: /* Rare. For example, fork() returns this if interrupted. * SA_RESTART is ignored (assumed set): the restart is unconditional. */ tprints("= ? ERESTARTNOINTR (To be restarted)"); break; case ERESTARTNOHAND: /* pause(), rt_sigsuspend() etc use this code. * SA_RESTART is ignored (assumed not set): * syscall won't restart (will return EINTR instead) * even after signal with SA_RESTART set. However, * after SIG_IGN or SIG_DFL signal it will restart * (thus the name "restart only if has no handler"). */ tprints("= ? ERESTARTNOHAND (To be restarted if no handler)"); break; case ERESTART_RESTARTBLOCK: /* Syscalls like nanosleep(), poll() which can't be * restarted with their original arguments use this * code. Kernel will execute restart_syscall() instead, * which changes arguments before restarting syscall. * SA_RESTART is ignored (assumed not set) similarly * to ERESTARTNOHAND. (Kernel can't honor SA_RESTART * since restart data is saved in "restart block" * in task struct, and if signal handler uses a syscall * which in turn saves another such restart block, * old data is lost and restart becomes impossible) */ tprints("= ? ERESTART_RESTARTBLOCK (Interrupted by signal)"); break; default: u_error_str = err_name(u_error); if (u_error_str) tprintf("= -1 %s (%s)", u_error_str, strerror(u_error)); else tprintf("= -1 %lu (%s)", u_error, strerror(u_error)); break; } if (syscall_fault_injected(tcp)) tprintf(" (INJECTED)"); if ((sys_res & RVAL_STR) && tcp->auxstr) tprintf(" (%s)", tcp->auxstr); } else { if (sys_res & RVAL_NONE) tprints("= ?"); else { switch (sys_res & RVAL_MASK) { case RVAL_HEX: #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG if (current_wordsize < sizeof(tcp->u_rval)) { tprintf("= %#x", (unsigned int) tcp->u_rval); } else #endif { tprintf("= %#" PRI_klx, tcp->u_rval); } break; case RVAL_OCTAL: tprints("= "); print_numeric_long_umask(tcp->u_rval); break; case RVAL_UDECIMAL: #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG if (current_wordsize < sizeof(tcp->u_rval)) { tprintf("= %u", (unsigned int) tcp->u_rval); } else #endif { tprintf("= %" PRI_klu, tcp->u_rval); } break; case RVAL_DECIMAL: tprintf("= %" PRI_kld, tcp->u_rval); break; case RVAL_FD: if (show_fd_path) { tprints("= "); printfd(tcp, tcp->u_rval); } else tprintf("= %" PRI_kld, tcp->u_rval); break; default: error_msg("invalid rval format"); break; } } if ((sys_res & RVAL_STR) && tcp->auxstr) tprintf(" (%s)", tcp->auxstr); } if (Tflag) { tv_sub(&tv, &tv, &tcp->etime); tprintf(" <%ld.%06ld>", (long) tv.tv_sec, (long) tv.tv_usec); } tprints("\n"); dumpio(tcp); line_ended(); #ifdef USE_LIBUNWIND if (stack_trace_enabled) unwind_print_stacktrace(tcp); #endif ret: tcp->flags &= ~(TCB_INSYSCALL | TCB_FAULT_INJ); tcp->sys_func_rval = 0; free_tcb_priv_data(tcp); return 0; }
static int trace_syscall_entering(struct tcb *tcp, unsigned int *sig) { int res, scno_good; scno_good = res = get_scno(tcp); if (res == 0) return res; if (res == 1) res = get_syscall_args(tcp); if (res != 1) { printleader(tcp); tprintf("%s(", scno_good == 1 ? tcp->s_ent->sys_name : "????"); /* * " <unavailable>" will be added later by the code which * detects ptrace errors. */ goto ret; } #ifdef LINUX_MIPSO32 if (SEN_syscall == tcp->s_ent->sen) decode_mips_subcall(tcp); #endif #if defined(SYS_socket_subcall) || defined(SYS_ipc_subcall) switch (tcp->s_ent->sen) { # ifdef SYS_socket_subcall case SEN_socketcall: decode_socket_subcall(tcp); break; # endif # ifdef SYS_ipc_subcall case SEN_ipc: decode_ipc_subcall(tcp); break; # endif } #endif /* Restrain from fault injection while the trace executes strace code. */ if (hide_log(tcp)) { tcp->qual_flg &= ~QUAL_FAULT; } switch (tcp->s_ent->sen) { case SEN_execve: case SEN_execveat: #if defined SPARC || defined SPARC64 case SEN_execv: #endif tcp->flags &= ~TCB_HIDE_LOG; break; } if (!(tcp->qual_flg & QUAL_TRACE) || (tracing_paths && !pathtrace_match(tcp)) ) { tcp->flags |= TCB_INSYSCALL | TCB_FILTERED; tcp->sys_func_rval = 0; return 0; } tcp->flags &= ~TCB_FILTERED; if (hide_log(tcp)) { res = 0; goto ret; } if (tcp->qual_flg & QUAL_FAULT) inject_syscall_fault_entering(tcp, sig); if (cflag == CFLAG_ONLY_STATS) { res = 0; goto ret; } #ifdef USE_LIBUNWIND if (stack_trace_enabled) { if (tcp->s_ent->sys_flags & STACKTRACE_CAPTURE_ON_ENTER) unwind_capture_stacktrace(tcp); } #endif printleader(tcp); tprintf("%s(", tcp->s_ent->sys_name); if (tcp->qual_flg & QUAL_RAW) res = printargs(tcp); else res = tcp->s_ent->sys_func(tcp); fflush(tcp->outf); ret: tcp->flags |= TCB_INSYSCALL; tcp->sys_func_rval = res; /* Measure the entrance time as late as possible to avoid errors. */ if (Tflag || cflag) gettimeofday(&tcp->etime, NULL); return res; }