Man page - ptrace(2)
Packages contains this manual
- __malloc_initialize_hook(3)
- getpwuid(3)
- frexpl(3)
- fchown(2)
- setttyent(3)
- pthread_attr_setstacksize(3)
- calloc(3)
- clog(3)
- seteuid(2)
- res_nquerydomain(3)
- y0l(3)
- catanl(3)
- catanh(3)
- inet_addr(3)
- getcwd(2)
- epoll_create1(2)
- atol(3)
- pciconfig_write(2)
- htonl(3)
- timer_settime(2)
- munmap(2)
- cexpl(3)
- rt_sigsuspend(2)
- msgctl(2)
- tan(3)
- get_mempolicy(2)
- roundf(3)
- towctrans(3)
- xdr_opaque(3)
- psignal(3)
- error_at_line(3)
- xdrmem_create(3)
- select(2)
- getdate_r(3)
- getprotobyname_r(3)
- nrand48_r(3)
- inet_netof(3)
- inet_ntoa(3)
- nextafterl(3)
- innetgr(3)
- on_exit(3)
- expm1l(3)
- strfmon(3)
- strdup(3)
- getservbyport(3)
- arch_prctl(2)
- j0(3)
- wait4(2)
- personality(2)
- bpf(2)
- pvalloc(3)
- getresuid32(2)
- des_setparity(3)
- prctl(2)
- clog10(3)
- aio_init(3)
- pthread_getconcurrency(3)
- csinl(3)
- linkat(2)
- vsscanf(3)
- isascii(3)
- xdr_union(3)
- nan(3)
- utimensat(2)
- ioctl_vt(2)
- _newselect(2)
- ldexpl(3)
- fabsf(3)
- chown(2)
- mkstemps(3)
- pthread_attr_getstacksize(3)
- listxattr(2)
- getpgrp(2)
- xdr_short(3)
- tcflush(3)
- pthread_cond_wait(3)
- argz_add(3)
- wcpncpy(3)
- reallocarray(3)
- llrintf(3)
- outsl(2)
- qsort(3)
- authnone_create(3)
- tzname(3)
- setresuid32(2)
- isspace(3)
- open_by_handle_at(2)
- drem(3)
- conjf(3)
- nanosleep(2)
- pthread_kill(3)
- putc(3)
- pthread_condattr_destroy(3)
- getpwuid_r(3)
- strverscmp(3)
- res_init(3)
- cacosl(3)
- qecvt_r(3)
- iswgraph(3)
- gethostbyname(3)
- ntohl(3)
- acct(2)
- asinl(3)
- envz_merge(3)
- strdupa(3)
- idle(2)
- getopt_long_only(3)
- hstrerror(3)
- fanotify_init(2)
- fputs_unlocked(3)
- sleep(3)
- vfprintf(3)
- scalb(3)
- nanl(3)
- lchown32(2)
- getnetent_r(3)
- fcntl(2)
- inw(2)
- rintl(3)
- arc4random(3)
- getsockopt(2)
- ilogbl(3)
- clog2(3)
- encrypt(3)
- sqrtf(3)
- isspace_l(3)
- tanl(3)
- cfmakeraw(3)
- assert(3)
- strtoull(3)
- xdrstdio_create(3)
- optopt(3)
- setrlimit(2)
- lround(3)
- xdr_accepted_reply(3)
- fmin(3)
- mq_notify(3)
- svcerr_auth(3)
- sbrk(2)
- recv(2)
- mq_unlink(2)
- strxfrm(3)
- ctan(3)
- atoi(3)
- xcrypt(3)
- sgetspent(3)
- fread(3)
- isless(3)
- ceil(3)
- pthread_cond_broadcast(3)
- oldfstat(2)
- outl(2)
- times(2)
- wcslen(3)
- popen(3)
- wprintf(3)
- labs(3)
- getrpcbynumber(3)
- shmat(2)
- clock_gettime(2)
- btree(3)
- s390_sthyi(2)
- siggetmask(3)
- getgid32(2)
- puts(3)
- scalblnl(3)
- strpbrk(3)
- catanhl(3)
- vlimit(3)
- getrpcent(3)
- tgammal(3)
- strtoll(3)
- funlockfile(3)
- xdecrypt(3)
- pthread_key_delete(3)
- setgrent(3)
- wmemmove(3)
- gnu_dev_major(3)
- regexec(3)
- lrintl(3)
- __ppc_set_ppr_med(3)
- rmdir(2)
- io_getevents(2)
- request_key(2)
- ecvt(3)
- __ppc_mdoom(3)
- mktemp(3)
- key_gendes(3)
- le64toh(3)
- statvfs(3)
- rpc(3)
- getdate_err(3)
- munlockall(2)
- close(2)
- xdr_rejected_reply(3)
- dlerror(3)
- le32toh(3)
- feclearexcept(3)
- insque(3)
- clntraw_create(3)
- getutid(3)
- strtof(3)
- settimeofday(2)
- mkdir(2)
- rewind(3)
- logf(3)
- tmpnam(3)
- iswpunct(3)
- wcrtomb(3)
- epoll_pwait(2)
- getitimer(2)
- wordexp(3)
- clog2f(3)
- capset(2)
- strrchr(3)
- outsb(2)
- freeifaddrs(3)
- getwc_unlocked(3)
- ustat(2)
- bswap_16(3)
- program_invocation_short_name(3)
- ldiv(3)
- exp10f(3)
- vprintf(3)
- wcsncpy(3)
- iscntrl(3)
- readlink(2)
- semget(2)
- connect(2)
- psiginfo(3)
- epoll_ctl(2)
- removexattr(2)
- envz_strip(3)
- fgetxattr(2)
- atexit(3)
- putgrent(3)
- bswap(3)
- getegid32(2)
- qecvt(3)
- asinh(3)
- isfdtype(3)
- setenv(3)
- readdir(3)
- rtime(3)
- nearbyint(3)
- getgroups32(2)
- statx(2)
- modify_ldt(2)
- cpow(3)
- eventfd_read(3)
- sendfile64(2)
- getnetbyname(3)
- fremovexattr(2)
- uselib(2)
- inet(3)
- endutxent(3)
- clnt_spcreateerror(3)
- pututline(3)
- nexttowardl(3)
- getipnodebyaddr(3)
- fts_set(3)
- memmem(3)
- fmodl(3)
- setfsuid32(2)
- wordfree(3)
- fadvise64(2)
- getppid(2)
- qsort_r(3)
- toupper(3)
- getwc(3)
- fputws(3)
- mrand48(3)
- preadv(2)
- sincosf(3)
- fstatat64(2)
- dirfd(3)
- jnf(3)
- static_assert(3)
- wctype(3)
- vwarn(3)
- setfsent(3)
- listen(2)
- wcstok(3)
- argz_insert(3)
- select_tut(2)
- ctanl(3)
- getunwind(2)
- difftime(3)
- daylight(3)
- sigpause(3)
- wcscat(3)
- dlclose(3)
- __ppc_set_ppr_med_low(3)
- pread(2)
- fstatvfs(3)
- cbrtf(3)
- strnlen(3)
- sinhl(3)
- inl_p(2)
- setregid32(2)
- putwc(3)
- register_printf_type(3)
- nextafterf(3)
- opendir(3)
- strtod(3)
- tgamma(3)
- malloc_get_state(3)
- aio_write(3)
- timezone(3)
- xdr_pmaplist(3)
- sysfs(2)
- index(3)
- svcerr_noproc(3)
- envz(3)
- klogctl(3)
- pselect(2)
- get_current_dir_name(3)
- xdr_char(3)
- asinhf(3)
- preadv2(2)
- inotify_init1(2)
- pthread_attr_setstackaddr(3)
- getline(3)
- tanhf(3)
- rtnetlink(3)
- pkey_alloc(2)
- edata(3)
- stailq(3)
- isastream(2)
- setregid(2)
- copy_file_range(2)
- rcmd_af(3)
- futex(2)
- prof(2)
- siglongjmp(3)
- hdestroy(3)
- catan(3)
- pthread_cond_signal(3)
- mkfifoat(3)
- clntudp_create(3)
- getentropy(3)
- vsprintf(3)
- fabs(3)
- lseek64(3)
- pthread_setname_np(3)
- conjl(3)
- chroot(2)
- ccoshf(3)
- erand48_r(3)
- wcsnrtombs(3)
- rindex(3)
- fputc_unlocked(3)
- setresgid32(2)
- gettimeofday(2)
- cexp(3)
- inotify_add_watch(2)
- set_robust_list(2)
- nice(2)
- strtold(3)
- mq_getattr(3)
- xdr(3)
- getxattr(2)
- getrandom(2)
- splice(2)
- strerror(3)
- fcntl64(2)
- fnmatch(3)
- ungetwc(3)
- getspnam_r(3)
- clearenv(3)
- atan2(3)
- get_myaddress(3)
- open(2)
- pthread_setcancelstate(3)
- newlocale(3)
- open_memstream(3)
- setprotoent(3)
- logbf(3)
- ilogb(3)
- wmemcpy(3)
- tcsendbreak(3)
- be16toh(3)
- perfmonctl(2)
- strtoq(3)
- getgrgid_r(3)
- pthread_timedjoin_np(3)
- memfd_create(2)
- getttynam(3)
- mcheck_pedantic(3)
- _llseek(2)
- renameat2(2)
- ioperm(2)
- ecb_crypt(3)
- pthread_condattr_init(3)
- fminl(3)
- lio_listio(3)
- envz_add(3)
- setbuf(3)
- setkey(3)
- expm1(3)
- strtoul(3)
- getcwd(3)
- setutxent(3)
- getrpcent_r(3)
- unimplemented(2)
- fclose(3)
- epoll_create(2)
- getfsent(3)
- key_secretkey_is_set(3)
- vserver(2)
- vswprintf(3)
- sigsuspend(2)
- pututxline(3)
- clnt_freeres(3)
- cacheflush(2)
- ioprio_set(2)
- alarm(2)
- fgetc(3)
- __fpurge(3)
- getlogin_r(3)
- vfork(2)
- bstring(3)
- div(3)
- getrusage(2)
- gettid(2)
- dprintf(3)
- strtoumax(3)
- jrand48(3)
- iswcntrl(3)
- vwarnx(3)
- cacos(3)
- ccoshl(3)
- fesetexceptflag(3)
- res_nclose(3)
- shmop(2)
- mcheck_check_all(3)
- vscanf(3)
- tolower(3)
- landlock_add_rule(2)
- argz_next(3)
- lroundl(3)
- ruserok(3)
- glob(3)
- brk(2)
- rename(2)
- strcspn(3)
- sched_getscheduler(2)
- wcstoumax(3)
- dbopen(3)
- xdr_bytes(3)
- fegetenv(3)
- scalbf(3)
- pkey_free(2)
- fgetgrent(3)
- strchrnul(3)
- fork(2)
- log1pf(3)
- strtoimax(3)
- fputs(3)
- putspent(3)
- ttyname_r(3)
- iswlower(3)
- epoll_wait(2)
- minor(3)
- wcsspn(3)
- sendmmsg(2)
- pthread_attr_getsigmask_np(3)
- erand48(3)
- setpgrp(2)
- db(3)
- readv(2)
- cimagf(3)
- pthread_sigmask(3)
- getresuid(2)
- gamma(3)
- logwtmp(3)
- imaxabs(3)
- y1(3)
- swapoff(2)
- svcerr_weakauth(3)
- mbtowc(3)
- madvise(2)
- __fbufsize(3)
- swapon(2)
- towlower(3)
- asin(3)
- initgroups(3)
- svc_getreqset(3)
- pthread_attr_destroy(3)
- scalblnf(3)
- ispunct(3)
- casin(3)
- xdr_pmap(3)
- sigvec(3)
- dlmopen(3)
- localeconv(3)
- tcgetattr(3)
- mempcpy(3)
- clnt_perrno(3)
- clock_getcpuclockid(3)
- setaliasent(3)
- clock(3)
- ftok(3)
- svc_run(3)
- getsubopt(3)
- coshf(3)
- pow(3)
- getpwent(3)
- ntp_gettime(3)
- xdrrec_skiprecord(3)
- symlink(2)
- shmctl(2)
- mq_timedreceive(2)
- malloc(3)
- tgkill(2)
- l64a(3)
- unlockpt(3)
- mallopt(3)
- creal(3)
- syscalls(2)
- set_tid_address(2)
- exp2f(3)
- fstatfs(2)
- statfs(2)
- dreml(3)
- feenableexcept(3)
- ftw(3)
- fanotify_mark(2)
- clnt_sperror(3)
- realpath(3)
- sysconf(3)
- _syscall(2)
- set_mempolicy(2)
- mq_unlink(3)
- freehostent(3)
- rresvport_af(3)
- nl_langinfo_l(3)
- fmaxl(3)
- iscntrl_l(3)
- copysignf(3)
- llseek(2)
- bzero(3)
- ioctl_fsmap(2)
- remquof(3)
- malloc_trim(3)
- pthread_getattr_default_np(3)
- isalnum_l(3)
- mlock(2)
- nearbyintf(3)
- confstr(3)
- sinf(3)
- ioctl_eventpoll(2)
- sigstack(3)
- seed48_r(3)
- utmpname(3)
- malloc_stats(3)
- stpncpy(3)
- getservbyport_r(3)
- cabsl(3)
- isblank(3)
- sigprocmask(2)
- isinfl(3)
- isinff(3)
- pathconf(3)
- xdr_u_short(3)
- acos(3)
- timerfd_create(2)
- key_encryptsession(3)
- log2f(3)
- oldlstat(2)
- res_querydomain(3)
- memcmp(3)
- gethostbyaddr(3)
- sighold(3)
- gtty(2)
- xdr_void(3)
- getmsg(2)
- io_setup(2)
- ttyslot(3)
- recno(3)
- cuserid(3)
- nanf(3)
- pthread_getaffinity_np(3)
- if_indextoname(3)
- remainderf(3)
- putpwent(3)
- pow10f(3)
- pwritev(2)
- swapcontext(3)
- cfsetospeed(3)
- envz_remove(3)
- cosh(3)
- a64l(3)
- uselocale(3)
- yn(3)
- msgget(2)
- pthread_equal(3)
- prlimit(2)
- setspent(3)
- newfstatat(2)
- renameat(2)
- truncf(3)
- pthread_yield(3)
- tkill(2)
- islessequal(3)
- isnanf(3)
- sethostent(3)
- setvbuf(3)
- gnu_get_libc_release(3)
- atoll(3)
- getgrnam(3)
- get_robust_list(2)
- __ppc_yield(3)
- __memalign_hook(3)
- eventfd2(2)
- mq_setattr(3)
- tmpnam_r(3)
- pmap_getport(3)
- svcfd_create(3)
- getfsspec(3)
- setgid(2)
- getlogin(3)
- get_nprocs(3)
- canonicalize_file_name(3)
- pthread_mutexattr_getrobust(3)
- strerrorname_np(3)
- csinh(3)
- malloc_set_state(3)
- tcgetsid(3)
- ssignal(3)
- secure_getenv(3)
- significandl(3)
- wcschr(3)
- isgraph(3)
- pthread_mutexattr_gettype(3)
- creat(2)
- cabsf(3)
- __ppc_set_ppr_med_high(3)
- fchdir(2)
- backtrace_symbols(3)
- exp10l(3)
- euidaccess(3)
- sync_file_range(2)
- getutxline(3)
- isdigit(3)
- sinhf(3)
- lgetxattr(2)
- getaliasent(3)
- memrchr(3)
- io_submit(2)
- clnt_create(3)
- __setfpucw(3)
- _flushlbf(3)
- lcong48_r(3)
- clog10l(3)
- pmap_getmaps(3)
- memalign(3)
- xdr_authunix_parms(3)
- execl(3)
- getdate(3)
- cfsetispeed(3)
- tanhl(3)
- wmempcpy(3)
- outw_p(2)
- faccessat(2)
- rresvport(3)
- nextup(3)
- fgetgrent_r(3)
- getopt(3)
- xdr_vector(3)
- aio_error(3)
- frexpf(3)
- getpw(3)
- sscanf(3)
- mprotect(2)
- exp(3)
- sched_getaffinity(2)
- accept4(2)
- remainderl(3)
- pthread_key_create(3)
- endian(3)
- setmntent(3)
- get_phys_pages(3)
- argz(3)
- _exit(2)
- towupper_l(3)
- lrand48(3)
- csqrt(3)
- hdestroy_r(3)
- remquo(3)
- feof_unlocked(3)
- isprint(3)
- pivot_root(2)
- arc4random_uniform(3)
- strfroml(3)
- getdomainname(2)
- va_end(3)
- getresgid(2)
- cosf(3)
- endhostent(3)
- setgid32(2)
- ioctl_fs(2)
- getaddrinfo(3)
- fgetwc(3)
- lock(2)
- getservbyname_r(3)
- sys_nerr(3)
- insb(2)
- usleep(3)
- security(2)
- cfree(3)
- tanf(3)
- fprintf(3)
- pthread_mutexattr_setpshared(3)
- xprt_unregister(3)
- alphasort(3)
- getgrent(3)
- scandirat(3)
- iruserok(3)
- ttyname(3)
- tdestroy(3)
- strcasecmp(3)
- getpgid(2)
- drand48_r(3)
- mmap(2)
- sigtimedwait(2)
- pthread_once(3)
- mq_receive(3)
- pthread_mutexattr_setkind_np(3)
- iopl(2)
- s390_runtime_instr(2)
- lckpwdf(3)
- memmove(3)
- __fpending(3)
- mbsrtowcs(3)
- restart_syscall(2)
- memset(3)
- significandf(3)
- openat2(2)
- timeradd(3)
- conj(3)
- flockfile(3)
- madvise1(2)
- inet_aton(3)
- fstatfs64(2)
- fmax(3)
- fmemopen(3)
- fmaf(3)
- lseek(2)
- registerrpc(3)
- kexec_file_load(2)
- gammal(3)
- feof(3)
- pidfd_open(2)
- crealf(3)
- clogl(3)
- getutmp(3)
- umount(2)
- inet_pton(3)
- flistxattr(2)
- xdr_wrapstring(3)
- socketcall(2)
- setrpcent(3)
- rint(3)
- vm86(2)
- sincosl(3)
- getprotoent_r(3)
- mknod(2)
- getdents64(2)
- gai_cancel(3)
- srandom_r(3)
- getnetbyname_r(3)
- sigaddset(3)
- htole16(3)
- endnetent(3)
- nextafter(3)
- timerisset(3)
- getgrent_r(3)
- freeaddrinfo(3)
- endprotoent(3)
- mbind(2)
- sigorset(3)
- pthread_rwlockattr_setkind_np(3)
- cimag(3)
- waitid(2)
- abs(3)
- unlink(2)
- recvmsg(2)
- getaliasbyname(3)
- wctrans(3)
- kill(2)
- strtol(3)
- __ppc_set_ppr_very_low(3)
- membarrier(2)
- getnetbyaddr_r(3)
- writev(2)
- errx(3)
- tfind(3)
- clone3(2)
- __freading(3)
- outw(2)
- regfree(3)
- accept(2)
- timer_getoverrun(2)
- shmdt(2)
- svcerr_decode(3)
- getnameinfo(3)
- endusershell(3)
- execvpe(3)
- cbc_crypt(3)
- res_send(3)
- xdr_destroy(3)
- getcontext(3)
- pkey_mprotect(2)
- twalk_r(3)
- isalnum(3)
- timercmp(3)
- setxattr(2)
- pthread_cleanup_pop_restore_np(3)
- stat(2)
- isupper(3)
- vsyslog(3)
- strlen(3)
- pthread_attr_setinheritsched(3)
- xdr_inline(3)
- strtouq(3)
- raise(3)
- getpeername(2)
- capget(2)
- atanl(3)
- ferror_unlocked(3)
- isxdigit_l(3)
- modfl(3)
- pthread_mutexattr_init(3)
- pthread_mutexattr_getkind_np(3)
- phys(2)
- llabs(3)
- sched_rr_get_interval(2)
- asprintf(3)
- explicit_bzero(3)
- asctime(3)
- clone(2)
- munlock(2)
- __realloc_hook(3)
- atof(3)
- rt_tgsigqueueinfo(2)
- syslog(2)
- inet_makeaddr(3)
- epoll_pwait2(2)
- iswalpha(3)
- netlink(3)
- sched_setattr(2)
- sigdescr_np(3)
- access(2)
- getc_unlocked(3)
- dysize(3)
- inet_net_pton(3)
- sched_setparam(2)
- timerfd_settime(2)
- nexttowardf(3)
- expf(3)
- svcerr_progvers(3)
- getwchar(3)
- ftime(3)
- if_nametoindex(3)
- argz_add_sep(3)
- vasprintf(3)
- unlinkat(2)
- putenv(3)
- pthread_mutexattr_setrobust_np(3)
- error_message_count(3)
- setfsgid(2)
- cmsg(3)
- setpwent(3)
- cfgetospeed(3)
- end(3)
- pidfd_send_signal(2)
- scalbn(3)
- closelog(3)
- srandom(3)
- argz_replace(3)
- ioctl_tty(2)
- va_arg(3)
- towlower_l(3)
- isblank_l(3)
- remove(3)
- expl(3)
- fscanf(3)
- versionsort(3)
- pow10(3)
- hsearch(3)
- gethostid(3)
- fchownat(2)
- group_member(3)
- getchar_unlocked(3)
- getservbyname(3)
- pthread_mutexattr_destroy(3)
- setpgid(2)
- acosf(3)
- ctanhf(3)
- shm_open(3)
- towupper(3)
- getdents(2)
- chown32(2)
- hypotf(3)
- undocumented(3)
- drand48(3)
- csinf(3)
- ctime_r(3)
- setlinebuf(3)
- ulimit(3)
- spu_create(2)
- fcvt_r(3)
- ipc(2)
- ftruncate64(2)
- fdopen(3)
- svcerr_noprog(3)
- getrpcport(3)
- csin(3)
- sinh(3)
- nrand48(3)
- openpty(3)
- xdr_double(3)
- pthread_attr_getscope(3)
- vfscanf(3)
- catanhf(3)
- inb(2)
- wcpcpy(3)
- ldexp(3)
- getopt_long(3)
- strerrordesc_np(3)
- mbsinit(3)
- argz_stringify(3)
- setbuffer(3)
- byteorder(3)
- expm1f(3)
- pthread_attr_setscope(3)
- gnu_dev_makedev(3)
- pipe(2)
- updwtmp(3)
- fts_read(3)
- ioctl_fat(2)
- h_errno(3)
- sem_getvalue(3)
- iswupper(3)
- lrint(3)
- perror(3)
- xdr_u_int(3)
- timer_create(2)
- iswdigit(3)
- fgetspent(3)
- fwrite_unlocked(3)
- reboot(2)
- ftruncate(2)
- getutmpx(3)
- pwrite64(2)
- getauxval(3)
- xdr_pointer(3)
- getprotobynumber(3)
- svc_destroy(3)
- vmsplice(2)
- inet_network(3)
- readdir_r(3)
- setsockopt(2)
- rexec(3)
- flock(2)
- getw(3)
- mmap2(2)
- j1f(3)
- cprojf(3)
- mkstemp(3)
- symlinkat(2)
- tempnam(3)
- pthread_attr_getaffinity_np(3)
- gethostbyname_r(3)
- signalfd4(2)
- sys_siglist(3)
- erfc(3)
- truncate64(2)
- verr(3)
- pthread_kill_other_threads_np(3)
- eaccess(3)
- fsetpos(3)
- slist(3)
- pmap_unset(3)
- modf(3)
- ioctl_pipe(2)
- vfwprintf(3)
- getresgid32(2)
- statfs64(2)
- cexp2(3)
- stdio_ext(3)
- login_tty(3)
- xdr_long(3)
- dlsym(3)
- clog2l(3)
- malloc_usable_size(3)
- fegetexceptflag(3)
- basename(3)
- fwrite(3)
- vhangup(2)
- printf(3)
- setnetent(3)
- gethostbyname2(3)
- mallinfo2(3)
- signbit(3)
- clnt_broadcast(3)
- sched_yield(2)
- sem_open(3)
- sigsetjmp(3)
- cacoshl(3)
- sem_unlink(3)
- setresuid(2)
- signgam(3)
- putw(3)
- imaxdiv(3)
- regex(3)
- alloc_hugepages(2)
- modff(3)
- exp10(3)
- cprojl(3)
- utime(2)
- clogf(3)
- pthread_mutex_unlock(3)
- erff(3)
- ioctl_userfaultfd(2)
- iswprint(3)
- roundl(3)
- sqrtl(3)
- fpurge(3)
- getusershell(3)
- fcloseall(3)
- xdr_opaque_auth(3)
- gethostent_r(3)
- fgetwc_unlocked(3)
- fchmod(2)
- strptime(3)
- lutimes(3)
- htole64(3)
- putchar_unlocked(3)
- create_module(2)
- isascii_l(3)
- sigaction(2)
- stdout(3)
- geteuid32(2)
- xprt_register(3)
- freopen(3)
- ccosl(3)
- pthread_setschedprio(3)
- rt_sigaction(2)
- getmntent(3)
- putwchar_unlocked(3)
- logl(3)
- remque(3)
- unsetenv(3)
- sigwaitinfo(2)
- pthread_mutexattr_getrobust_np(3)
- initstate_r(3)
- getfsfile(3)
- exp2l(3)
- isatty(3)
- lgamma_r(3)
- lrintf(3)
- outb(2)
- __clone2(2)
- strcpy(3)
- clnt_call(3)
- hypot(3)
- fegetexcept(3)
- tcsetpgrp(3)
- gets(3)
- malloc_info(3)
- nextupf(3)
- pthread_attr_getdetachstate(3)
- getaliasent_r(3)
- fstat64(2)
- futimesat(2)
- dl_iterate_phdr(3)
- posix_madvise(3)
- endnetgrent(3)
- tolower_l(3)
- pthread_attr_setstack(3)
- pread64(2)
- sigsetops(3)
- stty(2)
- process_vm_readv(2)
- isfinite(3)
- gethostbyaddr_r(3)
- cproj(3)
- gai_strerror(3)
- key_decryptsession(3)
- inet_ntop(3)
- __ppc_mdoio(3)
- btowc(3)
- setstate_r(3)
- if_nameindex(3)
- fdetach(2)
- random_r(3)
- iruserok_af(3)
- truncl(3)
- clearerr(3)
- lgammaf(3)
- lfind(3)
- ctanf(3)
- strcat(3)
- pthread_attr_getschedpolicy(3)
- pthread_rwlockattr_getkind_np(3)
- sigrelse(3)
- daemon(3)
- pthread_setcanceltype(3)
- sigevent(7)
- iswalnum(3)
- pmap_set(3)
- stdin(3)
- ceilf(3)
- asctime_r(3)
- poll(2)
- svc_unregister(3)
- isnanl(3)
- carg(3)
- getprotobyname(3)
- arm_fadvise(2)
- optind(3)
- mount_setattr(2)
- dlvsym(3)
- ntp_adjtime(3)
- abort(3)
- pthread_getname_np(3)
- execlp(3)
- bind(2)
- bsearch(3)
- endspent(3)
- register_printf_specifier(3)
- landlock_create_ruleset(2)
- mkostemp(3)
- setgroups(2)
- toupper_l(3)
- argz_extract(3)
- sigblock(3)
- j0l(3)
- argz_delete(3)
- setusershell(3)
- getspnam(3)
- optarg(3)
- vm86old(2)
- sigandset(3)
- getdtablesize(3)
- getsockname(2)
- pthread_sigqueue(3)
- ptsname(3)
- j1(3)
- lgamma(3)
- getpagesize(2)
- pthread_mutex_lock(3)
- setsid(2)
- strncat(3)
- ioctl_kd(2)
- tsearch(3)
- mq_notify(2)
- fcvt(3)
- clntudp_bufcreate(3)
- getpwent_r(3)
- pthread_getspecific(3)
- memfrob(3)
- arc4random_buf(3)
- forkpty(3)
- powl(3)
- dlopen(3)
- stderr(3)
- set_thread_area(2)
- query_module(2)
- sem_close(3)
- strndup(3)
- __malloc_hook(3)
- setjmp(3)
- stdio(3)
- bdflush(2)
- sendto(2)
- mpx(2)
- fopen(3)
- setpriority(2)
- nextdownl(3)
- mprobe(3)
- oldstat(2)
- sem_destroy(3)
- bcopy(3)
- remap_file_pages(2)
- isgreaterequal(3)
- getpass(3)
- seekdir(3)
- break(2)
- authunix_create_default(3)
- tty_ioctl(4)
- process_madvise(2)
- endfsent(3)
- atoq(3)
- strftime(3)
- fts(3)
- getgrgid(3)
- isxdigit(3)
- ftello(3)
- regcomp(3)
- error(3)
- getenv(3)
- clnt_sperrno(3)
- readahead(2)
- y0(3)
- roundup(3)
- io_destroy(2)
- vsnprintf(3)
- lgammal(3)
- eventfd_write(3)
- pthread_mutex_trylock(3)
- lchown(2)
- dladdr(3)
- error_print_progname(3)
- pthread_mutexattr_settype(3)
- strspn(3)
- __after_morecore_hook(3)
- localtime(3)
- fsync(2)
- ether_aton(3)
- csinhl(3)
- trunc(3)
- xdr_u_char(3)
- syslog(3)
- y1f(3)
- ioctl_nsfs(2)
- wmemcmp(3)
- ffsll(3)
- ether_ntohost(3)
- bswap_32(3)
- umount2(2)
- sigfillset(3)
- landlock_restrict_self(2)
- pthread_join(3)
- sysinfo(2)
- clock_settime(2)
- llrint(3)
- s390_guarded_storage(2)
- getc(3)
- inet_lnaof(3)
- tcgetpgrp(3)
- clock_getres(2)
- etext(3)
- strfmon_l(3)
- putwc_unlocked(3)
- xdr_replymsg(3)
- scalbl(3)
- fdim(3)
- getspent(3)
- sem_timedwait(3)
- posix_fallocate(3)
- res_nmkquery(3)
- pthread_spin_unlock(3)
- mq_timedsend(2)
- opterr(3)
- getloadavg(3)
- strsignal(3)
- finite(3)
- inw_p(2)
- csinhf(3)
- execveat(2)
- seed48(3)
- sigset(3)
- setgroups32(2)
- logbl(3)
- wcsdup(3)
- clnt_geterr(3)
- sys_errlist(3)
- inotify_rm_watch(2)
- qgcvt(3)
- wcspbrk(3)
- sin(3)
- lookup_dcookie(2)
- s390_pci_mmio_read(2)
- wcscmp(3)
- getutxent(3)
- pciconfig_read(2)
- initstate(3)
- backtrace(3)
- putc_unlocked(3)
- fedisableexcept(3)
- rt_sigprocmask(2)
- clock_adjtime(2)
- fwprintf(3)
- jnl(3)
- grantpt(3)
- cimagl(3)
- getgrnam_r(3)
- remquol(3)
- swprintf(3)
- mbrtowc(3)
- fileno_unlocked(3)
- readlinkat(2)
- sigignore(3)
- strndupa(3)
- semctl(2)
- assert_perror(3)
- sendfile(2)
- shm_unlink(3)
- log(3)
- ungetc(3)
- erf(3)
- qfcvt(3)
- pthread_atfork(3)
- login(3)
- setservent(3)
- jrand48_r(3)
- wcsnlen(3)
- tcflow(3)
- pthread_cond_destroy(3)
- inl(2)
- srand48_r(3)
- erfcf(3)
- iconv(3)
- pthread_mutex_consistent_np(3)
- fabsl(3)
- pclose(3)
- nfsservctl(2)
- gai_error(3)
- wcsncmp(3)
- islower_l(3)
- iswctype(3)
- svc_register(3)
- arm_sync_file_range(2)
- strfry(3)
- strfromd(3)
- getttyent(3)
- rand(3)
- fchown32(2)
- ctime(3)
- fsetxattr(2)
- feupdateenv(3)
- random(3)
- getpwnam_r(3)
- sigwait(3)
- aio_fsync(3)
- mq_open(2)
- tanh(3)
- localtime_r(3)
- bsd_signal(3)
- strsep(3)
- mknodat(2)
- cexpf(3)
- cacosh(3)
- mbrlen(3)
- aio_cancel(3)
- mq_getsetattr(2)
- fdatasync(2)
- htons(3)
- sem_post(3)
- htobe16(3)
- vtimes(3)
- fgetpwent_r(3)
- getwchar_unlocked(3)
- mkdirat(2)
- dup(2)
- free_hugepages(2)
- feraiseexcept(3)
- lockf(3)
- userfaultfd(2)
- pthread_attr_setaffinity_np(3)
- memcpy(3)
- prlimit64(2)
- ferror(3)
- ldexpf(3)
- aio_return(3)
- adjtimex(2)
- execle(3)
- tailq(3)
- cabs(3)
- endaliasent(3)
- execvp(3)
- hasmntopt(3)
- if_freenameindex(3)
- signal(2)
- dn_comp(3)
- pthread_attr_getstack(3)
- ether_hostton(3)
- re_comp(3)
- cexp2l(3)
- getwd(3)
- llroundl(3)
- cos(3)
- pthread_mutex_consistent(3)
- isalpha_l(3)
- io_cancel(2)
- frexp(3)
- finitel(3)
- perf_event_open(2)
- pthread_exit(3)
- ioctl_console(2)
- timelocal(3)
- timersub(3)
- setresgid(2)
- semop(2)
- getgroups(2)
- envz_entry(3)
- xdr_u_long(3)
- seccomp(2)
- ftrylockfile(3)
- setuid(2)
- wcwidth(3)
- llround(3)
- cacoshf(3)
- pthread_attr_setschedpolicy(3)
- fgetpos(3)
- xdr_array(3)
- sprintf(3)
- wmemset(3)
- setcontext(3)
- copysignl(3)
- be64toh(3)
- matherr(3)
- hypotl(3)
- rawmemchr(3)
- fmodf(3)
- mount(2)
- mktime(3)
- stdarg(3)
- clnttcp_create(3)
- string(3)
- profil(3)
- clnt_perror(3)
- getpriority(2)
- regerror(3)
- clone2(2)
- getgid(2)
- pthread_spin_lock(3)
- iswblank(3)
- ftell(3)
- dup3(2)
- toascii(3)
- strncpy(3)
- mrand48_r(3)
- setstate(3)
- sigqueue(3)
- cpowf(3)
- setlogmask(3)
- sched_getcpu(3)
- htobe32(3)
- list(3)
- isdigit_l(3)
- chdir(2)
- fstat(2)
- pwritev2(2)
- get_thread_area(2)
- freelocale(3)
- acoshl(3)
- socketpair(2)
- scalbln(3)
- fpclassify(3)
- getpwnam(3)
- pthread_getcpuclockid(3)
- ioprio_get(2)
- strtok_r(3)
- exit_group(2)
- scalbnf(3)
- xdrrec_create(3)
- pthread_mutex_destroy(3)
- sqrt(3)
- dirname(3)
- exit(2)
- ulckpwdf(3)
- cargl(3)
- powerof2(3)
- simpleq(3)
- process_vm_writev(2)
- fdopendir(3)
- getpt(3)
- floorl(3)
- va_start(3)
- lcong48(3)
- strerror_l(3)
- xdrrec_eof(3)
- key_setsecret(3)
- lstat64(2)
- memfd_secret(2)
- sigreturn(2)
- casinhf(3)
- valloc(3)
- stat64(2)
- jn(3)
- sinl(3)
- pthread_testcancel(3)
- cfgetispeed(3)
- dup2(2)
- getnetent(3)
- pthread_setconcurrency(3)
- memccpy(3)
- rt_sigqueueinfo(2)
- ccosf(3)
- sincos(3)
- tcdrain(3)
- ccos(3)
- chmod(2)
- cacosf(3)
- lstat(2)
- pthread_spin_trylock(3)
- sigisemptyset(3)
- getrpcbyname(3)
- fpathconf(3)
- copysign(3)
- round(3)
- wmemchr(3)
- qfcvt_r(3)
- fattach(2)
- __fsetlocking(3)
- adjtime(3)
- makedev(3)
- des_crypt(3)
- iswspace(3)
- twalk(3)
- exec(3)
- link(2)
- fileno(3)
- endpwent(3)
- logb(3)
- wcscspn(3)
- console_ioctl(4)
- fgetpwent(3)
- setegid(2)
- clnt_destroy(3)
- getaddrinfo_a(3)
- svc_getargs(3)
- addmntent(3)
- globfree(3)
- islower(3)
- muntrace(3)
- clnt_pcreateerror(3)
- llrintl(3)
- clnt_control(3)
- fgetspent_r(3)
- strstr(3)
- putmsg(2)
- __fwritable(3)
- res_nsearch(3)
- fseeko(3)
- mq_timedreceive(3)
- log10(3)
- fexecve(3)
- gammaf(3)
- pthread_setschedparam(3)
- wcscpy(3)
- xdr_float(3)
- pthread_attr_setdetachstate(3)
- sem_wait(3)
- pow10l(3)
- re_exec(3)
- rand_r(3)
- putpmsg(2)
- getdelim(3)
- utimes(2)
- mq_close(3)
- setutent(3)
- creall(3)
- mq_send(3)
- telldir(3)
- powf(3)
- erfl(3)
- pthread_self(3)
- pselect6(2)
- unlocked_stdio(3)
- insw(2)
- cfsetspeed(3)
- argz_create(3)
- xdr_string(3)
- pthread_attr_getguardsize(3)
- finitef(3)
- setlocale(3)
- bcmp(3)
- fmtmsg(3)
- sendmsg(2)
- pthread_cleanup_push(3)
- inb_p(2)
- mmap64(3)
- getuid32(2)
- truncate(2)
- mlock2(2)
- fegetround(3)
- ugetrlimit(2)
- getprotobynumber_r(3)
- utmpxname(3)
- isinf(3)
- clearerr_unlocked(3)
- stime(2)
- nftw(3)
- duplocale(3)
- svcraw_create(3)
- svc_getcaller(3)
- ctanhl(3)
- cbrt(3)
- floorf(3)
- sethostid(3)
- sigemptyset(3)
- sigaltstack(2)
- mkfifo(3)
- lsearch(3)
- getservent_r(3)
- islessgreater(3)
- floor(3)
- argz_append(3)
- tzset(3)
- res_mkquery(3)
- fstatat(2)
- strchr(3)
- semtimedop(2)
- bindresvport(3)
- tcsetattr(3)
- warn(3)
- getservent(3)
- atanhl(3)
- tdelete(3)
- ynf(3)
- ether_ntoa_r(3)
- fesetenv(3)
- mq_timedsend(3)
- quotactl(2)
- init_module(2)
- rcmd(3)
- fenv(3)
- getutxid(3)
- pthread_mutexattr_getpshared(3)
- scalbnl(3)
- atan2l(3)
- argz_count(3)
- rpmatch(3)
- timerfd_gettime(2)
- ualarm(3)
- pthread_attr_init(3)
- vdprintf(3)
- pthread_cancel(3)
- fflush(3)
- setkey_r(3)
- mbstowcs(3)
- mremap(2)
- strcasestr(3)
- hcreate_r(3)
- siginterrupt(3)
- offsetof(3)
- atan(3)
- wctomb(3)
- getutent(3)
- significand(3)
- arm_fadvise64_64(2)
- dremf(3)
- wcswidth(3)
- syscall(2)
- rintf(3)
- bswap_64(3)
- pthread_attr_getschedparam(3)
- lroundf(3)
- timegm(3)
- posix_fadvise(2)
- getrlimit(2)
- svc_freeargs(3)
- xdr_enum(3)
- hcreate(3)
- ptrace(2)
- backtrace_symbols_fd(3)
- fetestexcept(3)
- ccosh(3)
- htole32(3)
- kexec_load(2)
- fallocate(2)
- timer_gettime(2)
- tgammaf(3)
- errno(3)
- sched_get_priority_max(2)
- xdr_getpos(3)
- vwprintf(3)
- ssetmask(2)
- ether_ntoa(3)
- waitpid(2)
- sched_getattr(2)
- inotify_init(2)
- fma(3)
- gnu_get_libc_version(3)
- svctcp_create(3)
- wcstombs(3)
- gethostname(2)
- strerror_r(3)
- sigismember(3)
- fgetws_unlocked(3)
- hash(3)
- circleq(3)
- getrpcbynumber_r(3)
- pthread_cond_timedwait(3)
- uname(2)
- fgetc_unlocked(3)
- mq_open(3)
- cosl(3)
- rewinddir(3)
- nextdown(3)
- longjmp(3)
- execv(3)
- iconv_open(3)
- xencrypt(3)
- ctermid(3)
- isgraph_l(3)
- move_pages(2)
- isunordered(3)
- msgsnd(2)
- rt_sigtimedwait(2)
- syncfs(2)
- mlockall(2)
- pthread_getschedparam(3)
- lsetxattr(2)
- getutid_r(3)
- log1pl(3)
- catanf(3)
- passwd2des(3)
- iconv_close(3)
- aligned_alloc(3)
- sched_setscheduler(2)
- gmtime(3)
- __free_hook(3)
- acoshf(3)
- mtrace(3)
- resolver(3)
- clog10f(3)
- sethostname(2)
- pthread_attr_setguardsize(3)
- tuxcall(2)
- atanh(3)
- ispunct_l(3)
- svcudp_bufcreate(3)
- ctanh(3)
- j1l(3)
- log10l(3)
- alloca(3)
- sigpending(2)
- nexttoward(3)
- isnormal(3)
- svc_getreq(3)
- putchar(3)
- getnetbyaddr(3)
- cpowl(3)
- get_kernel_syms(2)
- getutline_r(3)
- pthread_setaffinity_np(3)
- isnan(3)
- getprotoent(3)
- catclose(3)
- getsid(2)
- endrpcent(3)
- fts_close(3)
- gnu_dev_minor(3)
- ruserok_af(3)
- getutent_r(3)
- getegid(2)
- sgetmask(2)
- posix_memalign(3)
- atanf(3)
- unshare(2)
- lremovexattr(2)
- strncasecmp(3)
- endutent(3)
- updwtmpx(3)
- outsw(2)
- sched_getparam(2)
- setuid32(2)
- catgets(3)
- nextupl(3)
- openat(2)
- logout(3)
- free(3)
- setfsuid(2)
- getutline(3)
- svc_sendreply(3)
- fadvise64_64(2)
- cargf(3)
- __ppc_set_ppr_low(3)
- casinh(3)
- outb_p(2)
- fputwc(3)
- log10f(3)
- getnetgrent(3)
- fputws_unlocked(3)
- ffsl(3)
- endttyent(3)
- isgreater(3)
- sigmask(3)
- sgetspent_r(3)
- fmaxf(3)
- openlog(3)
- strncmp(3)
- closedir(3)
- rexec_af(3)
- exp2(3)
- mcheck(3)
- isalpha(3)
- pthread_mutex_init(3)
- catopen(3)
- clock_nanosleep(2)
- ioctl(2)
- remainder(3)
- olduname(2)
- getcpu(2)
- setns(2)
- asinhl(3)
- wcscasecmp(3)
- nearbyintl(3)
- atan2f(3)
- wctob(3)
- nextdownf(3)
- gmtime_r(3)
- fmal(3)
- setfsgid32(2)
- dlinfo(3)
- posix_spawnp(3)
- fgets_unlocked(3)
- major(3)
- fseek(3)
- xdr_callhdr(3)
- execve(2)
- exit(3)
- makecontext(3)
- sysctl(2)
- oldolduname(2)
- getgrouplist(3)
- pthread_getattr_np(3)
- ffs(3)
- sem_init(3)
- gcvt(3)
- fts_children(3)
- rt_sigreturn(2)
- mallinfo(3)
- insl(2)
- geteuid(2)
- signalfd(2)
- erfcl(3)
- sched_get_priority_min(2)
- sched_setaffinity(2)
- wcsrchr(3)
- xdr_reference(3)
- snprintf(3)
- delete_module(2)
- j0f(3)
- malloc_hook(3)
- casinf(3)
- y0f(3)
- endgrent(3)
- y1l(3)
- pthread_create(3)
- wcsncasecmp(3)
- pidfd_getfd(2)
- htobe64(3)
- _sysctl(2)
- lrand48_r(3)
- warnx(3)
- lgammaf_r(3)
- verrx(3)
- finit_module(2)
- gsignal(3)
- recvfrom(2)
- log2(3)
- fflush_unlocked(3)
- getaliasbyname_r(3)
- pthread_mutexattr_setrobust(3)
- getdirentries(3)
- getrpcbyname_r(3)
- ppoll(2)
- tmpfile(3)
- isupper_l(3)
- xdr_free(3)
- res_nquery(3)
- fts_open(3)
- shutdown(2)
- xdr_callmsg(3)
- coshl(3)
- ntp_gettimex(3)
- afs_syscall(2)
- be32toh(3)
- fchmodat(2)
- addseverity(3)
- pause(2)
- strcmp(3)
- mkostemps(3)
- wcsrtombs(3)
- scandir(3)
- __freadable(3)
- killpg(3)
- add_key(2)
- strcoll(3)
- migrate_pages(2)
- pthread_setattr_default_np(3)
- pthread_attr_setsigmask_np(3)
- sigabbrev_np(3)
- readdir(2)
- subpage_prot(2)
- strfromf(3)
- sysv_signal(3)
- gethostbyname2_r(3)
- outl_p(2)
- sync(2)
- pthread_attr_getinheritsched(3)
- socket(2)
- msgrcv(2)
- fgetws(3)
- pthread_cleanup_push_defer_np(3)
- getnetgrent_r(3)
- ynl(3)
- endservent(3)
- srand(3)
- endmntent(3)
- cbrtl(3)
- setitimer(2)
- pmap_rmtcall(3)
- svcerr_systemerr(3)
- fesetround(3)
- ilogbf(3)
- __fwriting(3)
- log1p(3)
- futimens(3)
- xdrrec_endofrecord(3)
- setreuid32(2)
- swab(3)
- pthread_spin_init(3)
- memchr(3)
- fminf(3)
- getipnodebyname(3)
- msgop(2)
- wait(2)
- ether_aton_r(3)
- open_wmemstream(3)
- xdr_bool(3)
- pthread_tryjoin_np(3)
- xdr_int(3)
- inet_net_ntop(3)
- fdimf(3)
- srand48(3)
- xdr_setpos(3)
- asinf(3)
- program_invocation_name(3)
- write(2)
- mkdtemp(3)
- pthread_cleanup_pop(3)
- ptsname_r(3)
- lgammal_r(3)
- pthread_attr_getstackaddr(3)
- authunix_create(3)
- getpmsg(2)
- ceill(3)
- cexp2f(3)
- kcmp(2)
- setup(2)
- err(3)
- sync_file_range2(2)
- getpid(2)
- wcsncat(3)
- envz_get(3)
- futimes(3)
- mincore(2)
- herror(3)
- ether_line(3)
- feholdexcept(3)
- fputc(3)
- keyctl(2)
- timer_delete(2)
- posix_spawn(3)
- faccessat2(2)
- setnetgrent(3)
- pwrite(2)
- aio_read(3)
- shmget(2)
- acosh(3)
- sigdelset(3)
- __ppc_get_timebase(3)
- __flbf(3)
- dladdr1(3)
- argz_create_sep(3)
- mblen(3)
- gethostent(3)
- pciconfig_iobase(2)
- recvmmsg(2)
- isprint_l(3)
- csqrtf(3)
- wcstoimax(3)
- hsearch_r(3)
- svcudp_create(3)
- setreuid(2)
- le16toh(3)
- name_to_handle_at(2)
- strftime_l(3)
- pthread_attr_setschedparam(3)
- eventfd(2)
- atanhf(3)
- pthread_setspecific(3)
- pthread_cond_init(3)
- acosl(3)
- llistxattr(2)
- fputwc_unlocked(3)
- scanf(3)
- getmntent_r(3)
- getchar(3)
- res_ninit(3)
- error_one_per_line(3)
- sigsetmask(3)
- putwchar(3)
- llroundf(3)
- rt_sigpending(2)
- send(2)
- wcsstr(3)
- log2l(3)
- fmod(3)
- va_copy(3)
- res_search(3)
- res_nsend(3)
- res_query(3)
- wait3(2)
- encrypt_r(3)
- system(3)
- close_range(2)
- ecvt_r(3)
- read(2)
- auth_destroy(3)
- realloc(3)
- pipe2(2)
- dn_expand(3)
- timerclear(3)
- get_avphys_pages(3)
- mbsnrtowcs(3)
- strtok(3)
- fwide(3)
- __ppc_get_timebase_freq(3)
- gai_suspend(3)
- stpcpy(3)
- lldiv(3)
- iswxdigit(3)
- posix_openpt(3)
- s390_pci_mmio_write(2)
- pthread_spin_destroy(3)
- callrpc(3)
- getifaddrs(3)
- aio_suspend(3)
- fread_unlocked(3)
- get_nprocs_conf(3)
- getuid(2)
- spu_run(2)
- termios(3)
- umask(2)
- csqrtl(3)
- register_printf_modifier(3)
- sem_trywait(3)
- tee(2)
- msync(2)
- mpool(3)
- setdomainname(2)
- fopencookie(3)
- nl_langinfo(3)
- sockatmark(3)
- getspent_r(3)
- casinhl(3)
- fdiml(3)
- ntohs(3)
- fgets(3)
- time(2)
- casinl(3)
- pthread_detach(3)
- seccomp_unotify(2)
apt-get install manpages-dev
Available languages:
en fr ru deManual
ptrace
NOMBIBLIOTHĂQUE
SYNOPSIS
DESCRIPTION
Mort sous ptrace
Ătats arrĂȘtĂ©s
ArrĂȘt-distribution-signal
Injection et suppression de signal
ArrĂȘt-groupe
ArrĂȘts PTRACE_EVENT
ArrĂȘts-appel-systĂšme
ArrĂȘts PTRACE_EVENT_SECCOMP (Linux 3.5 Ă Linux 4.7)
ArrĂȘts PTRACE_EVENT_SECCOMP (depuis Linux 4.8)
ArrĂȘts PTRACE_SINGLESTEP
Commandes ptrace dâinformation et de redĂ©marrage
Attachement et détachement
execve(2) sous ptrace
Vrai parent
VALEUR RENVOYĂE
ERREURS
STANDARDS
HISTORIQUE
NOTES
VĂ©rification du mode dâaccĂšs ptrace
/proc/sys/kernel/yama/ptrace_scope
Différences entre bibliothÚque C et noyau
BOGUES
VOIR AUSSI
TRADUCTION
NOM
ptrace - Suivre un processus
BIBLIOTHĂQUE
BibliothĂšque C standard ( libc , -lc )
SYNOPSIS
#include <sys/ptrace.h>
long
ptrace(enum __ptrace_request
op
, pid_t
pid
,
void *
addr
, void *
data
);
DESCRIPTION
Lâappel systĂšme ptrace () fournit Ă un processus (lâ« observateur ») un moyen dâobserver et de contrĂŽler lâexĂ©cution dâun autre processus (lâ« observé »), et dâexaminer et Ă©diter la mĂ©moire et les registres de lâobservĂ©. Lâutilisation principale de cette fonction est lâimplĂ©mentation de points dâarrĂȘt pour le dĂ©bogage, et pour suivre les appels systĂšme.
Un observĂ© doit dâabord ĂȘtre attachĂ© Ă lâobservateur. Lâattachement et les commandes suivantes sont par thread : dans un processus multithreadĂ©, chaque thread peut ĂȘtre attachĂ© individuellement Ă un observateur (Ă©ventuellement diffĂ©rent), ou ĂȘtre laissĂ© dĂ©tachĂ© et donc non dĂ©boguĂ©. Par consĂ©quent, lâ« observé » signifie toujours « (un) thread », jamais « un processus (Ă©ventuellement multithreadĂ©) ». Les commandes ptrace sont toujours envoyĂ©es Ă un observĂ© spĂ©cifique en utilisant un appel de la forme
ptrace(PTRACE_truc, pid, ...)
oĂč pid est lâidentifiant de thread du thread Linux correspondant.
(Remarquez que dans cette page, un « processus multithreadé » signifie un groupe de threads constituĂ© de threads créés en utilisant lâattribut CLONE_THREAD de clone (2).)
Un processus peut dĂ©marrer un suivi en appelant fork (2) et faire en sorte que lâenfant créé fasse un PTRACE_TRACEME , suivi (en gĂ©nĂ©ral) par un execve (2). Autrement, un processus peut commencer Ă suivre un autre processus en utilisant PTRACE_ATTACH ou PTRACE_SEIZE .
LâobservĂ© sâarrĂȘtera Ă chaque fois quâun signal lui sera distribuĂ©, mĂȘme si le signal est ignorĂ© (Ă lâexception de SIGKILL qui a les effets habituels). Lâobservateur sera prĂ©venu Ă son prochain appel de waitpid (2) (ou un des appels systĂšme liĂ©s à « wait ») ; cet appel renverra une valeur status contenant les renseignements indiquant la raison de lâarrĂȘt de lâobservĂ©. Lorsque lâobservĂ© est arrĂȘtĂ©, lâobservateur peut utiliser plusieurs opĂ©rations ptrace pour inspecter et modifier lâobservĂ©. Lâobservateur peut Ă©galement laisser continuer lâexĂ©cution de lâobservĂ©, en ignorant Ă©ventuellement le signal ayant dĂ©clenchĂ© lâarrĂȘt, ou mĂȘme en envoyant un autre signal.
Si lâoption PTRACE_O_TRACEEXEC nâest pas effective, tous les appels rĂ©ussis dâ execve (2) par le processus suivi dĂ©clencheront lâenvoi dâun signal SIGTRAP , ce qui permet au parent de reprendre le contrĂŽle avant que le nouveau programme commence son exĂ©cution.
Quand lâobservateur a fini le suivi, il peut forcer lâobservĂ© Ă continuer normalement, en mode non suivi, avec PTRACE_DETACH .
La valeur de
lâargument
op
indique précisément
lâopĂ©ration Ă entreprendre.
PTRACE_TRACEME
Le processus en cours va ĂȘtre suivi par son parent. Un processus ne devrait sans doute pas envoyer cette opĂ©ration si son parent nâest pas prĂȘt Ă le suivre. Dans cette requĂȘte pid , addr , et data sont ignorĂ©s.
LâopĂ©ration PTRACE_TRACEME ne sert quâĂ lâobservĂ©. Les opĂ©rations restantes ne servent quâĂ lâobservateur. Dans les observations suivantes, pid prĂ©cise lâidentifiant de thread de lâobservĂ© sur lequel agir. Pour dâautres opĂ©rations que PTRACE_ATTACH , PTRACE_SEIZE , PTRACE_INTERRUPT et PTRACE_KILL , lâobservĂ© doit ĂȘtre arrĂȘtĂ©.
PTRACE_PEEKTEXT
PTRACE_PEEKDATA
Lire un mot Ă lâadresse addr dans lâespace mĂ©moire de lâobservĂ© et le renvoyer en rĂ©sultat de lâappel ptrace (). Linux ne sĂ©pare pas les espaces dâadressage de code et de donnĂ©es, donc ces deux opĂ©rations sont Ă©quivalentes ( data est ignorĂ©, consultez la section NOTES).
PTRACE_PEEKUSER
Lire un mot Ă la position addr dans lâespace USER de lâobservĂ©, qui contient les registres et divers renseignements sur le processus (voir <sys/user.h> ). Le mot est renvoyĂ©e en rĂ©sultat de ptrace (). En principe, lâadresse doit ĂȘtre alignĂ©e sur une frontiĂšre de mots, bien que cela varie selon les architectures. Consultez la section NOTES . ( data est ignorĂ©, consultez la section NOTES ).
PTRACE_POKETEXT
PTRACE_POKEDATA
Copier le mot data vers lâadresse addr de la mĂ©moire de lâobservĂ©. Comme pour PTRACE_PEEKTEXT et PTRACE_PEEKDATA , ces deux opĂ©rations sont Ă©quivalentes.
PTRACE_POKEUSER
Copier le mot data vers lâadresse addr dans lâespace USER de lâobservĂ©. Comme pour PTRACE_PEEKUSER , les emplacements doivent ĂȘtre alignĂ©s sur une frontiĂšre de mot. Pour maintenir lâintĂ©gritĂ© du noyau, certaines modifications de la zone USER sont interdites.
PTRACE_GETREGS
PTRACE_GETFPREGS
Copier les registres gĂ©nĂ©raux ou du processeur en virgule flottante de lâobservĂ©, vers lâadresse data de lâobservateur. Consultez <sys/user.h> pour les dĂ©tails sur le format de ces donnĂ©es ( addr est ignorĂ©). Remarquez que les systĂšmes SPARC ont la signification de data et addr inversĂ©e, câest-Ă -dire que data est ignorĂ© et les registres sont copiĂ©s vers lâadresse addr . PTRACE_GETREGS et PTRACE_GETFPREGS ne sont pas prĂ©sents sur toutes les architectures.
PTRACE_GETREGSET (depuis Linux 2.6.34)
Lire les registres de lâobservĂ©. addr indique, de maniĂšre dĂ©pendante de lâarchitecture, le type de registres Ă lire. NT_PRSTATUS (avec une valeur numĂ©rique de 1) a pour consĂ©quence habituelle la lecture de registres gĂ©nĂ©raux. Si le processeur a, par exemple, des registres en virgule flottante ou en vecteur, ils peuvent ĂȘtre rĂ©cupĂ©rĂ© en configurant addr Ă la constante NT_foo correspondante. data pointe vers une struct iovec , qui dĂ©crit lâemplacement et la taille du tampon de destination. Le noyau modifie iov.len au retour pour indiquer le vĂ©ritable nombre dâoctets renvoyĂ©s.
PTRACE_SETRGS
PTRACE_SETFPREGS
Modifier les registres gĂ©nĂ©raux ou du processeur en virgule flottante de lâobservĂ©, depuis lâadresse data de lâobservateur. Comme pour PTRACE_POKEUSER , certaines modifications de registres gĂ©nĂ©raux pourraient ĂȘtre interdites ( addr est ignorĂ©). Remarquez que les systĂšmes SPARC ont la signification de data et addr inversĂ©e, câest-Ă -dire que data est ignorĂ© et les registres sont copiĂ©s depuis lâadresse addr . PTRACE_SETREGS et PTRACE_SETFPREGS ne sont pas prĂ©sents sur toutes les architectures.
PTRACE_SETREGSET (depuis Linux 2.6.34)
Modifier les registres de lâobservĂ©. La signification de addr et data est analogue Ă PTRACE_GETREGSET .
PTRACE_GETSIGINFO (depuis Linux 2.3.99-pre6)
RĂ©cupĂ©rer des renseignements sur le signal qui a provoquĂ© lâarrĂȘt. Pour ce faire, copier une structure siginfo_t (consultez sigaction (2)) de lâobservĂ© Ă lâadresse data de lâobservateur ( addr est ignorĂ©).
PTRACE_SETSIGINFO (depuis Linux 2.3.99-pre6)
DĂ©finir les renseignements de signaux : copier une structure siginfo_t de lâadresse data de lâobservateur vers lâobservĂ©. Cela nâaffecte que les signaux qui auraient dĂ» ĂȘtre distribuĂ©s Ă lâobservĂ© et ont Ă©tĂ© interceptĂ©s Ă cause de ptrace (). DiffĂ©rencier ces signaux normaux des signaux créés par ptrace () lui-mĂȘme peut ĂȘtre dĂ©licat ( addr est ignorĂ©).
PTRACE_PEEKSIGINFO (depuis Linux 3.10)
RĂ©cupĂ©rer les structures siginfo_t sans supprimer les signaux dâune file dâattente. addr pointe vers une structure ptrace_peeksiginfo_args qui indique la position ordinale Ă partir de laquelle la copie des signaux devrait commencer et le nombre de signaux Ă copier. Les structures siginfo_t sont copiĂ©es dans le tampon pointĂ© par data . La valeur de retour contient le nombre de signaux copiĂ©s (zĂ©ro indique quâil nây a pas de signal correspondant Ă la position ordinale indiquĂ©e). Dans les structures siginfo renvoyĂ©es, le champ si_code contient des renseignements ( __SI_CHLD , __SI_FAULT , etc.) qui sinon ne sont pas exposĂ©s Ă lâespace utilisateur.
struct
ptrace_peeksiginfo_args {
u64 off; /* Position ordinale dans la file dâattente
oĂč commencer la copie de signaux */
u32 flags; /* PTRACE_PEEKSIGINFO_SHARED ou 0 */
s32 nr; /* Nombre de signaux Ă copier */
};
Actuellement, seul lâattribut PTRACE_PEEKSIGINFO_SHARED permet de vider les signaux de la file de signaux par processus. Si cet attribut nâest pas dĂ©fini, les signaux sont lus depuis la file par thread du thread indiquĂ©.
PTRACE_GETSIGMASK (depuis Linux 3.11)
Placer une copie du masque des signaux bloquĂ©s (consultez sigprocmask (2)) dans le tampon pointĂ© par data qui devrait ĂȘtre un pointeur vers un tampon de type sigset_t . Lâargument addr contient la taille du tampon pointĂ© par data (câest-Ă -dire sizeof(sigset_t) ).
PTRACE_SETSIGMASK (depuis Linux 3.11)
Modifier le masque des signaux bloquĂ©s (consultez sigprocmask (2)) Ă la valeur indiquĂ©e dans le tampon pointĂ© par data qui devrait ĂȘtre un pointeur vers un tampon de type sigset_t . Lâargument addr contient la taille du tampon pointĂ© par data (câest-Ă -dire sizeof(sigset_t) ).
PTRACE_SETOPTIONS
(depuis
Linux 2.4.6, consultez les remarques de
BOGUES
)
Définir les options de
ptrace Ă partir de lâadresse
data
(
addr
est ignoré).
data
est
interprĂ©tĂ© comme un masque dâoptions,
qui est construit Ă partir des attributs suivants.
PTRACE_O_EXITKILL
(depuis Linux 3.8)
Envoyer un signal SIGKILL Ă lâobservĂ© si lâobservateur existe. Cet option est utile pour les gardiens ptrace qui veulent sâassurer que les observĂ©s ne peuvent jamais Ă©chapper au contrĂŽle de lâobservateur.
PTRACE_O_TRACECLONE (depuis Linux 2.5.46)
ArrĂȘter lâobservĂ© au prochain clone (2) et commencer automatiquement Ă suivre le nouveau processus clonĂ©, qui dĂ©marrera avec un signal SIGSTOP , ou PTRACE_EVENT_STOP si PTRACE_SEIZE est utilisĂ©. Un waitpid (2) par lâobservateur renverra une valeur status comme
status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8))
Le PID du nouveau processus peut ĂȘtre rĂ©cupĂ©rĂ© avec PTRACE_GETEVENTMSG .
Cette option peut ne pas intercepter tous les appels clone (2). Si lâobservĂ© appelle clone (2) avec lâattribut CLONE_VFORK , PTRACE_EVENT_VFORK sera envoyĂ© si PTRACE_O_TRACEVFORK est utilisĂ©. Sinon, si lâobservĂ© appelle clone (2) avec SIGCHLD comme signal de terminaison, PTRACE_EVENT_FORK sera envoyĂ© si PTRACE_O_TRACEFORK est utilisĂ©.
PTRACE_O_TRACEEXEC (depuis Linux 2.5.46)
ArrĂȘter lâobservĂ© au prochain execve (2). Un waitpid (2) par lâobservateur renverra une valeur status comme
status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))
Si le thread en cours dâexĂ©cution nâest pas un leader de groupe de threads, lâidentifiant de thread est rĂ©initialisĂ© Ă lâidentifiant du leader de groupe de threads avant cet arrĂȘt. Depuis Linux 3.0, le premier identifiant de thread peut ĂȘtre rĂ©cupĂ©rĂ© avec PTRACE_GETEVENTMSG .
PTRACE_O_TRACEEXIT (depuis Linux 2.5.60)
ArrĂȘter lâobservĂ© Ă la terminaison. Un waitpid (2) par lâobservateur renverra une valeur status comme
status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))
LâĂ©tat de fin de lâobservĂ© peut ĂȘtre rĂ©cupĂ©rĂ© avec PTRACE_GETEVENTMSG .
LâobservĂ© est arrĂȘtĂ© tĂŽt dans la terminaison du processus, alors que les registres sont toujours disponibles, ce qui permet au processus utilisant ptrace () de voir oĂč la terminaison sâest produite, alors que la notification de terminaison normale a lieu Ă la fin de cette terminaison. MĂȘme si le contexte est disponible, lâobservateur ne peut pas empĂȘcher la terminaison Ă ce moment lĂ .
PTRACE_O_TRACEFORK (depuis Linux 2.5.46)
ArrĂȘter lâobservĂ© au prochain fork (2) et commencer automatiquement Ă suivre le nouveau processus créé, qui dĂ©marrera avec un signal SIGSTOP , ou PTRACE_EVENT_STOP si PTRACE_SEIZE est utilisĂ©. Un waitpid (2) par lâobservateur renverra une valeur status comme
status>>8 == (SIGTRAP | (PTRACE_EVENT_FORK<<8))
Le PID du nouveau processus peut ĂȘtre rĂ©cupĂ©rĂ© avec PTRACE_GETEVENTMSG .
PTRACE_O_TRACESYSGOOD (depuis Linux 2.4.6)
Lors des interceptions dâappel systĂšme, positionner le bit 7 sur le numĂ©ro de signal (envoyer SIGTRAP|0x80 ). Cela facilite pour lâobservateur la distinction entre les interceptions normales et celles provoquĂ©es par un appel systĂšme.
PTRACE_O_TRACEVFORK (depuis Linux 2.5.46)
ArrĂȘter lâobservĂ© au prochain vfork (2) et commencer automatiquement Ă suivre le nouveau processus créé, qui dĂ©marrera avec un signal SIGSTOP , ou PTRACE_EVENT_STOP si PTRACE_SEIZE est utilisĂ©. Un waitpid (2) par lâobservateur renverra une valeur status comme
status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK<<8))
Le PID du nouveau processus peut ĂȘtre rĂ©cupĂ©rĂ© avec PTRACE_GETEVENTMSG .
PTRACE_O_TRACEVFORKDONE (depuis Linux 2.5.60)
ArrĂȘter lâobservĂ© Ă la fin du prochain vfork (2). Un waitpid (2) par lâobservateur renverra une valeur status comme
status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK_DONE<<8))
Le PID du nouveau processus peut (depuis Linux 2.6.18) ĂȘtre rĂ©cupĂ©rĂ© avec PTRACE_GETEVENTMSG .
PTRACE_O_TRACESECCOMP (depuis Linux 3.5)
ArrĂȘter lâobservĂ© quand une rĂšgle SECCOMP_RET_TRACE de seccomp (2) est dĂ©clenchĂ©e. Un waitpid (2) par lâobservateur renverra une valeur status comme
status>>8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP<<8))
Si cela entraĂźne un arrĂȘt PTRACE_EVENT , câest Ă©quivalent Ă un arrĂȘt-entrĂ©e-appel-systĂšme. Pour des dĂ©tails, voir la remarque sur PTRACE_EVENT_SECCOMP ci-dessous. Les donnĂ©es du message de lâĂ©vĂ©nement seccomp (issues de la partie SECCOMP_RET_DATA de la rĂšgle du filtre seccomp) peuvent ĂȘtre rĂ©cupĂ©rĂ©es avec PTRACE_GETEVENTMSG .
PTRACE_O_SUSPEND_SECCOMP (depuis Linux 4.3)
Suspendre les protections seccomp de lâobservĂ©. Cela sâapplique quel que soit le mode et peut ĂȘtre utilisĂ© lorsque lâobservĂ© nâa pas encore installĂ© de filtres seccomp. Cela veut dire quâun cas dâutilisation valable consiste Ă suspendre les protections seccomp dâun observĂ© avant quâelles ne soient installĂ©es par lâobservĂ©, laisser lâobservĂ© installer les filtres et vider cet attribut quand les filtres doivent ĂȘtre rĂ©activĂ©s. La dĂ©finition de cette option implique que lâobservateur ait la capacitĂ© CAP_SYS_ADMIN , nâait pas de protection seccomp installĂ©e et nâait pas de PTRACE_O_SUSPEND_SECCOMP positionnĂ© sur lui-mĂȘme.
PTRACE_GETEVENTMSG (depuis Linux 2.5.46)
RĂ©cupĂ©rer un message (dans un unsigned long ) concernant lâĂ©vĂ©nement ptrace qui vient dâarriver, en le plaçant Ă lâadresse data de lâobservateur. Pour PTRACE_EVENT_EXIT , il sâagit du code de retour de lâobservĂ©. Pour PTRACE_EVENT_FORK , PTRACE_EVENT_VFORK , PTRACE_EVENT_VFORK_DONE et PTRACE_EVENT_CLONE , il sâagit du PID du nouveau processus. Pour PTRACE_EVENT_SECCOMP , il sâagit des SECCOMP_RET_DATA du filtre seccomp (2) associĂ©es Ă la rĂšgle dĂ©clenchĂ©e ( addr est ignorĂ©e).
PTRACE_CONT
RedĂ©marrer lâobservĂ© arrĂȘtĂ©. Si data est non nul, il est interprĂ©tĂ© comme un numĂ©ro de signal Ă distribuer Ă lâobservé ; sinon aucun signal nâest distribuĂ©. Lâobservateur peut ainsi contrĂŽler si un signal envoyĂ© Ă lâobservĂ© doit lui ĂȘtre distribuĂ© ou non ( addr est ignorĂ©).
PTRACE_SYSCALL
PTRACE_SINGLESTEP
RedĂ©marrer lâobservĂ© arrĂȘtĂ© comme pour PTRACE_CONT , mais en sâarrangeant pour quâil soit arrĂȘtĂ© Ă la prochaine entrĂ©e ou sortie dâun appel systĂšme, ou aprĂšs la prochaine instruction, respectivement (lâobservĂ© sera aussi arrĂȘtĂ© par lâarrivĂ©e dâun signal). Du point de vue de lâobservateur, lâobservĂ© semblera ĂȘtre arrĂȘtĂ© par SIGTRAP . Ainsi, pour PTRACE_SYSCALL lâidĂ©e est dâinspecter les arguments de lâappel systĂšme au premier arrĂȘt puis de faire un autre PTRACE_SYSCALL et dâinspecter la valeur de retour au second arrĂȘt. Le paramĂštre data est interprĂ©tĂ© comme pour PTRACE_CONT ( addr est ignorĂ©).
PTRACE_SET_SYSCALL (depuis Linux 2.6.16)
Lorsquâil est en arrĂȘt-entrĂ©e-appel-systĂšme, passer le numĂ©ro de lâappel systĂšme qui va ĂȘtre exĂ©cutĂ© Ă celui indiquĂ© dans le paramĂštre data . Le paramĂštre addr est ignorĂ©. Cette opĂ©ration nâest actuellement prise en charge que sur arm (et arm64, quoique uniquement Ă des fins de rĂ©trocompatibilitĂ©), mais la plupart des autres architectures ont dâautres moyens de faire cela (en gĂ©nĂ©ral en modifiant le registre qui a passĂ© lâappel systĂšme au code au niveau de lâutilisateur).
PTRACE_SYSEMU
PTRACE_SYSEMU_SINGLESTEP
(depuis Linux 2.6.14)
Pour PTRACE_SYSEMU , continuer puis sâarrĂȘter lors du prochain appel systĂšme, qui ne sera pas exĂ©cutĂ©. Voir la documentation des syscall-stops ci-dessous. Pour PTRACE_SYSEMU_SINGLESTEP , faire la mĂȘme chose, mais exĂ©cuter pas Ă pas sâil ne sâagit pas dâun appel systĂšme. Cette fonction est utilisĂ©e par des programmes comme User Mode Linux, qui veulent Ă©muler tous les appels systĂšme de lâobservĂ©. Le paramĂštre data est interprĂ©tĂ© comme pour PTRACE_CONT . Lâargument addr est ignorĂ©. Ces opĂ©rations ne sont pour lâinstant disponibles que sur x86.
PTRACE_LISTEN (depuis Linux 3.4)
RedĂ©marrer lâobservĂ© arrĂȘtĂ©, mais en lâempĂȘchant de sâexĂ©cuter. LâĂ©tat rĂ©sultant de lâobservĂ© est similaire a celui dâun processus qui a Ă©tĂ© arrĂȘtĂ© par un SIGSTOP (ou autre signal dâarrĂȘt). Consultez la sous-section ArrĂȘt-groupe pour des renseignements supplĂ©mentaires. PTRACE_LISTEN ne fonctionne que sur les observĂ©s attachĂ©s par PTRACE_SEIZE .
PTRACE_KILL
Envoyer Ă lâobservĂ© un signal SIGKILL pour le terminer ( addr et data sont ignorĂ©s).
Cette opĂ©ration est obsolĂšte, ne lâutilisez pas. Ă la place, envoyez un SIGKILL directement en utilisant kill (2) ou tgkill (2). Le problĂšme avec PTRACE_KILL est quâil nĂ©cessite que lâobservĂ© soit en arrĂȘt-distribution-signal, sinon cela risque de ne pas fonctionner (câest-Ă -dire risque de se terminer avec succĂšs sans tuer lâobservĂ©). En revanche, envoyer SIGKILL directement nâest pas concernĂ© par cette limite.
PTRACE_INTERRUPT (depuis Linux 3.4)
ArrĂȘter un observĂ©. Si lâobservĂ© est en cours dâexĂ©cution ou en sommeil dans lâespace utilisateur et que PTRACE_SYSCALL est effectif, lâappel systĂšme est interrompu et lâarrĂȘt-sortie-appel-systĂšme est signalĂ© (lâappel systĂšme interrompu est redĂ©marrĂ© quand lâobservĂ© est redĂ©marrĂ©). Si lâobservĂ© avait dĂ©jĂ Ă©tĂ© arrĂȘtĂ© par un signal et que PTRACE_LISTEN lui avait Ă©tĂ© envoyĂ©, lâobservĂ© sâarrĂȘte avec PTRACE_EVENT_STOP et WSTOPSIG(status) renvoie le signal dâarrĂȘt. Si nâimporte quel autre arrĂȘt-ptrace est créé en mĂȘme temps (par exemple, si un signal est envoyĂ© Ă lâobservĂ©), cet arrĂȘt-ptrace arrive. Si rien de ce qui prĂ©cĂšde ne sâapplique (par exemple si lâobservĂ© est en cours dâexĂ©cution en espace utilisateur), il sâarrĂȘte avec PTRACE_EVENT_STOP avec WSTOPSIG(status) == SIGTRAP . PTRACE_INTERRUPT ne fonctionne que sur les observĂ©s attachĂ©s par PTRACE_SEIZE .
PTRACE_ATTACH
Attacher le processus numĂ©ro pid , pour le suivre. LâobservĂ© va recevoir un SIGSTOP , mais il ne sera peut-ĂȘtre pas arrĂȘtĂ© tout de suite, utilisez waitid (2) pour attendre son arrĂȘt. Consultez la sous-section Attachement et dĂ©tachement pour obtenir de plus amples renseignements ( addr et data sont ignorĂ©s).
Le droit dâeffectuer un PTRACE_ATTACH est gĂ©rĂ© par la vĂ©rification PTRACE_MODE_ATTACH_REALCREDS du mode dâaccĂšs de ptrace ; voir ci-dessous.
PTRACE_SEIZE (depuis Linux 3.4)
Attacher au processus indiquĂ© dans pid , en faire un observĂ© du processus appelant. Contrairement Ă PTRACE_ATTACH , PTRACE_SEIZE nâarrĂȘte pas le processus. Les arrĂȘts-groupe sont signalĂ©s en tant que PTRACE_EVENT_STOP et WSTOPSIG(status) renvoie le signal dâarrĂȘt. Les enfants automatiquement attachĂ©s avec PTRACE_EVENT_STOP et WSTOPSIG(status) renvoient SIGTRAP au lieu de recevoir un signal SIGSTOP . execve (2) nâenvoie pas dâautres SIGTRAP . Seul un processus PTRACE_SEIZE Ă© peut accepter des commandes PTRACE_INTERRUPT et PTRACE_LISTEN . Le comportement « seized » qui vient dâĂȘtre dĂ©crit est rĂ©cupĂ©rĂ© par les enfants automatiquement attachĂ©s en utilisant PTRACE_O_TRACEFORK , PTRACE_O_TRACEVFORK et PTRACE_O_TRACECLONE . addr doit ĂȘtre de zĂ©ro. data contient un masque de bit des options ptrace Ă activer immĂ©diatement.
Le droit dâeffectuer un PTRACE_SEIZE est gĂ©rĂ© par une vĂ©rification PTRACE_MODE_ATTACH_REALCREDS du mode dâaccĂšs ptrace ; voir ci-dessous.
PTRACE_SECCOMP_GET_FILTER (depuis Linux 4.4)
Cette opĂ©ration autorise lâobservateur Ă vider les filtres BPF classiques de lâobservĂ©.
addr est un entier indiquant lâindex du filtre Ă vider. Le filtre le plus rĂ©cemment installĂ© a le numĂ©ro dâindex 0 . Si addr est supĂ©rieur aux numĂ©ros des filtres installĂ©s, lâopĂ©ration Ă©choue avec lâerreur ENOENT .
data est soit un pointeur vers un tableau struct sock_filter assez grand pour stocker le programme BPF, soit NULL si le programme ne va pas ĂȘtre stockĂ©.
En cas de succĂšs, le code de retour est le nombre dâinstructions du programme BPF. Si data Ă©tait NULL, ce code de retour peut ĂȘtre utilisĂ© pour dimensionner correctement le tableau struct sock_filter passĂ© dans un appel ultĂ©rieur.
Cette opĂ©ration Ă©choue avec lâerreur EACCES si lâappelant nâa pas la capacitĂ© CAP_SYS_ADMIN ou sâil est en mode seccomp filtrĂ© ou restreint. Si le filtre auquel renvoie addr nâest pas un filtre BPF classique, lâopĂ©ration Ă©choue avec lâerreur EMEDIUMTYPE .
Cette opĂ©ration nâest disponible que si le noyau a Ă©tĂ© configurĂ© avec les options CONFIG_SECCOMP_FILTER et CONFIG_CHECKPOINT_RESTORE .
PTRACE_DETACH
Relancer lâobservĂ© arrĂȘtĂ© comme avec PTRACE_CONT , mais en commençant par sâen dĂ©tacher. Sous Linux un observĂ© peut ĂȘtre dĂ©tachĂ© ainsi quelque soit la mĂ©thode employĂ©e pour dĂ©marrer le suivi ( addr est ignorĂ©).
PTRACE_GET_THREAD_AREA (depuis Linux 2.6.0)
Cette opĂ©ration effectue une tĂąche identique Ă get_thread_area (2). Elle lit lâentrĂ©e TLS dans le GDT dont lâindex est donnĂ© dans addr , mettant une copie de lâentrĂ©e dans la struct user_desc vers laquelle pointe data (contrairement Ă get_thread_area (2), entry_number de la struct user_desc est ignorĂ©e).
PTRACE_SET_THREAD_AREA (depuis Linux 2.6.0)
Cette opĂ©ration effectue la mĂȘme tĂąche que set_thread_area (2). Elle positionne lâentrĂ©e TLS dans le GDT dont lâindex est donnĂ© dans addr , en lui affectant les donnĂ©es fournies dans la struct user_desc vers laquelle pointe data (contrairement Ă set_thread_area (2), entry_number de la struct user_desc est ignorĂ©e ; autrement dit, cette opĂ©ration de ptrace ne peut pas ĂȘtre utilisĂ©e pour affecter une entrĂ©e TLS libre).
PTRACE_GET_SYSCALL_INFO (depuis Linux 5.3)
RĂ©cupĂ©rer des informations sur lâappel systĂšme qui a provoquĂ© lâarrĂȘt. Les informations sont placĂ©es dans le tampon vers lequel pointe le paramĂštre data , lequel doit ĂȘtre un pointeur vers un tampon de type struct ptrace_syscall_info . Le paramĂštre addr contient la taille du tampon vers lequel pointe le paramĂštre data (Ă savoir sizeof(struct ptrace_syscall_info) ). Le code de retour contient le nombre dâoctets que le noyau peut Ă©crire. Si la taille des donnĂ©es que le noyau doit Ă©crire dĂ©passe celle indiquĂ©e par le paramĂštre addr , les donnĂ©es de sortie sont tronquĂ©es.
La structure ptrace_syscall_info contient les champs suivants :
struct
ptrace_syscall_info {
__u8 op; /* Type dâappel systĂšme
dâarrĂȘt */
__u32 arch; /* Valeur AUDIT_ARCH_*Â ; voir seccomp(2) */
__u64 instruction_pointer; /* Pointeur vers
lâinstruction du processeur */
__u64 stack_pointer; /* Pointeur vers la pile du processeur
*/
union {
struct { /* op == PTRACE_SYSCALL_INFO_ENTRY */
__u64 nr; /* NumĂ©ro de lâappel systĂšme
*/
__u64 args[6]; /* ParamĂštres de lâappel
systĂšme */
} entry;
struct { /* op == PTRACE_SYSCALL_INFO_EXIT */
__s64 rval; /* Code de retour de lâappel
systĂšme */
__u8 is_error; /* Attribut dâerreur de lâappel
systÚme ;
Booléen : rval contient-il
un code dâerreur (-ERRCODE) ou
un code de retour de non erreur ? */
} exit;
struct { /* op == PTRACE_SYSCALL_INFO_SECCOMP */
__u64 nr; /* NumĂ©ro de lâappel systĂšme
*/
__u64 args[6]; /* ParamĂštres de lâappel
systĂšme */
__u32 ret_data; /* Partie SECCOMP_RET_DATA de la valeur
de retour de SECCOMP_RET_TRACE */
} seccomp;
};
};
Les champs op , arch , instruction_pointer et stack_pointer sont dĂ©finis pour tous les types dâarrĂȘts de lâappel systĂšme ptrace. Le reste de la structure est une union ; on ne doit lire que les champs significatifs pour le type dâarrĂȘt de lâappel systĂšme indiquĂ© par le champ op .
Le champ
op
prend une des valeurs suivantes (définies
dans
<linux/ptrace.h>
), indiquant le type
dâarrĂȘt qui sâest produit et la partie
remplie de lâunion :
PTRACE_SYSCALL_INFO_ENTRY
Le composant entry de lâunion contient des informations liĂ©es Ă un arrĂȘt dâentrĂ©e appel systĂšme.
PTRACE_SYSCALL_INFO_EXIT
Le composant exit de lâunion contient des informations sur un arrĂȘt de sortie dâappel systĂšme.
PTRACE_SYSCALL_INFO_SECCOMP
Le composant seccomp de lâunion contient des informations concernant un arrĂȘt PTRACE_EVENT_SECCOMP .
PTRACE_SYSCALL_INFO_NONE
Aucun composant de lâunion ne contient dâinformations pertinentes.
Dans le cas oĂč une entrĂ©e ou une sortie dâappel systĂšme sâinterrompt, les donnĂ©es renvoyĂ©es par PTRACE_GET_SYSCALL_INFO sont limitĂ©es au type PTRACE_SYSCALL_INFO_NONE Ă moins que lâoption PTRACE_O_TRACESYSGOOD ne soit dĂ©finie avant que lâarrĂȘt de lâappel systĂšme correspondant se produise.
Mort sous ptrace
Quand un processus (Ă©ventuellement multithreadĂ©) reçoit un signal pour le tuer (un dont la disposition est configurĂ©e Ă SIG_DFL et dont lâaction par dĂ©faut est de tuer le processus), tous les threads se terminent. Chaque observĂ© signale sa mort Ă son ou ses observateurs. La notification de cet Ă©vĂ©nement est distribuĂ©e par waitpid (2).
Remarquez que le signal tueur provoquera dâabord un arrĂȘt-distribution-signal (sur un seul observĂ©) et, seulement aprĂšs ĂȘtre injectĂ© par lâobservateur (ou aprĂšs ĂȘtre envoyĂ© Ă un thread qui nâest pas suivi), la mort du signal arrivera sur tous les observĂ©s dâun processus multithreadĂ© (le terme « arrĂȘt-distribution-signal » est expliquĂ© plus bas).
SIGKILL ne gĂ©nĂšre pas dâarrĂȘt-distribution-signal et lâobservateur ne peut par consĂ©quent pas le supprimer. SIGKILL tue mĂȘme Ă lâintĂ©rieur des appels systĂšmes (arrĂȘt-sortie-appel-systĂšme nâest pas créé avant la mort par SIGKILL ). Lâeffet direct est que SIGKILL tue toujours le processus (tout ses threads), mĂȘme si certains threads du processus sont suivis avec ptrace.
Quand lâobservĂ© appelle _exit (2), il signale sa mort Ă son observateur. Les autres threads ne sont pas concernĂ©s.
Quand nâimporte quel thread exĂ©cute exit_group (2), tous les observĂ©s de son groupe de threads signalent leur mort Ă leur observateur.
Si lâoption PTRACE_O_TRACEEXIT est active, PTRACE_EVENT_EXIT arrivera avant la mort rĂ©elle. Cela sâapplique aux terminaisons avec exit (2), exit_group (2) et aux morts de signal (sauf SIGKILL , selon la version du noyau ; voir les BOGUES ci-dessous), et lorsque les threads sont dĂ©truits par execve (2) dans un processus multithreadĂ©.
Lâobservateur ne peut pas assumer que lâobservĂ© arrĂȘtĂ©-ptrace existe. LâobservĂ© risque de mourir avant dâĂȘtre arrĂȘtĂ© dans plusieurs cas (comme avec SIGKILL ). Par consĂ©quent, le tracĂ© doit ĂȘtre prĂ©parĂ© pour traiter une erreur ESRCH sur nâimporte quelle opĂ©ration ptrace. Malheureusement, la mĂȘme erreur est renvoyĂ©e si lâobservĂ© existe mais nâest pas arrĂȘtĂ©-ptrace (pour les commandes qui nĂ©cessitent un observĂ© arrĂȘtĂ©), ou sâil nâest pas suivi par le processus qui a envoyĂ© lâappel ptrace. Lâobservateur doit garder une trace de lâĂ©tat arrĂȘtĂ© ou en fonctionnement de lâobservĂ©, et interprĂ©ter ESRCH comme « lâobservĂ© sâest achevĂ© de maniĂšre inattendue » seulement sâil sait que lâobservĂ© est effectivement entrĂ© en arrĂȘt-ptrace. Remarquez quâil nâest pas garanti que waitpid(WNOHANG) signale de façon fiable lâĂ©tat de mort de lâobservĂ© si une opĂ©ration ptrace renvoie ESRCH . waitpid(WNOHANG) pourrait plutĂŽt renvoyer 0 . Autrement dit, lâobservĂ© pourrait « ne pas ĂȘtre encore mort », mais dĂ©jĂ refuser des opĂ©rations ptrace.
Lâobservateur ne peut pas assumer que lâobservĂ© finit toujours sa vie en signalant WIFEXITED(status) ou WIFSIGNALED(status) ; dans certains cas ça nâarrive pas. Par exemple si un thread diffĂ©rent du leader de groupe de threads fait un execve (2), il disparaĂźt ; son PID ne sera plus jamais vu, tous les arrĂȘts suivants de ptrace seront signalĂ©s sous le PID du leader de groupe de threads.
Ătats arrĂȘtĂ©s
Deux Ă©tats existent pour un observé : en cours dâexĂ©cution ou Ă lâarrĂȘt. Du point de vue de ptrace, un observĂ© qui est bloquĂ© dans un appel systĂšme (comme read (2), pause (2), etc.) est nĂ©anmoins considĂ©rĂ© en cours dâexĂ©cution, mĂȘme si lâobservĂ© est bloquĂ© depuis longtemps. LâĂ©tat de lâobservĂ© aprĂšs PTRACE_LISTEN est en quelque sorte une zone dâombre : il nâest dans aucun arrĂȘt-ptrace (les commandes ptrace nâauront aucun effet sur lui et il distribuera des notifications waitpid (2)), mais il pourrait aussi ĂȘtre considĂ©rĂ© « arrĂȘté » parce quâil nâest pas en train dâexĂ©cuter des instructions (pas de programmation) et, sâil Ă©tait en arrĂȘt-groupe avant PTRACE_LISTEN , il ne rĂ©pondra pas aux signaux avant de recevoir SIGCONT .
De nombreuses sortes dâĂ©tats sont possibles quand lâobservĂ© est arrĂȘtĂ©, et les discussions dans ptrace sont souvent confondues. Par consĂ©quent, lâutilisation de termes prĂ©cis est importante.
Dans cette page de manuel, tous les Ă©tats dâarrĂȘt dans lesquels lâobservĂ© est prĂȘt Ă accepter des commandes ptrace de lâobservateur sont appelĂ©s arrĂȘt-ptrace . Les arrĂȘts-ptrace peuvent ensuite ĂȘtre sous-divisĂ©s en arrĂȘt-distribution-signal , arrĂȘt-groupe , arrĂȘt-appel-systĂšme , arrĂȘt-PTRACE_EVENT , etc. Ces Ă©tats dâarrĂȘt sont dĂ©crits en dĂ©tail ci-dessous.
Lorsque lâobservĂ© en cours dâexĂ©cution entre en arrĂȘt-ptrace, il avise son observateur en utilisant waitpid (2) (ou un des autres appels systĂšme « wait »). La plupart de cette page de manuel suppose que lâobservateur attend avec :
pid = waitpid(pid_ou_moins_1, &status, __WALL);
Les observĂ©s arrĂȘtĂ©s-ptrace sont signalĂ©s comme renvoyĂ©s avec un pid strictement positif et WIFSTOPPED(status) vrai.
Lâattribut __WALL ne contient pas les attributs WSTOPPED et WEXITED , mais implique leur fonctionnalitĂ©.
La configuration de lâattribut WCONTINUED en appelant waitpid (2) nâest pas conseillĂ©e : lâĂ©tat « exĂ©cuté » est relatif au processus et lâutiliser peut embrouiller le vrai parent de lâobservĂ©.
Utiliser lâattribut WNOHANG pourrait forcer waitpid (2) Ă renvoyer 0 (« aucun rĂ©sultat dâattente encore disponible ») mĂȘme si lâobservateur sait quâil devrait y avoir une notification. Exemple :
errno = 0;
ptrace(PTRACE_CONT, pid, 0L, 0L);
if (errno == ESRCH) {
/* lâobservĂ© est mort */
r = waitpid(tracee, &status, __WALL | WNOHANG);
/* r peut encore valoir 0 ici ! */
}
Les sortes dâarrĂȘts-ptrace suivants existent : arrĂȘts-distribution-signal, arrĂȘts-groupe, arrĂȘts PTRACE_EVENT et arrĂȘts-appel-systĂšme. Ils sont signalĂ©s par waitpid (2) avec WIFSTOPPED(status) vrai. Ils peuvent ĂȘtre distinguĂ©s en examinant la valeur status>>8 , et en cas dâambiguĂŻtĂ© dans cette valeur, en faisant une requĂȘte PTRACE_GETSIGINFO (remarque : la macro WSTOPSIG(status) ne peut pas ĂȘtre utilisĂ©e pour rĂ©aliser cet examen, car elle renvoie la valeur (status>>8) & 0xff .)
ArrĂȘt-distribution-signal
Quand un processus (Ă©ventuellement multithreadĂ©) reçoit nâimporte quel signal sauf SIGKILL , le noyau choisi un thread arbitraire pour traiter le signal (si le signal est créé avec tgill (2), le thread cible peut ĂȘtre explicitement choisi par lâappelant). Si le thread choisi est observĂ©, il entre en arrĂȘt-distribution-signal. Ă ce moment lĂ , le signal nâest pas encore distribuĂ© au processus, et peut ĂȘtre supprimĂ© par lâobservateur. Si lâobservateur ne supprime pas le signal, il passe le signal Ă lâobservĂ© lors de lâopĂ©ration suivante de redĂ©marrage de ptrace. Cette deuxiĂšme Ă©tape de distribution de signal est appelĂ©e injection de signal dans cette page de manuel. Remarquez que si le signal est bloquĂ©, lâarrĂȘt-distribution-signal nâarrive pas avant que le signal soit dĂ©bloquĂ©, Ă lâexception habituelle que SIGSTOP ne peut pas ĂȘtre bloquĂ©.
LâarrĂȘt-distribution-signal est respectĂ© par lâobservateur tant que waitpid (2) retourne avec WIFSTOPPED(status) vrai, avec le signal renvoyĂ© par WSTOPSIG(status) . Si le signal est SIGTRAP , cela pourrait ĂȘtre un arrĂȘt-ptrace de nature diffĂ©rente ; consultez les sections ArrĂȘts-appel-systĂšme et execve(2) sous ptrace plus bas pour obtenir de plus amples prĂ©cisions. Si WSTOPSIG(status) renvoie un signal dâarrĂȘt, cela pourrait ĂȘtre un arrĂȘt-groupe ; voir ci-dessous.
Injection et suppression de signal
AprĂšs un arrĂȘt-distribution-signal respectĂ© par lâobservateur, lâobservateur devrait redĂ©marrer lâobservĂ© avec lâappel
ptrace(PTRACE_restart, pid, 0, sig)
oĂč PTRACE_restart est une des opĂ©rations ptrace de redĂ©marrage. Si sig est 0 , alors aucun signal nâest distribuĂ©. Sinon, le signal sig est distribuĂ©. Cette opĂ©ration est appelĂ©e injection de signal dans cette page de manuel, pour la distinguer de lâarrĂȘt-distribution-signal.
La valeur de sig peut ĂȘtre diffĂ©rente de celle de WSTOPSIG(status) : lâobservateur peut provoquer lâinjection dâun autre signal.
Remarquez quâun signal supprimĂ© provoque toujours un retour prĂ©maturĂ© des appels systĂšme. Dans ce cas, les appels systĂšme seront redĂ©marrĂ©s : lâobservateur forcera lâobservĂ© Ă rĂ©exĂ©cuter lâappel systĂšme interrompu (ou lâappel systĂšme restart_syscall (2) pour les quelques appels systĂšme qui utilisent un autre mĂ©canisme de redĂ©marrage) si lâobservateur utilise PTRACE_SYSCALL . MĂȘme les appels systĂšme (comme poll (2)) qui ne sont pas redĂ©marrables aprĂšs le signal sont redĂ©marrĂ©s aprĂšs la suppression du signal ; cependant, des bogues du noyau existent et certains appels systĂšme Ă©chouent avec EINTR mĂȘme si aucun signal observable nâest injectĂ© dans lâobservĂ©.
Lors du redĂ©marrage des commandes ptrace Ă©mises dans dâautres arrĂȘts-ptrace quâarrĂȘt-distribution-signal, lâinjection de signal nâest pas garantie, mĂȘme si sig est non nul. Aucune erreur nâest signalĂ©e ; un sig non nul risque simplement dâĂȘtre ignorĂ©. Les utilisateurs de ptrace ne devraient pas essayer de « crĂ©er un nouveau signal » de cette façon : utilisez plutĂŽt tgkill (2).
Le fait que des opĂ©rations dâinjection de signal puissent ĂȘtre ignorĂ©es lors du redĂ©marrage de lâobservĂ© aprĂšs des arrĂȘts ptrace qui ne sont pas des arrĂȘts-distribution-signal est une source de confusion pour les utilisateurs de ptrace. Un scĂ©nario typique est que lâobservateur remarque un arrĂȘt-groupe, le confonde avec un arrĂȘt-distribution-signal, et redĂ©marre lâobservĂ© avec
ptrace(PTRACE_restart, pid, 0, stopsig)
dans le but dâinjecter stopsig , mais stopsig sera ignorĂ© et lâobservĂ© continuera de fonctionner.
Le signal SIGCONT a pour effet de bord de rĂ©veiller (tous les threads dâ)un processus arrĂȘtĂ©-groupe. Cet effet de bord arrive avant un arrĂȘt-distribution-signal. Lâobservateur ne peut pas supprimer cet effet de bord (il ne peut que supprimer lâinjection de signal, qui force seulement le gestionnaire de SIGCONT Ă ne pas ĂȘtre exĂ©cutĂ© dans lâobservĂ©, si un gestionnaire de ce type est installĂ©). En fait, le rĂ©veil depuis un arrĂȘt-groupe pourrait ĂȘtre suivi par un arrĂȘt-distribution-signal pour le ou les signaux diffĂ©rents de SIGCONT , sâils Ă©taient en attente quand SIGCONT a Ă©tĂ© distribuĂ©. Autrement dit, SIGCONT pourrait ne pas ĂȘtre le premier signal remarquĂ© par lâobservĂ© aprĂšs avoir Ă©tĂ© envoyĂ©.
LâarrĂȘt de signaux force (tous les threads dâ)un processus Ă entrer en arrĂȘt-groupe. Cet effet de bord arrive aprĂšs une injection de signal, et peut par consĂ©quent ĂȘtre supprimĂ© par lâobservateur.
Sous Linux 2.4 et les versions prĂ©cĂ©dentes, le signal SIGSTOP ne pouvait pas ĂȘtre injectĂ©.
PTRACE_GETSIGINFO peut ĂȘtre utilisĂ© pour rĂ©cupĂ©rer une structure siginfo_t qui correspond au signal distribuĂ©. PTRACE_SETSIGINFO pourrait ĂȘtre utilisĂ© pour le modifier. Si PTRACE_SETSIGINFO a Ă©tĂ© utilisĂ© pour modifier siginfo_t , le champ si_signo et le paramĂštre sig de la commande de redĂ©marrage doivent correspondre, sinon le rĂ©sultat est indĂ©fini.
ArrĂȘt-groupe
Quand un processus (Ă©ventuellement multithreadĂ©) reçoit un signal dâarrĂȘt, tous les threads sâarrĂȘtent. Si certains threads sont suivis, ils entrent en arrĂȘt-groupe. Remarquez que le signal dâarrĂȘt provoquera dâabord un arrĂȘt-distribution-signal (sur un seul observĂ©) et, seulement aprĂšs avoir Ă©tĂ© injectĂ© par lâobservateur (ou aprĂšs avoir Ă©tĂ© envoyĂ© Ă un thread qui nâest pas suivi), lâarrĂȘt-groupe sera initiĂ© sur tous les observĂ©s dâun processus multithreadĂ©. Comme dâhabitude, tous les observĂ©s signalent leur arrĂȘt-groupe sĂ©parĂ©ment Ă lâobservateur correspondant.
LâarrĂȘt-groupe est respectĂ© par lâobservateur tant que waitpid (2) retourne avec WIFSTOPPED(status) vrai, avec le signal dâarrĂȘt disponible par lâintermĂ©diaire de WSTOPSIG(status) . Le mĂȘme rĂ©sultat est renvoyĂ© par dâautres classes dâarrĂȘts-ptrace, par consĂ©quent la mĂ©thode conseillĂ©e est de rĂ©aliser lâappel
ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo)
Lâappel peut ĂȘtre Ă©vitĂ© si le signal nâest pas SIGSTOP , SIGTSTP , SIGTTIN ou SIGTTOU ; seuls ces quatre signaux sont des signaux dâarrĂȘt. Si lâobservateur voit autre chose, ce ne peut pas ĂȘtre un arrĂȘt-groupe. Sinon, lâobservateur doit appeler PTRACE_GETSIGINFO . Si PTRACE_GETSIGINFO Ă©choue avec EINVAL , alors câest dĂ©finitivement un arrĂȘt-groupe (dâautres codes dâĂ©chec sont possibles, comme ESRCH (« pas de processus de ce type ») si un SIGKILL a tuĂ© lâobservĂ©).
Si lâobservĂ© Ă©tait attachĂ© en utilisant PTRACE_SEIZE , un arrĂȘt-groupe est indiquĂ© par PTRACE_EVENT_STOP : status>>16 == PTRACE_EVENT_STOP . Cela permet la dĂ©tection dâarrĂȘts-groupe sans nĂ©cessiter dâappel PTRACE_GETSIGINFO supplĂ©mentaire.
Depuis Linux 2.6.38, aprĂšs que lâobservateur a vu lâarrĂȘt-ptrace de lâobservĂ© et jusquâĂ ce quâil le redĂ©marre ou le tue, lâobservĂ© ne fonctionnera pas, et nâenverra pas de notification (sauf mort par SIGKILL ) Ă lâobservateur, mĂȘme si lâobservateur entre dans un autre appel waitpid (2).
Le comportement du noyau dĂ©crit dans le paragraphe prĂ©cĂ©dent pose un problĂšme avec la gestion transparente de signaux dâarrĂȘt. Si lâobservateur redĂ©marre lâobservĂ© aprĂšs un arrĂȘt-groupe, le signal dâarrĂȘt est effectivement ignorĂ© â lâobservĂ© ne reste pas arrĂȘtĂ©, il fonctionne. Si lâobservateur ne redĂ©marre pas lâobservĂ© avant dâentrer dans le prochain waitpid (2), les signaux SIGCONT suivants ne seront pas signalĂ©s Ă lâobservateur ; cela pourrait forcer des signaux SIGCONT Ă ĂȘtre sans effet sur lâobservĂ©.
Depuis Linux 3.4, une mĂ©thode permet dâĂ©viter ce problĂšme : Ă la place de PTRACE_CONT , une commande PTRACE_LISTEN peut ĂȘtre utilisĂ©e pour redĂ©marrer un observĂ© de façon Ă ce quâil ne sâexĂ©cute pas, mais attende un nouvel Ă©vĂ©nement quâil peut signaler Ă lâaide de waitpid (2) (comme sâil Ă©tait redĂ©marrĂ© par un SIGCONT ).
ArrĂȘts PTRACE_EVENT
Si lâobservateur configure des options PTRACE_O_TRACE_* , lâobservĂ© entrera en arrĂȘts-ptrace appelĂ©s arrĂȘts PTRACE_EVENT .
Les arrĂȘts PTRACE_EVENT sont respectĂ©s par lâobservateur pendant que waitpid (2) renvoie WIFSTOPPED(status) et que WSTOPSIG(status) renvoie SIGTRAP (ou pour PTRACE_EVENT_STOP , renvoie le signal dâarrĂȘt si lâobservĂ© est dans un arrĂȘt de groupe). Un bit supplĂ©mentaire est configurĂ© dans lâoctet le plus haut du mot dâĂ©tat : la valeur status>>8 sera
((PTRACE_EVENT_foo<<8) | SIGTRAP).
Les
événements suivants existent.
PTRACE_EVENT_VFORK
ArrĂȘt avant de revenir de vfork (2) ou clone (2) avec lâattribut CLONE_VFORK . Quand lâobservĂ© est continuĂ© aprĂšs cet arrĂȘt, il attendra une sortie ou exĂ©cution de lâenfant avant de continuer son exĂ©cution (autrement dit, le comportement normal avec vfork (2)).
PTRACE_EVENT_FORK
ArrĂȘt avant de revenir de fork (2) ou clone (2) avec le signal de sortie configurĂ© Ă SIGCHLD .
PTRACE_EVENT_CLONE
ArrĂȘt avant de revenir de clone (2).
PTRACE_EVENT_VFORK_DONE
ArrĂȘt avant de revenir de vfork (2) ou clone (2) avec lâattribut CLONE_VFORK , mais aprĂšs que lâenfant a dĂ©bloquĂ© son observĂ© par sortie ou exĂ©cution.
Pour les quatre
arrĂȘts dĂ©crits ci-dessus, lâarrĂȘt
arrive dans le parent (câest-Ă -dire
lâobservĂ©), pas dans le nouveau thread
créé.
PTRACE_GETEVENTMSG
permet de
rĂ©cupĂ©rer lâidentifiant du nouveau
thread.
PTRACE_EVENT_EXEC
ArrĂȘt avant le retour dâ execve (2). Depuis Linux 3.0, PTRACE_GETEVENTMSG renvoie le premier identifiant de thread.
PTRACE_EVENT_EXIT
ArrĂȘt avant la sortie (y compris la mort depuis exit_group (2)), la mort du signal ou la sortie provoquĂ©e par execve (2) dans un processus multithreadĂ©. PTRACE_GETEVENTMSG renvoie lâĂ©tat de sortie. Les registres peuvent ĂȘtre examinĂ©s (contrairement Ă quand une « vraie » sortie arrive). LâobservĂ© est toujours actif ; il a besoin de PTRACE_CONT ou PTRACE_DETACH pour terminer sa sortie.
PTRACE_EVENT_STOP
ArrĂȘt causĂ© par la commande PTRACE_INTERRUPT , ou arrĂȘt-groupe, ou arrĂȘt-ptrace initial quand un nouvel enfant est attachĂ© (seulement sâil est attachĂ© en utilisant PTRACE_SEIZE ).
PTRACE_EVENT_SECCOMP
ArrĂȘt diffĂ©rĂ© par une rĂšgle seccomp (2) sur lâentrĂ©e appel systĂšme de lâobservĂ© quand PTRACE_O_TRACESECCOMP a Ă©tĂ© positionnĂ© par lâobservateur. Les donnĂ©es du message de lâĂ©vĂ©nement seccomp (issues de la portion SECCOMP_RET_DATA de la rĂšgle de filtrage seccomp) peuvent ĂȘtre rĂ©cupĂ©rĂ©es avec PTRACE_GETEVENTMSG . La sĂ©mantique de cet arrĂȘt est dĂ©crit en dĂ©tails dans une section distincte ci-dessous.
PTRACE_GETSIGINFO sur les arrĂȘts PTRACE_EVENT renvoie SIGTRAP dans si_signo , avec si_code configurĂ© Ă (event<<8) | SIGTRAP .
ArrĂȘts-appel-systĂšme
Si lâobservĂ© Ă©tait redĂ©marrĂ© par PTRACE_SYSCALL ou PTRACE_SYSEMU , lâobservĂ© entre en arrĂȘt-entrĂ©e-appel-systĂšme juste avant dâentrer dans nâimporte quel appel systĂšme (qui ne sera pas exĂ©cutĂ© si le redĂ©marrage utilisait PTRACE_SYSEMU , quels que soient les changements apportĂ©s aux registres Ă ce point ou Ă la maniĂšre dont lâobservĂ© redĂ©marre aprĂšs cet arrĂȘt). Peu importe la mĂ©thode qui a conduit en arrĂȘt-entrĂ©e-appel-systĂšme si lâobservateur redĂ©marre lâobservĂ© avec PTRACE_SYSCALL , lâobservĂ© entre en arrĂȘt-sortie-appel-systĂšme quand lâappel systĂšme est terminĂ© ou sâil est interrompu par un signal (câest-Ă -dire quâun arrĂȘt-distribution-signal nâarrive jamais entre un arrĂȘt-entrĂ©e-appel-systĂšme et un arrĂȘt-sortie-appel-systĂšme ; il arrive aprĂšs lâarrĂȘt-sortie-appel-systĂšme). Si lâobservĂ© est poursuivi en utilisant une autre mĂ©thode (notamment PTRACE_SYSEMU ), aucun arrĂȘt-sortie-appel-systĂšme ne se produit. Remarquez que toutes les mentions PTRACE_SYSEMU sâappliquent Ă©galement Ă PTRACE_SYSEMU_SINGLESTEP .
Toutefois, mĂȘme si lâobservĂ© a Ă©tĂ© poursuivi en utilisant PTRACE_SYSCALL , il nâest pas garanti que le prochain arrĂȘt sera un arrĂȘt-sortie-appel-systĂšme. Dâautres possibilitĂ©s sont que lâobservĂ© pourrait sâarrĂȘter dans un arrĂȘt PTRACE_EVENT , sortir (sâil est entrĂ© en _exit (2) ou exit_group (2)), ĂȘtre tuĂ© par SIGKILL ou mourir silencieusement (sâil sâagit dâun leader de groupe de threads, que lâ execve (2) est arrivĂ© dans un autre thread et que ce thread nâest pas suivi par le mĂȘme observateur ; cette situation sera abordĂ©e plus tard).
Les arrĂȘt-entrĂ©e-appel-systĂšme et arrĂȘt-sortie-appel-systĂšme sont respectĂ©s par lâobservateur tant que waitpid (2) retourne avec WIFSTOPPED(status) vrai, et que WSTOPSIG(status) donne SIGTRAP . Si lâoption PTRACE_O_TRACESYSGOOD Ă©tait configurĂ©e par lâobservateur, alors WSTOPSIG(status) donnera la valeur ( SIGTRAP | 0x80 ).
Les
arrĂȘts-appel-systĂšme peuvent ĂȘtre
distinguĂ©s dâun arrĂȘt-distribution-signal
avec
SIGTRAP
en demandant
PTRACE_GETSIGINFO
pour les cas suivants.
si_code
<= 0
SIGTRAP a Ă©tĂ© distribuĂ© comme rĂ©sultat dâune action en espace utilisateur, par exemple, un appel systĂšme ( tgkill (2), kill (2), sigqueue (3), etc.), lâexpiration dâun minuteur POSIX, la modification dâĂ©tat sur une file de messages POSIX oĂč la fin dâune opĂ©ration dâE/S asynchrone.
si_code == SI_KERNEL (0x80)
SIGTRAP a été envoyé par le noyau.
si_code == SIGTRAP ou si_code == (SIGTRAP|0x80)
Câest un arrĂȘt-appel-systĂšme.
Cependant, les arrĂȘts-appel-systĂšme arrivent trĂšs souvent (deux fois par appel systĂšme) et rĂ©aliser PTRACE_GETSIGINFO pour chaque arrĂȘt-appel-systĂšme pourrait ĂȘtre assez coĂ»teux.
Certaines architectures permettent de distinguer ces cas en examinant les registres. Par exemple, sur x86, rax == - ENOSYS en arrĂȘt-entrĂ©e-appel-systĂšme. Puisque SIGTRAP (comme tout autre signal) arrive toujours aprĂšs lâarrĂȘt-sortie-appel-systĂšme et que rax ne contient Ă ce moment presque jamais - ENOSYS , le SIGTRAP ressemble Ă un « arrĂȘt-appel-systĂšme qui nâest pas un arrĂȘt-entrĂ©e-appel-systĂšme » ; autrement dit, il ressemble Ă un « arrĂȘt-sortie-appel-systĂšme perdu » et peut ĂȘtre dĂ©tectĂ© de cette façon. Une telle dĂ©tection est nĂ©anmoins fragile, elle est donc a Ă©viter.
Lâutilisation de lâoption PTRACE_O_TRACESYSGOOD est la mĂ©thode conseillĂ©e pour distinguer les arrĂȘts-appel-systĂšme des autres sortes dâarrĂȘts-ptrace, puisquâil est fiable et nâinduit pas de perte de performances.
Les arrĂȘt-entrĂ©e-appel-systĂšme et arrĂȘt-sortie-appel-systĂšme ne sont pas diffĂ©rentiables lâun de lâautre. Lâobservateur doit garder une trace de la suite dâarrĂȘts-ptrace afin de ne pas mal interprĂ©ter un arrĂȘt-entrĂ©e-appel-systĂšme comme un arrĂȘt-sortie-appel-systĂšme ou vice versa. GĂ©nĂ©ralement, lâarrĂȘt-entrĂ©e-appel-systĂšme est toujours suivi par un arrĂȘt-sortie-appel-systĂšme, un arrĂȘt PTRACE_EVENT ou la mort de lâobservé ; aucune autre sorte dâarrĂȘt-ptrace ne peut arriver entre-deux. Toutefois, remarquez que les arrĂȘts seccomp (voir ci-dessous) peuvent provoquer des arrĂȘts-sortie-appel-systĂšme sans arrĂȘt-entrĂ©e-appel-systĂšme prĂ©alable. Si seccomp, il faut faire attention Ă ne pas mal interprĂ©ter de tels arrĂȘts en arrĂȘts-entrĂ©e-appel-systĂšme.
Si suite Ă un arrĂȘt-entrĂ©e-appel-systĂšme, lâobservateur utilise une commande de redĂ©marrage diffĂ©rente de PTRACE_SYSCALL , lâarrĂȘt-sortie-appel-systĂšme nâest pas créé.
PTRACE_GETSIGINFO sur les arrĂȘts-appel-systĂšme renvoie SIGTRAP dans si_signo , avec si_code configurĂ© Ă SIGTRAP ou ( SIGTRAP | 0x80 ).
ArrĂȘts PTRACE_EVENT_SECCOMP (Linux 3.5 Ă Linux 4.7)
Le comportement des arrĂȘts PTRACE_EVENT_SECCOMP et leur interaction avec les autres types dâarrĂȘt ptrace a changĂ© entre les versions du noyau. Nous documentons ici le comportement lors de leur introduction dans Linux 4.7 (inclus). Le comportement dans les versions postĂ©rieures du noyau est documentĂ© dans la section suivante.
Un arrĂȘt PTRACE_EVENT_SECCOMP se produit Ă chaque fois quâune rĂšgle SECCOMP_RET_TRACE est dĂ©clenchĂ©e. Cela est indĂ©pendant de la mĂ©thode utilisĂ©e pour redĂ©marrer lâappel systĂšme. En particulier, seccomp sâexĂ©cute toujours mĂȘme si lâobservĂ© a Ă©tĂ© redĂ©marrĂ© en utilisant PTRACE_SYSEMU et cet appel systĂšme est sautĂ© sans condition.
Les redĂ©marrages Ă partir de cet arrĂȘt se comporteront comme si lâarrĂȘt sâĂ©tait produit juste avant lâappel systĂšme en question. En particulier, tant PTRACE_SYSCALL que PTRACE_SYSEMU provoqueront normalement un arrĂȘt-entrĂ©e-appel-systĂšme ultĂ©rieur. Cependant, si aprĂšs le PTRACE_EVENT_SECCOMP le numĂ©ro de lâappel systĂšme est nĂ©gatif, lâarrĂȘt-entrĂ©e-appel-systĂšme et lâappel lui-mĂȘme seront tous deux sautĂ©s. Cela veut dire que si le numĂ©ro dâappel systĂšme est nĂ©gatif aprĂšs un PTRACE_EVENT_SECCOMP et si lâobservĂ© est redĂ©marrĂ© en utilisant PTRACE_SYSCALL , le prochain arrĂȘt observĂ© sera un arrĂȘt-sortie-appel-systĂšme et non un arrĂȘt-entrĂ©e-appel-systĂšme qui comme on aurait pu sây attendre.
ArrĂȘts PTRACE_EVENT_SECCOMP (depuis Linux 4.8)
Ă partir de Linux 4.8, lâarrĂȘt PTRACE_EVENT_SECCOMP a Ă©tĂ© rĂ©amĂ©nagĂ© pour intervenir entre lâarrĂȘt-entrĂ©e-appel-systĂšme et lâarrĂȘt-sortie-appel-systĂšme. Remarquez que seccomp ne sâexĂ©cute plus (et aucun PTRACE_EVENT_SECCOMP ne sera renvoyĂ©) si lâappel systĂšme est sautĂ© du fait dâun PTRACE_SYSEMU .
Pratiquement, un arrĂȘt PTRACE_EVENT_SECCOMP fonctionne comme un arrĂȘt-entrĂ©e-appel-systĂšme (Ă savoir que les reprises utilisant PTRACE_SYSCALL provoqueront des arrĂȘts-sortie-appel-systĂšme, le numĂ©ro de lâappel systĂšme peut ĂȘtre modifiĂ© et tous les registres modifiĂ©s sont visibles Ă©galement Ă lâappel systĂšme Ă exĂ©cuter). Remarquez quâil peut y avoir, sans obligation quâil y ait dĂ©jĂ eu, un arrĂȘt-entrĂ©e-appel-systĂšme prĂ©cĂ©dent.
AprĂšs un arrĂȘt PTRACE_EVENT_SECCOMP , seccomp sera rĂ©exĂ©cutĂ©, avec une rĂšgle SECCOMP_RET_TRACE qui fonctionne dĂ©sormais de la mĂȘme maniĂšre que SECCOMP_RET_ALLOW . En particulier, cela veut dire que si les registres ne sont pas modifiĂ©s lors dâun arrĂȘt PTRACE_EVENT_SECCOMP , lâappel systĂšme aura alors lâautorisation.
ArrĂȘts PTRACE_SINGLESTEP
[Les prĂ©cisions sur ces types dâarrĂȘts sont encore Ă documenter.]
Commandes ptrace dâinformation et de redĂ©marrage
La plupart des commandes ptrace (toutes sauf PTRACE_ATTACH , PTRACE_SEIZE , PTRACE_TRACEME , PTRACE_INTERRUPT et PTRACE_KILL ) nĂ©cessitent que lâobservĂ© soit en arrĂȘt-ptrace, sinon il Ă©choue avec ESRCH .
Quand lâobservĂ© est en arrĂȘt-ptrace, lâobservateur peut lire et Ă©crire les donnĂ©s sur lâobservĂ© en utilisant les commandes dâinformation. Ces commandes laissent lâobservĂ© en Ă©tat arrĂȘtĂ©-ptrace :
ptrace(PTRACE_PEEKTEXT/PEEKDATA/PEEKUSER,
pid, addr, 0);
ptrace(PTRACE_POKETEXT/POKEDATA/POKEUSER, pid, addr,
long_val);
ptrace(PTRACE_GETREGS/GETFPREGS, pid, 0, &struct);
ptrace(PTRACE_SETREGS/SETFPREGS, pid, 0, &struct);
ptrace(PTRACE_GETREGSET, pid, NT_foo, &iov);
ptrace(PTRACE_SETREGSET, pid, NT_foo, &iov);
ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo);
ptrace(PTRACE_SETSIGINFO, pid, 0, &siginfo);
ptrace(PTRACE_GETEVENTMSG, pid, 0, &long_var);
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags);
Remarquez que certaines erreurs ne sont pas signalĂ©es. Par exemple, la configuration dâinformations de signal ( siginfo ) pourrait ĂȘtre sans effet pour certains arrĂȘts-ptrace, alors que lâappel pourrait-ĂȘtre rĂ©ussi (en renvoyant 0 et sans dĂ©finir errno ) ; la demande de PTRACE_GETEVENTMSG pourrait rĂ©ussir et renvoyer une quelconque valeur alĂ©atoire si lâarrĂȘt-ptrace actuel nâest pas documentĂ© comme renvoyant un message dâĂ©vĂ©nement significatif.
Lâappelâ
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags);
ne concerne quâun observĂ©. Les attributs actuels de lâobservĂ© sont remplacĂ©s. Les attributs sont hĂ©ritĂ©s par les nouveaux observĂ©s créés et « attachĂ©s automatiquement » Ă lâaide dâoptions PTRACE_O_TRACEFORK , PTRACE_O_TRACEVFORK ou PTRACE_O_TRACECLONE actives.
Un autre groupe de commandes peut redĂ©marrer lâobservĂ© arrĂȘtĂ©-ptrace. Ils sont de la forme :
ptrace(cmd, pid, 0, sig);
oĂč cmd est PTRACE_CONT , PTRACE_LISTEN , PTRACE_DETACH , PTRACE_SYSCALL , PTRACE_SINGLESTEP , PTRACE_SYSEMU ou PTRACE_SYSEMU_SINGLESTEP . Si lâobservĂ© est en arrĂȘt-distribution-signal, sig est le signal Ă injecter (sâil est non nul). Sinon, sig pourrait ĂȘtre ignorĂ© (lors du redĂ©marrage dâun observĂ© depuis un arrĂȘt-ptrace diffĂ©rent dâun arrĂȘt-distribution-signal, il est conseillĂ© de toujours passer 0 Ă sig ).
Attachement et détachement
Un thread peut ĂȘtre attachĂ© Ă lâobservateur en utilisant lâappel
ptrace(PTRACE_ATTACH, pid, 0, 0);
ou
ptrace(PTRACE_SEIZE, pid, 0, PTRACE_O_flags);
PTRACE_ATTACH envoie aussi SIGSTOP Ă ce thread. Si lâobservateur veut que SIGSTOP soit sans effet, il doit le supprimer. Remarquez que si dâautres signaux sont envoyĂ©s en mĂȘme temps Ă ce thread pendant lâattachement, lâobservateur pourrait voir lâobservĂ© entrer en arrĂȘt-distribution-signal avec dâautres signaux dâabord ! Ces signaux sont dâhabitude rĂ©injectĂ©s jusquâĂ ce que SIGSTOP soit vu, puis lâinjection SIGSTOP est supprimĂ©e. Le bogue de conception ici est quâun attachement ptrace et un SIGSTOP distribuĂ©s en mĂȘme temps peuvent entrer en compĂ©tition et le SIGSTOP risque dâĂȘtre perdu.
Puisque lâattachement envoie SIGSTOP et que lâobservateur le supprime normalement, cela risque de forcer le retour dâun EINTR perdu de lâappel systĂšme en cours dâexĂ©cution dans lâobservĂ©, tel que câest dĂ©crit dans la section Injection et suppression de signal .
Depuis Linux 3.4, PTRACE_SEIZE peut ĂȘtre utilisĂ© Ă la place de PTRACE_ATTACH . PTRACE_SEIZE nâarrĂȘte pas le processus attachĂ©. Si vous devez lâarrĂȘter aprĂšs attachement (ou Ă nâimporte quel autre moment) sans lui envoyer de signal du tout, utilisez la commande PTRACE_INTERRUPT .
LâopĂ©ration
ptrace(PTRACE_TRACEME, 0, 0, 0);
transforme le thread appelant en observĂ©. Lâappel continue dâĂȘtre exĂ©cutĂ© (nâentre pas en arrĂȘt-ptrace). PTRACE_TRACEME est habituellement suivi avec
raise(SIGSTOP);
et permet au parent (qui est maintenant lâobservateur) de respecter lâarrĂȘt-distribution-signal.
Si les options PTRACE_O_TRACEFORK , PTRACE_O_TRACEVFORK ou PTRACE_O_TRACECLONE font effet, alors les enfants respectivement créés par vfork (2) ou clone (2) avec lâattribut CLONE_VFORK , fork (2) ou clone (2) avec le signal de sortie configurĂ© Ă SIGCHLD , et dâautres sortes de clone (2), sont automatiquement attachĂ©s au mĂȘme observateur qui Ă suivi leur parent. SIGSTOP est distribuĂ© aux enfants, les forçant Ă entrer en arrĂȘt-distribution-signal aprĂšs ĂȘtre sortis de lâappel systĂšme quâils ont créé.
Le dĂ©tachement de lâobservĂ© est rĂ©alisĂ© par :
ptrace(PTRACE_DETACH, pid, 0, sig);
PTRACE_DETACH est une opĂ©ration de redĂ©marrage ; par consĂ©quent elle nĂ©cessite que lâobservĂ© soit en arrĂȘt-ptrace. Si lâobservĂ© est en arrĂȘt-distribution-signal, un signal peut ĂȘtre injectĂ©. Sinon, le paramĂštre sig pourrait ĂȘtre silencieusement ignorĂ©.
Si lâobservĂ© est en cours dâexĂ©cution quand lâobservateur veut le dĂ©tacher, la solution habituelle est dâenvoyer SIGSTOP (en utilisant tgkill (2), pour sâassurer quâil va au bon thread), dâattendre que lâobservĂ© sâarrĂȘte en arrĂȘt-distribution-signal pour SIGSTOP et ensuite de le dĂ©tacher (en supprimant lâinjection SIGSTOP ). Un bogue de conception est que lâobservĂ© pourrait entrer dans dâautres arrĂȘts-ptrace et avoir besoin dâĂȘtre redĂ©marrĂ© et attendre encore, jusquâĂ ce que SIGSTOP soit vu. Encore une autre complication est de sâassurer que lâobservĂ© nâest pas dĂ©jĂ arrĂȘtĂ©-ptrace, parce quâaucune distribution de signal nâarrive tant quâil lâest â pas mĂȘme SIGSTOP .
Si lâobservateur meurt, tous les observĂ©s sont automatiquement dĂ©tachĂ©s et redĂ©marrĂ©s, sauf sâil Ă©taient en arrĂȘt-groupe. Le gestion de redĂ©marrage depuis un arrĂȘt-groupe est en ce moment dysfonctionnelle, mais le comportement « prĂ©vu » est de laisser les observĂ©s arrĂȘtĂ©s et dâattendre un SIGCONT . Si lâobservĂ© est redĂ©marrĂ© depuis un arrĂȘt-distribution-signal, le signal en attente est injectĂ©.
execve(2) sous ptrace
Quand un thread de processus multithreadĂ© appelle execve (2), le noyau dĂ©truit tous les autres threads du processus, et rĂ©initialise lâidentifiant de thread du thread exĂ©cutĂ© Ă lâidentifiant de groupe de threads (PID) (ou, pour le prĂ©senter autrement, quand un processus multithreadĂ© fait un execve (2), Ă la fin de lâappel, il apparaĂźt comme si lâ execve (2) sâĂ©tait appliquĂ© au leader de groupe de threads, quelque soit le thread qui a fait execve (2)). Cette rĂ©initialisation de lâidentifiant de thread semble est trĂšs dĂ©routante pour les observateurs.
|
- |
Tous les autres threads sâarrĂȘtent en arrĂȘt PTRACE_EVENT_EXIT , si lâoption PTRACE_O_TRACEEXIT Ă©tait activĂ©e. Alors tous les autres threads sauf le leader de groupe de threads signalent leur mort comme sâil sâĂ©taient terminĂ©s par lâintermĂ©diaire de _exit (2) avec un code de retour 0 . |
||
|
- |
LâobservĂ© en cours dâexĂ©cution modifie son identifiant de thread pendant quâil est dans lâ execve (2) (rappelez-vous que, sous ptrace, le « pid » renvoyĂ© par waitpid (2) ou fourni dans les appels ptrace, est lâidentifiant de thread de lâobservĂ©). Ainsi, lâidentifiant de thread de lâobservĂ© est rĂ©initialisĂ© pour ĂȘtre le mĂȘme que son identifiant de processus (PID), qui est le mĂȘme que lâidentifiant de thread du leader de groupe de threads. |
||
|
- |
Ensuite un arrĂȘt PTRACE_EVENT_EXEC arrive, si lâoption PTRACE_O_TRACEEXEC Ă©tait activĂ©e. |
||
|
- |
Si le leader de groupe de threads a signalĂ© son arrĂȘt PTRACE_EVENT_EXIT pendant ce temps, le leader de thread mort Ă lâair de « revenir de nulle part » du point de vue de lâobservateur (remarque : le leader de groupe de threads ne signale pas sa mort Ă lâaide de WIFEXITED(status) tant quâau moins un autre thread est en vie. Cela enlĂšve la possibilitĂ© Ă lâobservateur de le voir mourir puis rĂ©apparaĂźtre). Si le leader de groupe de threads Ă©tait encore en vie, cela pourrait ĂȘtre vu par lâobservateur comme si le leader de groupe revenait dâun autre appel systĂšme que celui dans lequel il Ă©tait entrĂ©, ou mĂȘme « revenait dâun appel systĂšme mĂȘme sâil nây avait pas dâappel systĂšme ». Si le leader de groupe de threads nâĂ©tait pas suivi (ou Ă©tait suivi par un autre observateur), alors pendant execve (2) il apparaĂźtra comme sâil Ă©tait devenu un observĂ© de lâobservateur de lâobservĂ© en cours dâexĂ©cution. |
Tous les effets prĂ©cĂ©dents sont des artifices de la modification dâidentifiant de thread de lâobservĂ©.
Lâoption PTRACE_O_TRACEEXEC est lâoutil conseillĂ© pour sâoccuper de cette situation. Dâabord, elle active lâarrĂȘt PTRACE_EVENT_EXEC , qui arrive avant le retour dâ execve (2). Dans cet arrĂȘt, lâobservateur peut utiliser PTRACE_GETEVENTMSG pour rĂ©cupĂ©rer lâancien identifiant de thread de lâobservĂ© (cette fonctionnalitĂ© a Ă©tĂ© introduite avec Linux 3.0). Ensuite, lâoption PTRACE_O_TRACEEXEC dĂ©sactive la crĂ©ation obsolĂšte de SIGTRAP dans execve (2).
Quand lâobservĂ© reçoit une notification dâarrĂȘt PTRACE_EVENT_EXEC , il est garanti quâĂ part cet observĂ© et le leader de groupe de threads, aucun autre thread du processus nâest en vie.
Lors de la rĂ©ception dâune notification dâarrĂȘt PTRACE_EVENT_EXEC , lâobservateur devrait nettoyer toutes ses structures de donnĂ©es internes dĂ©crivant les threads de ce processus et ne garder quâune seule structure de donnĂ©es â celle qui dĂ©crit lâunique observĂ© en cours dâexĂ©cution, avec
identifiant de thread == identifiant de groupe de threads == identifiant de processus.
Par exemple, soient deux threads qui appellent execve (2) en mĂȘme temps :
***
arrĂȘt-entrĂ©e-appel-systĂšme obtenu dans
le thread 1 : **
PID1 execve("/bin/truc", "truc" <pas
terminĂ©âŠ>
*** PTRACE_SYSCALL émis pour le thread 1 **
*** arrĂȘt-entrĂ©e-appel-systĂšme obtenu
dans le thread 2 : **
PID2 execve("/bin/bidule", "bidule"
<pas terminĂ©âŠ>
*** PTRACE_SYSCALL émis pour le thread 2 **
*** PTRACE_EVENT_EXEC obtenu pour PID0, PTRACE_SYSCALL
émis **
*** arrĂȘt-sortie-appel-systĂšme obtenu pour PID0
: **
PID0 <⊠retour dâexecve> ) = 0
Si lâoption PTRACE_O_TRACEEXEC nâest pas effective pour lâobservĂ© en cours dâexĂ©cution et si lâobservĂ© a Ă©tĂ© PTRACE_ATTACH Ă© et non PTRACE_SEIZE Ă©, le noyau distribue un SIGTRAP supplĂ©mentaire Ă lâobservĂ© aprĂšs le retour dâ execve (2). Câest un signal normal (similaire Ă celui qui peut ĂȘtre créé par kill -TRAP ), pas une sorte spĂ©ciale dâarrĂȘt-ptrace. Lâutilisation de PTRACE_GETSIGINFO pour ce signal renvoie si_code configurĂ© Ă 0 ( SI_USER ). Ce signal pourrait ĂȘtre bloquĂ© par un masque de signal et pourrait ainsi ĂȘtre distribuĂ© (bien) plus tard.
Normalement, lâobservateur (par exemple strace (1)) ne voudrait pas montrer ce signal SIGTRAP supplĂ©mentaire postĂ©rieur Ă execve Ă lâutilisateur, et voudrait supprimer sa distribution Ă lâobservĂ© (si SIGTRAP est configurĂ© Ă SIG_DFL , câest un signal tueur). Cependant, dĂ©terminer quel est le SIGTRAP Ă supprimer nâest pas simple. La configuration de lâoption PTRACE_O_TRACEEXEC ou lâutilisation de PTRACE_SEIZE et par consĂ©quent la suppression du SIGTRAP supplĂ©mentaire est lâapproche conseillĂ©e.
Vrai parent
Lâinterface de programmation de ptrace utilise (parfois mal) la norme UNIX de signalement de parent ou enfant par lâintermĂ©diaire de waitpid (2). Cela a rĂ©guliĂšrement forcĂ© le vrai parent du processus Ă arrĂȘter de recevoir plusieurs sortes de notifications de waitpid (2) quand le processus enfant est suivi par un autre processus.
De nombreux bogues de ce type ont été corrigés, mais il en reste encore beaucoup dans Linux 2.6.38. Consultez la section BOGUES ci dessous.
Depuis Linux 2.6.38, ce qui suit est censé fonctionner correctement :
|
- |
lâexĂ©cution ou la mort par signal sont dâabord signalĂ©es Ă lâobservateur, puis, quand lâobservateur consomme le rĂ©sultat de waitpid (2), au vrai parent (au vrai parent seulement quand lâintĂ©gralitĂ© du processus multithreadĂ© se termine). Si lâobservateur et le vrai parent sont le mĂȘme processus, le signalement nâest envoyĂ© quâune fois. |
VALEUR RENVOYĂE
En cas de succĂšs, lâopĂ©ration PTRACE_PEEK* renvoie les donnĂ©es demandĂ©es (mais consultez les NOTES), lâopĂ©ration PTRACE_SECCOMP_GET_FILTER renvoie le nombre dâinstructions du programme BPF, lâopĂ©ration PTRACE_GET_SYSCALL_INFO renvoie le nombre dâoctets disponibles disponible pour ĂȘtre Ă©crits par le noyau, alors que les autres opĂ©rations renvoient zĂ©ro.
En cas dâerreur, toutes les opĂ©rations renvoient -1 et errno est dĂ©fini pour indiquer lâerreur. Comme la valeur renvoyĂ©e par une opĂ©ration PTRACE_PEEK* peut lĂ©gitimement ĂȘtre -1 , lâappelant doit effacer errno avant lâappel, et ensuite le vĂ©rifier pour savoir si une erreur sâest produite.
ERREURS
|
EBUSY |
(i386 seulement) Une erreur est survenue lors de lâallocation ou de la libĂ©ration dâun registre de dĂ©bogage. |
||
|
EFAULT |
Tentative de lire ou Ă©crire dans une zone mĂ©moire non valable de lâobservateur ou de lâobservĂ©, probablement parce que la zone nâĂ©tait pas projetĂ©e ou accessible. Malheureusement sous Linux, certaines variantes de cette erreur dĂ©clencheront EIO ou EFAULT plus ou moins arbitrairement. |
||
|
EINVAL |
Tentative dâutiliser une option non valable. |
||
|
EIO |
LâopĂ©ration op nâest pas valable ou une tentative de lecture ou dâĂ©criture dans une zone non valable de mĂ©moire de lâobservateur ou de lâobservĂ© a eu lieu. Un problĂšme dâalignement a aussi pu survenir sur une frontiĂšre de mot, ou un signal non valable a Ă©tĂ© spĂ©cifiĂ© pendant une opĂ©ration de redĂ©marrage. |
||
|
EPERM |
Le processus indiquĂ© ne peut pas ĂȘtre suivi. Cela peut ĂȘtre dĂ» Ă un manque de privilĂšge de lâobservateur (la capacitĂ© nĂ©cessaire est CAP_SYS_PTRACE ). Les processus non privilĂ©giĂ©s ne peuvent pas suivre les processus auxquels ils ne peuvent envoyer de signal, ou ceux qui sâexĂ©cutent Set-UID/Set-GID, pour des raisons Ă©videntes. En outre, le processus visĂ© peut ĂȘtre dĂ©jĂ suivi, ou (avant Linux 2.6.26) ĂȘtre init (8) (le processus numĂ©ro 1). |
||
|
ESRCH |
Le processus indiquĂ© nâexiste pas, ou nâest pas suivi par lâappelant, ou nâest pas arrĂȘtĂ© (pour les opĂ©rations qui ont besoin dâun observĂ© arrĂȘtĂ©). |
STANDARDS
Aucun.
HISTORIQUE
SVr4, 4.3BSD.
Avant Linux 2.6.26, init (8), le processus numĂ©ro 1, ne peut pas ĂȘtre suivi.
NOTES
Bien que les arguments de ptrace () soient interprĂ©tĂ©s comme dans le prototype donnĂ©, la bibliothĂšque glibc dĂ©clare ptrace comme une fonction variadique oĂč seul lâargument op est corrigĂ©. Il vaut mieux toujours fournir quatre arguments, mĂȘme si lâopĂ©ration demandĂ©e ne les utilise pas, en configurant les arguments non utilisĂ©s ou ignorĂ©s Ă 0L ou (void *) 0 .
Le parent dâobservĂ©s reste observateur mĂȘme sâil appelle execve (2).
La disposition du contenu de la mĂ©moire et de la zone USER dĂ©pendent du systĂšme dâexploitation et de lâarchitecture. Le dĂ©calage fourni et les donnĂ©es renvoyĂ©es peuvent ne pas correspondre entiĂšrement avec la dĂ©finition dâune structure struct user .
La taille dâun mot (« word ») est dĂ©terminĂ©e par la version du systĂšme dâexploitation (par exemple 32 bits pour Linux 32 bits).
Cette page documente le fonctionnement actuel de ptrace () sous Linux. Celui-ci peut varier significativement dâautres types dâUNIX. De toute façon, lâutilisation de ptrace () dĂ©pend fortement de lâarchitecture et du systĂšme dâexploitation.
VĂ©rification du mode dâaccĂšs ptrace
Divers endroits de lâAPI de lâespace utilisateur du noyau (pas seulement les opĂ©rations ptrace ()) exigent ce quâon appelle des « vĂ©rifications de mode dâaccĂšs ptrace », dont le rĂ©sultat dĂ©termine si une opĂ©ration est autorisĂ©e (ou, dans certains cas, fait renvoyer Ă lâopĂ©ration « read » des donnĂ©es nettoyĂ©es). Ces vĂ©rifications sont effectuĂ©es dans les cas oĂč un processus peut accĂ©der Ă des informations sensibles concernant un autre processus ou modifier son Ă©tat. Les vĂ©rifications sâopĂšrent sur la base de facteurs tels que les droits et les capacitĂ©s des deux processus, le fait que le processus « cible » puisse gĂ©nĂ©rer un fichier core, et des rĂ©sultats des vĂ©rifications effectuĂ©es par un module de sĂ©curitĂ© Linux activĂ© (LSM) (par exemple SELinux, Yama ou Smack) et par le LSM commoncap (qui est toujours appelĂ©).
Avant
Linux 2.6.27, toutes les vérifications
dâaccĂšs Ă©taient dâun seul type.
Depuis Linux 2.6.27, on distingue deux niveaux de modes
dâaccĂšs :
PTRACE_MODE_READ
Pour les opĂ©rations « read » ou dâautres moins dangereuses telles que : get_robust_list (2) ; kcmp (2) ; la lecture de /proc/ pid /auxv , /proc/ pid /environ ou de /proc/ pid /stat ; ou le readlink (2) dâun fichier /proc/ pid /ns/* .
PTRACE_MODE_ATTACH
Pour les opĂ©rations « write » ou dâautres plus dangereuses telles que : le rattachement de ptrace ( PTRACE_ATTACH ) Ă un autre processus ou un appel process_vm_writev (2) ( PTRACE_MODE_ATTACH Ă©tait celui par dĂ©faut avant Linux 2.6.27).
Depuis Linux
4.5, les vĂ©rifications de mode dâaccĂšs
ci-dessus sont combinées (opération OU) avec
un ou plusieurs des modificateurs suivants :
PTRACE_MODE_FSCREDS
Utiliser lâidentifiant de groupe ou dâutilisateur du systĂšme de fichiers de lâappelant (voir credentials (7)) ou les capacitĂ©s effectives pour les vĂ©rifications LSM.
PTRACE_MODE_REALCREDS
Utiliser lâidentifiant de groupe ou dâutilisateur rĂ©el de lâappelant ou les capacitĂ©s autorisĂ©es pour les vĂ©rifications LSM. CâĂ©tait lâaction par dĂ©faut avant Linux 4.5.
La combinaison
dâun des modificateurs de droits avec un des modes
dâaccĂšs ci-dessus Ă©tant classique,
certaines macros sont définies dans les sources du
noyau pour les combinaisons :
PTRACE_MODE_READ_FSCREDS
Définie en tant que PTRACE_MODE_READ | PTRACE_MODE_FSCREDS .
PTRACE_MODE_READ_REALCREDS
Définie en tant que PTRACE_MODE_READ | PTRACE_MODE_REALCREDS .
PTRACE_MODE_ATTACH_FSCREDS
Définie en tant que PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS .
PTRACE_MODE_ATTACH_REALCREDS
Définie en tant que PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS .
Un modificateur
supplĂ©mentaire peut ĂȘtre liĂ©
(opĂ©ration OU) au mode dâaccĂšs :
PTRACE_MODE_NOAUDIT
(depuis Linux 3.3)
Ne pas effectuer la vĂ©rification de ce mode dâaccĂšs. Ce modificateur est utilisĂ© pour les vĂ©rifications de mode dâaccĂšs ptrace (telles que celles faites lors de la lecture de /proc/ pid /stat ) qui filtrent ou nettoient la sortie au lieu de renvoyer une erreur Ă lâappelant. Dans ces cas, lâaccĂšs au fichier nâest pas une violation de sĂ©curitĂ© et il nây aucune raison de gĂ©nĂ©rer un enregistrement de lâĂ©valuation de la sĂ©curitĂ©. Ce modificateur supprime la gĂ©nĂ©ration dâun tel enregistrement pour cette vĂ©rification dâaccĂšs particuliĂšre.
Remarquez que toutes les constantes PTRACE_MODE_* dĂ©crites dans cette sous-section sont internes au noyau et invisibles Ă lâespace utilisateur. Le nom des constantes est mentionnĂ© ici pour identifier les diffĂ©rents types de vĂ©rification des modes dâaccĂšs ptrace effectuĂ©es pour divers appels systĂšme et divers accĂšs Ă des pseudofichiers (comme dans /proc ). Ces noms sont utilisĂ©s dans dâautres pages de manuel pour fournir un raccourci simple dâidentification des vĂ©rifications du noyau.
Lâalgorithme utilisĂ© pour la vĂ©rification des modes dâaccĂšs ptrace dĂ©termine si le processus appelant est autorisĂ© Ă effectuer lâaction correspondante sur le processus cible (pour lâouverture des fichiers /proc/ pid, le « processus appelant » est celui qui ouvre le fichier et le processus dont le PID correspond est le « processus cible »). Lâalgorithme est comme suit :
|
(1) |
Si le thread appelant et cible sont dans le mĂȘme groupe de threads, lâaccĂšs est toujours autorisĂ©. |
||
|
(2) |
Si le mode dâaccĂšs indique PTRACE_MODE_FSCREDS , lors de la vĂ©rification de la prochaine Ă©tape, utiliser lâidentifiant dâutilisateur et de groupe du systĂšme de fichiers appelant (comme indiquĂ© dans credentials (7), les identifiants dâutilisateur et de groupe du systĂšme de fichiers ont presque toujours la mĂȘme valeur que les identifiants effectifs correspondant). |
Sinon le mode dâaccĂšs indique PTRACE_MODE_REALCREDS , donc utiliser lâidentifiant dâutilisateur et de groupe rĂ©els de lâappelant lors des vĂ©rifications de la prochaine Ă©tape (la plupart des API qui vĂ©rifient les identifiants dâutilisateur et de groupe utilisent les identifiants effectifs. Pour des raisons historiques, la vĂ©rification PTRACE_MODE_REALCREDS utilise plutĂŽt ceux rĂ©els).
|
(3) |
Interdire lâaccĂšs si rien de ce qui suit nâest vrai : |
-
|
Les identifiants utilisateur rĂ©el, effectif et dĂ©fini de la cible correspondent Ă lâidentifiant utilisateur de lâappelant et les identifiants rĂ©els, effectifs et dĂ©finis de groupe de la cible correspondent Ă ceux de groupe de lâappelant. |
|||
|
- |
Lâappelant a la capacitĂ© CAP_SYS_PTRACE dans lâespace de noms utilisateur de la cible. |
||
|
(4) |
Interdire lâaccĂšs si lâattribut « dumpable » du processus cible a une autre valeur que 1 ( SUID_DUMP_USER ; voir le point sur PR_SET_DUMPABLE dans prctl (2)) et lâappelant nâa pas la capacitĂ© CAP_SYS_PTRACE dans lâespace de noms de lâutilisateur du processus cible.
|
(5) |
Lâinterface security_ptrace_access_check () du LSM du noyau est appelĂ©e pour voir si lâaccĂšs ptrace est autorisĂ©. Le rĂ©sultat dĂ©pend des LSM. LâimplĂ©mentation de cette interface dans le LSM commoncap suit les Ă©tapes suivantes : |
(5.1)
|
Si le mode dâaccĂšs comprend PTRACE_MODE_FSCREDS , utiliser lâensemble des capacitĂ©s effectives de lâappelant dans la prochaine vĂ©rification ; sinon (si le mode dâaccĂšs indique PTRACE_MODE_REALCREDS ), utiliser lâensemble des capacitĂ©s autorisĂ©es de lâappelant. |
|||
|
(5.2) |
Interdire lâaccĂšs si rien de ce qui suit nâest vrai : |
-
|
Les processus appelant et cible sont dans le mĂȘme espace de noms utilisateur et les capacitĂ©s de lâappelant sont un surensemble des capacitĂ©s autorisĂ©es du processus cible. |
|||
|
- |
Lâappelant a la capacitĂ© CAP_SYS_PTRACE dans lâespace de noms utilisateur du processus cible. |
Remarquez que le LSM commoncap ne fait pas de différence entre PTRACE_MODE_READ et PTRACE_MODE_ATTACH .
|
(6) |
Si lâaccĂšs nâa pas Ă©tĂ© interdit par une Ă©tape prĂ©cĂ©dente, il est autorisĂ©. |
/proc/sys/kernel/yama/ptrace_scope
Sur des systĂšmes ayant un Yama Linux Security Module (LSM) installĂ© (donc si le noyau a Ă©tĂ© configurĂ© avec CONFIG_SECURITY_YAMA ), le fichier /proc/sys/kernel/yama/ptrace_scope (disponible depuis Linux 3.4) peut ĂȘtre utilisĂ© pour restreindre la possibilitĂ© dâobserver un processus avec ptrace () (et ainsi, celle dâutiliser des outils tels que strace (1) et gdb (1)). Le but de telles restrictions est dâempĂȘcher des attaques en cascade par lesquelles un processus infectĂ© peut sâattacher avec un ptrace Ă dâautres processus sensibles (comme un agent GPG ou une session SSH) appartenant Ă lâutilisateur, afin dâobtenir dâautres droits qui pourraient exister en mĂ©moire et ainsi, Ă©largir lâobjectif de lâattaque.
Plus prĂ©cisĂ©ment, le Yama LSM limite deux types dâopĂ©rations :
|
- |
Toute opĂ©ration qui effectue une vĂ©rification PTRACE_MODE_ATTACH de mode dâaccĂšs (par exemple, PTRACE_ATTACH de ptrace (), voir le point sur les « vĂ©rifications de mode dâaccĂšs ptrace » ci-dessus). |
||
|
- |
PTRACE_TRACEME ptrace (). |
Un processus
ayant la capacité
CAP_SYS_PTRACE
peut mettre
Ă jour le fichier
/proc/sys/kernel/yama/ptrace_scope
avec une ou
plusieurs des valeurs suivantes :
0
(droits ptrace
« classiques »)
Aucune restriction supplémentaire sur les opérations qui effectuent des vérifications PTRACE_MODE_ATTACH (au-delà de celles imposées par le LSM commoncap et les autres).
Lâutilisation de PTRACE_TRACEME ne change pas.
1 (« ptrace restreint » (valeur par défaut)
Lors dâune opĂ©ration qui exige une vĂ©rification PTRACE_MODE_ATTACH , le processus appelant doit avoir soit la capacitĂ© CAP_SYS_PTRACE dans lâespace de noms utilisateur du processus cible, soit une relation prĂ©dĂ©finie avec le processus cible. Par dĂ©faut, la relation prĂ©dĂ©finie est que le processus cible doit ĂȘtre un descendant de lâappelant.
Un processus cible peut utiliser lâopĂ©ration PR_SET_PTRACER de prctl (2) pour dĂ©clarer un PID supplĂ©mentaire autorisĂ© Ă effectuer des opĂ©rations PTRACE_MODE_ATTACH sur la cible. Voir le fichier Documentation/admin-guide/LSM/Yama.rst des sources du noyau (ou Documentation/security/Yama.txt avant Linux 4.13) pour plus de dĂ©tails.
Lâutilisation de PTRACE_TRACEME ne change pas.
2 (attachement « admin-only »)
Seuls les processus ayant la capacitĂ© CAP_SYS_PTRACE dans lâespace de noms de lâutilisateur du processus cible peuvent effectuer des opĂ©rations PTRACE_MODE_ATTACH ou observer les enfants qui utilisent PTRACE_TRACEME .
3 (« pas dâattachement »)
Aucun processus ne peut effectuer dâopĂ©ration PTRACE_MODE_ATTACH ou observer les enfants qui utilisent PTRACE_TRACEME .
Une fois que cette valeur a Ă©tĂ© Ă©crite dans le fichier, elle ne peut pas ĂȘtre modifiĂ©e.
Par rapport aux valeurs 1 et 2 , remarquez que la crĂ©ation dâun nouvel espace de noms utilisateur supprime de fait la protection apportĂ©e par Yama. Cela parce quâun processus dans lâespace de noms de lâutilisateur parent dont lâidentifiant utilisateur effectif correspond Ă celui de lâespace de noms enfant a toutes les capacitĂ©s (y compris CAP_SYS_PTRACE ) lorsquâil effectue des opĂ©rations dans lâespace de noms utilisateur de lâenfant (et les descendants supprimĂ©s plus tard de cet espace de noms). Par consĂ©quent, quand un processus essaie dâutiliser les espaces de noms utilisateur pour sâisoler lui-mĂȘme, il affaiblit Ă son insu les protections apportĂ©es par le Yama LSM.
Différences entre bibliothÚque C et noyau
Lâinterface de programmation de lâappel systĂšme est diffĂ©rente pour les opĂ©rations PTRACE_PEEKTEXT , PTRACE_PEEKDATA et PTRACE_PEEKUSER : elles stockent le rĂ©sultat Ă lâadresse indiquĂ©e par le paramĂštre data , et la valeur de retour est lâattribut dâerreur. La fonction glibc encapsulant cet appel fournit une interface dĂ©taillĂ©e dans la section DESCRIPTION ci-dessus, et le rĂ©sultat quâelle renvoie est le rĂ©sultat de lâappel systĂšme.
BOGUES
Sur les machines ayant des en-tĂȘtes du noyau Linux 2.6, PTRACE_SETOPTIONS est dĂ©clarĂ© avec une valeur diffĂ©rente de celle de Linux 2.4. De ce fait, les applications compilĂ©es avec des en-tĂȘtes du noyau Linux 2.6 ne peuvent pas sâexĂ©cuter sous Linux 2.4. Il est possible de contourner cette difficultĂ© en redĂ©finissant PTRACE_SETOPTIONS Ă PTRACE_OLDSETOPTIONS , si cette derniĂšre constante est dĂ©finie.
Les notifications dâarrĂȘt-groupe sont envoyĂ©es Ă lâobservateur, mais pas au vrai parent. CâĂ©tait encore vrai sur 2.6.38.6.
Si un leader de groupe de threads est suivi et existe en appelant _exit (2), un arrĂȘt PTRACE_EVENT_EXIT lui arrivera (si rĂ©clamĂ©), mais la notification WIFEXITED suivante ne sera pas distribuĂ©e avant la fin de tous les autres threads. Comme expliquĂ© prĂ©cĂ©demment, si un des autres threads appelle execve (2), la mort du leader de groupe de threads ne sera jamais signalĂ©e. Si le thread exĂ©cutĂ© nâest pas suivi par cet observateur, lâobservĂ© ne saura jamais quâ execve (2) est arrivĂ©. Un contournement possible est de PTRACE_DETACH er le leader de groupe de threads au lieu de le redĂ©marrer dans ce cas. CâĂ©tait encore vrai sur 2.6.38.6.
Un signal SIGKILL pourrait encore provoquer un arrĂȘt PTRACE_EVENT_EXIT avant une vĂ©ritable mort du signal. Cela pourrait Ă©voluer Ă lâavenir. SIGKILL est supposĂ© tuer immĂ©diatement les tĂąches mĂȘme sous ptrace. CâĂ©tait encore vrai sur Linux 3.13.
Certains appels systĂšme renvoient EINTR si un signal a Ă©tĂ© envoyĂ© Ă lâobservĂ©, mais que la distribution a Ă©tĂ© supprimĂ©e par lâobservateur (câest une opĂ©ration tout Ă fait caractĂ©ristique : elle est normalement rĂ©alisĂ©e par les dĂ©bogueurs sur tous les attachements, afin de ne pas introduire de SIGSTOP dĂ©fectueux). Depuis Linux 3.2.9, les appels systĂšme suivants sont concernĂ©s (cette liste est sans doute incomplĂšte) : epoll_wait (2) et read (2) depuis un descripteur de fichier inotify (7). Le symptĂŽme classique de ce bogue est quâen attachant Ă un processus quiescent avec la commande
strace -p <process-ID>
alors, au lieu de la ligne de sortie habituelle attendue comme
restart_syscall(<... reprise de lâappel interrompu ...>_
ou
select(6, [5], NULL, [5], NULL_
(« _ » indique la position du curseur), plusieurs lignes sont affichées. Par exemple :
clock_gettime(CLOCK_MONOTONIC,
{15370, 690928118}) = 0
epoll_wait(4,_
Ce qui nâest pas visible ici est que le processus a Ă©tĂ© bloquĂ© dans epoll_wait (2) avant que strace (1) ne sây soit attachĂ©. Lâattachement a forcĂ© epoll_wait (2) Ă revenir dans lâespace utilisateur avec lâerreur EINTR . Dans ce cas particulier, le programme a rĂ©agit Ă EINTR en vĂ©rifiant lâheure actuelle et en exĂ©cutant encore epoll_wait (2) (les programmes qui ne sâattendent pas Ă de telles erreurs EINTR « perdue » risquent de se comporter de façon inattendue sur une attache strace (1)).
Contrairement aux rĂšgles normales, lâenveloppe de la glibc pour ptrace () peut positionner errno sur zĂ©ro.
VOIR AUSSI
gdb (1), ltrace (1), strace (1), clone (2), execve (2), fork (2), gettid (2), prctl (2), seccomp (2), sigaction (2), tgkill (2), vfork (2), waitpid (2), exec (3), capabilities (7), signal (7)
TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>
Cette traduction est une documentation libre ; veuillez vous reporter Ă la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il nây a aucune RESPONSABILITĂ LĂGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org .