เจฏเฉเจจเจฟเจเจธ-เจตเจฐเจเฉ เจเจชเจฐเฉเจเจฟเฉฐเจ เจธเจฟเจธเจเจฎเจพเจ เจตเจฟเฉฑเจ, เจเฉฑเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฆเจพ เจฌเจพเจนเจฐเฉ เจธเฉฐเจธเจพเจฐ เจ เจคเฉ เจเจชเจฐเฉเจเจฟเฉฐเจ เจธเจฟเจธเจเจฎ เจจเจพเจฒ เจธเฉฐเจเจพเจฐ เจซเฉฐเจเจธเจผเจจเจพเจ เจฆเฉ เจเฉฑเจ เจเฉเจเฉ เจธเจฎเฉเจน เจฆเฉเจเจฐเจพ เจนเฉเฉฐเจฆเจพ เจนเฉ - เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจเฅค เจเจธเจฆเจพ เจฎเจคเจฒเจฌ เจเจน เจนเฉ เจเจฟ เจกเฉเจฌเฉฑเจเจฟเฉฐเจ เจเจฆเฉเจธเจผเจพเจ เจฒเจ เจเจน เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจฆเฉเจเจฐเจพ เจเจฒเจพเจเจเจ เจเจพ เจฐเจนเฉเจเจ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจฆเฉ เจเจพเจธเฉเจธเฉ เจเจฐเจจเจพ เจฒเจพเจญเจฆเจพเจเจ เจนเฉ เจธเจเจฆเจพ เจนเฉเฅค
เจเฉฑเจ เจเจชเจฏเฉเจเจคเจพ เจคเฉเจนเจพเจจเฉเฉฐ เจฒเฉเจจเจเจธ 'เจคเฉ เจชเฉเจฐเฉเจเจฐเจพเจฎเจพเจ เจฆเฉ "เจ
เฉฐเจคเจฐเจเจจ เจเฉเจตเจจ" เจฆเฉ เจจเจฟเจเจฐเจพเจจเฉ เจเจฐเจจ เจตเจฟเฉฑเจ เจฎเจฆเจฆ เจเจฐเจฆเฉ เจนเฉ strace
, เจเฉ เจเจฟ เจเจธ เจฒเฉเจ เจฆเจพ เจตเจฟเจธเจผเจพ เจนเฉเฅค เจเจพเจธเฉเจธเฉ เจเจชเจเจฐเจฃเจพเจ เจฆเฉ เจตเจฐเจคเฉเจ เจฆเฉเจเจ เจเจฆเจพเจนเจฐเจฃเจพเจ เจเฉฑเจ เจธเฉฐเจเฉเจช เจเจคเจฟเจนเจพเจธ เจฆเฉ เจจเจพเจฒ เจนเจจ strace
เจ
เจคเฉ เจ
เจเจฟเจนเฉ เจชเฉเจฐเฉเจเจฐเจพเจฎเจพเจ เจฆเฉ เจกเจฟเจเจผเจพเจเจจ เจฆเจพ เจตเฉเจฐเจตเจพเฅค
เจธเจฎเฉฑเจเจฐเฉ
เจธเจชเฉเจธเฉเจเจผ เจฆเจพ เจฎเฉเจฒ เจธเฉฐเจเฉเจช เจตเจฟเฉฑเจ เจธเจเฉเจฐเฉเจธ เจกเจฟเจตเจพเจเจธ: เจชเจฟเจเจฒเฉเจ เจเจฐเฉเจธ เจฌเฉเจจเจฟเจเจฆ: เจเฉฑเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจเฉฑเจฒ เจฐเจฟเจนเจพ strace เจจเฉเฉฐ เจเจฒเจพเจเจฃเจพ เจฌเฉเจจเจฟเจเจฆ: เจเฉฑเจกเจฆเฉ เจนเฉเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจตเจฟเฉฑเจ เจธเจผเจพเจฎเจฒ เจนเฉเจฃเจพ เจเจฆเจพเจนเจฐเจจ: เจฌเจพเจฒ เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจจเฉเฉฐ เจเจฐเฉเจ เจเจฐเจจเจพ เจเจฆเจพเจนเจฐเจจ: เจนเฉเจเจกเจฒ เจฆเฉ เจฌเจเจพเจ เจซเจพเจเจฒ เจชเจพเจฅ เจเจฆเจพเจนเจฐเจจ: เจซเจพเจเจฒ เจเจเจธเฉเจธ เจเฉเจฐเฉเจเจฟเฉฐเจ เจเจฆเจพเจนเจฐเจจ: เจฎเจฒเจเฉเจฅเฉเจฐเฉเจกเจก เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฎเจพเจธเจเจฐ เจเจฒเจพเจธ: เจธเจฟเจธเจเจฎ เจเจพเจฒ เจฆเฉ เจธเจฎเฉเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจธเจเฉเจ เจฎเจพเจธเจเจฐ เจเจฒเจพเจธ: เจเจฒเจคเฉ เจเฉเจเจพ เจฌเจพเจ เจฆ
เจธเจชเฉเจธเฉเจเจผ เจฆเจพ เจฎเฉเจฒ
เจฏเฉเจจเจฟเจเจธ เจตเจฟเฉฑเจ เจชเฉเจฐเฉเจเจฐเจพเจฎเจพเจ เจ เจคเฉ OS เจเจฐเจจเจฒ เจตเจฟเจเจเจพเจฐ เจฎเฉเฉฑเจ เจเฉฐเจเจฐเจซเฉเจธ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจนเจจเฅค เจธเจฟเจธเจเจฎ เจเจพเจฒ, เจธเจพเจเจเจฒ), เจฌเจพเจนเจฐเฉ เจธเฉฐเจธเจพเจฐ เจจเจพเจฒ เจชเฉเจฐเฉเจเจฐเจพเจฎเจพเจ เจฆเฉ เจเจชเจธเฉ เจคเจพเจฒเจฎเฉเจฒ เจตเจฟเจธเจผเฉเจธเจผ เจคเฉเจฐ 'เจคเฉ เจเจนเจจเจพเจ เจฆเฉเจเจฐเจพ เจนเฉเฉฐเจฆเฉ เจนเฉเฅค
เจชเจฐ เจฏเฉเจจเจฟเจเจธ เจฆเฉ เจชเจนเจฟเจฒเฉ เจเจจเจคเจ เจธเฉฐเจธเจเจฐเจฃ เจตเจฟเฉฑเจ (ptrace
.
ptrace เจฎเฉเฉฑเจ เจคเฉเจฐ 'เจคเฉ เจเฉฐเจเจฐเจเจเจเจฟเจต เจกเฉเจฌเฉฑเจเจฐเจพเจ เจฒเจ เจตเจฟเจเจธเจค เจเฉเจคเจพ เจเจฟเจ เจธเฉ, เจชเจฐ 80 เจฆเฉ เจฆเจนเจพเจเฉ เจฆเฉ เจ
เฉฐเจค เจคเฉฑเจ (เจตเจชเจพเจฐเจ เจฆเฉ เจฏเฉเฉฑเจ เจตเจฟเฉฑเจ
trace
เจธเฉเจฐเจ เจคเฉเจ. เจเจฒเฉเจจ เจ
เจคเฉ เจ
เจธเจฒเฉ เจฆเฉเจตเฉเจ เจธเจจเฉเจธ เจฒเจ เจคเจฟเจเจฐ เจเฉเจคเฉ เจเจ เจธเจจ, เจชเจฐ 1994 เจคเฉฑเจ strace
เจธเจฟเจธเจเจฎ V, เจธเฉเจฒเจพเจฐเจฟเจธ เจ
เจคเฉ เจตเจงเจฆเฉ เจชเฉเจฐเจธเจฟเฉฑเจง เจฒเฉเจจเจเจธ เจฒเจ เจชเฉเจฐเจ เจเฉเจคเจพ เจเจฟเจ เจธเฉเฅค
เจ
เฉฑเจ เจธเจเฉเจฐเฉเจธ เจธเจฟเจฐเจซเจผ เจฒเฉเจจเจเจธ เจฆเจพ เจธเจฎเจฐเจฅเจจ เจเจฐเจฆเจพ เจนเฉ เจ
เจคเฉ เจเจธเฉ 'เจคเฉ เจจเจฟเจฐเจญเจฐ เจเจฐเจฆเจพ เจนเฉ ptrace
, เจฌเจนเฉเจค เจธเจพเจฐเฉ เจเจเจธเจเฉเจเจธเจผเจจเจพเจ เจจเจพเจฒ เจตเจงเจฟเจ เจนเฉเจเจ เจนเฉเฅค
เจเจงเฉเจจเจฟเจ (เจ
เจคเฉ เจฌเจนเฉเจค เจธเจฐเจเจฐเจฎ) เจฐเฉฑเจ-เจฐเจเจพเจ
เจเจฐเจจ เจตเจพเจฒเจพ strace
-
เจเจน เจตเฉ เจฎเจนเฉฑเจคเจตเจชเฉเจฐเจจ เจนเฉ เจเจฟ เจฒเฉเจจเจเจธ, เจซเฉเจฐเฉเจฌเฉเจเจธเจกเฉ, เจเจชเจจเจฌเฉเจเจธเจกเฉ เจ เจคเฉ เจฐเจตเจพเจเจคเฉ เจฏเฉเจจเจฟเจเจธ เจตเจฟเฉฑเจ เจฒเฉฐเจฌเฉ เจเจคเจฟเจนเจพเจธ เจ เจคเฉ เจฒเจพเจเฉ เจนเฉเจฃ เจฆเฉ เจฌเจพเจตเจเฉเจฆ, ptrace เจธเจฟเจธเจเจฎ เจเจพเจฒ เจ เจคเฉ เจเจฐเฉเจธเจฐ เจเจฆเฉ เจตเฉ POSIX เจตเจฟเฉฑเจ เจธเจผเจพเจฎเจฒ เจจเจนเฉเจ เจเฉเจคเฉ เจเจ เจธเจจเฅค
เจธเฉฐเจเฉเจช เจตเจฟเฉฑเจ เจธเจเฉเจฐเฉเจธ เจกเจฟเจตเจพเจเจธ: เจชเจฟเจเจฒเฉเจ เจเจฐเฉเจธ
"เจคเฉเจนเจพเจกเฉ เจคเฉเจ เจเจน เจธเจฎเจเจฃ เจฆเฉ เจเจฎเฉเจฆ เจจเจนเฉเจ เจนเฉ" (เจกเฉเจจเจฟเจธ เจฐเจฟเจเฉ, เจธเฉฐเจธเจเจฐเจฃ 6 เจฏเฉเจจเจฟเจเจธ เจธเจฐเฉเจค เจเฉเจก เจตเจฟเฉฑเจ เจเจฟเฉฑเจชเจฃเฉ)
เจฌเจเจชเจจ เจคเฉเจ เจนเฉ, เจฎเฉเจ เจฌเจฒเฉเจ เจฌเจพเจเจธ เจจเฉเฉฐ เจเฉเจพ เจจเจนเฉเจ เจเจฐ เจธเจเจฆเจพ: เจฎเฉเจ เจเจฟเจกเฉเจฃเจฟเจเจ เจจเจพเจฒ เจจเจนเฉเจ เจเฉเจกเจฟเจ, เจชเจฐ เจเจนเจจเจพเจ เจฆเฉ เจฌเจฃเจคเจฐ เจจเฉเฉฐ เจธเจฎเจเจฃ เจฆเฉ เจเฉเจธเจผเจฟเจธเจผ เจเฉเจคเฉ (เจฌเจพเจฒเจเจพเจ เจจเฉ "เจเฉเฉฑเจเจฟเจ" เจธเจผเจฌเจฆ เจตเจฐเจคเจฟเจ, เจชเจฐ เจฌเฉเจฐเจพเจเจเจ 'เจคเฉ เจตเจฟเจธเจผเจตเจพเจธ เจจเจพ เจเจฐเฉ)เฅค เจธเจผเจพเจเจฆ เจเจนเฉ เจเจพเจฐเจจ เจนเฉ เจเจฟ เจชเจนเจฟเจฒเฉ เจฏเฉเจจเจฟเจเจธ เจ เจคเฉ เจเจงเฉเจจเจฟเจ เจเจชเจจ-เจธเฉเจฐเจธ เจ เฉฐเจฆเฉเจฒเจจ เจฆเจพ เจเฉเจฐ เจฐเจธเจฎเฉ เจธเฉฑเจญเจฟเจเจเจพเจฐ เจฎเฉเจฐเฉ เจฌเจนเฉเจค เจจเฉเฉเฉ เจนเฉเฅค
เจเจธ เจฒเฉเจ เจฆเฉ เจเจฆเฉเจธเจผเจพเจ เจฒเจ, เจธเจเฉเจฐเฉเจธ เจฆเฉ เจธเจฐเฉเจค เจเฉเจก เจจเฉเฉฐ เจตเฉฑเจ เจเจฐเจจเจพ เจเฉเจฐ-เจตเจพเจเจฌ เจนเฉ, เจเฉ เจฆเจนเจพเจเจฟเจเจ เจคเฉเจ เจตเจงเจฟเจ เจนเฉเฅค เจชเจฐ เจชเจพเจ เจเจพเจ เจฒเจ เจเฉเจ เจญเฉเจค เจจเจนเฉเจ เจเฉฑเจกเจฃเจพ เจเจพเจนเฉเจฆเจพเฅค เจเจธ เจฒเจ, เจ
เจเจฟเจนเฉ เจธเจเจฐเฉเจธ เจชเฉเจฐเฉเจเจฐเจพเจฎเจพเจ เจฆเฉ เจธเฉฐเจเจพเจฒเจจ เจฆเฉ เจธเจฟเจงเจพเจเจค เจจเฉเฉฐ เจฆเจฐเจธเจพเจเจฃ เจฒเจ, เจฎเฉเจ เจเฉฑเจ เจเฉเจเฉ เจเจฐเฉเจธเจฐ เจฒเจ เจเฉเจก เจชเฉเจฐเจฆเจพเจจ เจเจฐเจพเจเจเจพ -
$ gcc examples/piglet-trace.c -o ptr
$ ptr echo test > /dev/null
BRK(12) -> 94744690540544
ACCESS(21) -> 18446744073709551614
ACCESS(21) -> 18446744073709551614
unknown(257) -> 3
FSTAT(5) -> 0
MMAP(9) -> 140694657216512
CLOSE(3) -> 0
ACCESS(21) -> 18446744073709551614
unknown(257) -> 3
READ(0) -> 832
FSTAT(5) -> 0
MMAP(9) -> 140694657208320
MMAP(9) -> 140694650953728
MPROTECT(10) -> 0
MMAP(9) -> 140694655045632
MMAP(9) -> 140694655070208
CLOSE(3) -> 0
unknown(158) -> 0
MPROTECT(10) -> 0
MPROTECT(10) -> 0
MPROTECT(10) -> 0
MUNMAP(11) -> 0
BRK(12) -> 94744690540544
BRK(12) -> 94744690675712
unknown(257) -> 3
FSTAT(5) -> 0
MMAP(9) -> 140694646390784
CLOSE(3) -> 0
FSTAT(5) -> 0
IOCTL(16) -> 18446744073709551591
WRITE(1) -> 5
CLOSE(3) -> 0
CLOSE(3) -> 0
unknown(231)
Tracee terminated
เจชเจฟเจเจฒเฉเจ เจเจฐเฉเจธ เจฒเจเจญเจ เจธเฉเจเจเฉเฉ เจฒเฉเจจเจเจธ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจชเจเจพเจฃเจฆเจพ เจนเฉ (เจตเฉเจเฉ.
เจเจ เจเจชเจฃเฉ เจเจฒเฉเจจ เจฆเฉ เจเฉฐเจฎ เจจเฉเฉฐ เจตเฉเจเฉเจ. เจฒเฉเจจเจเจธ เจฆเฉ เจฎเจพเจฎเจฒเฉ เจตเจฟเฉฑเจ, เจกเฉเจฌเฉฑเจเจฐ เจ
เจคเฉ เจเจฐเฉเจธเจฐ, เจเจฟเจตเฉเจ เจเจฟ เจเฉฑเจชเจฐ เจฆเฉฑเจธเจฟเจ เจเจฟเจ เจนเฉ, ptrace เจธเจฟเจธเจเจฎ เจเจพเจฒ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจฆเฉ เจนเจจเฅค เจเจน เจชเจนเจฟเจฒเฉ เจเจฐเจเฉเจฎเฉเจเจ เจตเจฟเฉฑเจ เจเจฎเจพเจเจก เจชเจเจพเจฃเจเจฐเจคเจพ เจจเฉเฉฐ เจชเจพเจธ เจเจฐเจเฉ เจเฉฐเจฎ เจเจฐเจฆเจพ เจนเฉ, เจเจฟเจธเจฆเฉ เจธเจพเจจเฉเฉฐ เจธเจฟเจฐเจซเจผ เจฒเฉเฉ เจนเฉ PTRACE_TRACEME
, PTRACE_SYSCALL
ะธ PTRACE_GETREGS
.
เจเจฐเฉเจธเจฐ เจเจฎ เจฏเฉเจจเจฟเจเจธ เจธเจผเฉเจฒเฉ เจตเจฟเฉฑเจ เจธเจผเฉเจฐเฉ เจนเฉเฉฐเจฆเจพ เจนเฉ: fork(2)
เจเฉฑเจ เจเจพเจเจฒเจก เจชเฉเจฐเจเจฟเจฐเจฟเจ เจธเจผเฉเจฐเฉ เจเจฐเจฆเจพ เจนเฉ, เจเฉ เจฌเจฆเจฒเฉ เจตเจฟเฉฑเจ เจตเจฐเจคเจฆเจพ เจนเฉ exec(3)
เจ
เจงเจฟเจเจจ เจ
เจงเฉเจจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฆเฉ เจธเจผเฉเจฐเฉเจเจค เจเจฐเจฆเจพ เจนเฉเฅค เจเฉฑเจฅเฉ เจธเจฟเจฐเจซ เจธเฉเจเจฎเจคเจพ เจเฉเจฃเฉเจคเฉ เจนเฉ ptrace(PTRACE_TRACEME)
ะฟะตัะตะด exec
: เจฌเจพเจฒ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฎเจพเจคเจพ-เจชเจฟเจคเจพ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจคเฉเจ เจเจธเจฆเฉ เจจเจฟเจเจฐเจพเจจเฉ เจเจฐเจจ เจฆเฉ เจเจฎเฉเจฆ เจเจฐเจฆเฉ เจนเฉ:
pid_t child_pid = fork();
switch (child_pid) {
case -1:
err(EXIT_FAILURE, "fork");
case 0:
/* Child here */
/* A traced mode has to be enabled. A parent will have to wait(2) for it
* to happen. */
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
/* Replace itself with a program to be run. */
execvp(argv[1], argv + 1);
err(EXIT_FAILURE, "exec");
}
เจฎเจพเจคเจพ-เจชเจฟเจคเจพ เจฆเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจจเฉเฉฐ เจนเฉเจฃ เจเจพเจฒ เจเจฐเจจเจพ เจเจพเจนเฉเจฆเจพ เจนเฉ wait(2)
เจเจพเจเจฒเจก เจชเฉเจฐเจเจฟเจฐเจฟเจ เจตเจฟเฉฑเจ, เจฏเจพเจจเฉ, เจฏเจเฉเจจเฉ เจฌเจฃเจพเจ เจเจฟ เจเจฐเฉเจธ เจฎเฉเจก เจตเจฟเฉฑเจ เจธเจตเจฟเจ เจเจฐเจจเจพ เจนเฉเจเจ เจนเฉ:
/* Parent */
/* First we wait for the child to set the traced mode (see
* ptrace(PTRACE_TRACEME) above) */
if (waitpid(child_pid, NULL, 0) == -1)
err(EXIT_FAILURE, "traceme -> waitpid");
เจเจธ เจธเจฎเฉเจ, เจคเจฟเจเจฐเฉเจเจ เจชเฉเจฐเฉเจเจ เจนเฉ เจเจเจเจ เจนเจจ เจ เจคเฉ เจคเฉเจธเฉเจ เจเฉฑเจ เจฌเฉเจ เฉฐเจค เจฒเฉเจช เจตเจฟเฉฑเจ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจเจฐเฉเจ เจเจฐเจจ เจฒเจ เจธเจฟเฉฑเจงเฉ เจ เฉฑเจเฉ เจตเจง เจธเจเจฆเฉ เจนเฉเฅค
เจเฉเจฃเฉเจคเฉ ptrace(PTRACE_SYSCALL)
เจเจธ เจคเฉเจ เจฌเจพเจ
เจฆ เจฆเฉ เจเจพเจฐเฉฐเจเฉ เจฆเจฟเฉฐเจฆเจพ เจนเฉ wait
เจฎเจพเจคเจพ เจเจพเจ เจคเจพเจ เจธเจฟเจธเจเจฎ เจเจพเจฒ เจฆเฉ เจเจเจเจผเฉเจเจฟเจเจ เจนเฉเจฃ เจคเฉเจ เจชเจนเจฟเจฒเจพเจ เจเจพเจ เจเจธ เจฆเฉ เจชเฉเจฐเจพ เจนเฉเจฃ เจคเฉเจ เจคเฉเจฐเฉฐเจค เจฌเจพเจ
เจฆ เจชเฉเจฐเจพ เจนเฉ เจเจพเจตเฉเจเจพเฅค เจฆเฉ เจเจพเจฒเจพเจ เจฆเฉ เจตเจฟเจเจเจพเจฐ เจคเฉเจธเฉเจ เจเฉเจ เจตเฉ เจเจพเจฐเจตเจพเจเจเจ เจเจฐ เจธเจเจฆเฉ เจนเฉ: เจเจพเจฒ เจจเฉเฉฐ เจเจฟเจธเฉ เจตเจฟเจเจฒเจชเจ เจจเจพเจฒ เจฌเจฆเจฒเฉ, เจเจฐเจเฉเจฎเฉเจเจเจธ เจเจพเจ เจตเจพเจชเจธเฉ เจฎเฉเฉฑเจฒ เจฌเจฆเจฒเฉเฅค
เจธเจพเจจเฉเฉฐ เจธเจฟเจฐเจซเจผ เจฆเฉ เจตเจพเจฐ เจเจฎเจพเจเจก เจจเฉเฉฐ เจเจพเจฒ เจเจฐเจจ เจฆเฉ เจฒเฉเฉ เจนเฉ ptrace(PTRACE_GETREGS)
เจฐเจเจฟเจธเจเจฐ เจฐเจพเจ เจชเฉเจฐเจพเจชเจค เจเจฐเจจ เจฒเจ rax
เจเจพเจฒ เจคเฉเจ เจชเจนเจฟเจฒเจพเจ (เจธเจฟเจธเจเจฎ เจเจพเจฒ เจจเฉฐเจฌเจฐ) เจ
เจคเฉ เจคเฉเจฐเฉฐเจค เจฌเจพเจ
เจฆ (เจตเจพเจชเจธเฉ เจฎเฉเฉฑเจฒ)เฅค
เจ เจธเจฒ เจตเจฟเฉฑเจ, เจเฉฑเจเจฐ:
/* A system call tracing loop, one interation per call. */
for (;;) {
/* A non-portable structure defined for ptrace/GDB/strace usage mostly.
* It allows to conveniently dump and access register state using
* ptrace. */
struct user_regs_struct registers;
/* Enter syscall: continue execution until the next system call
* beginning. Stop right before syscall.
*
* It's possible to change the system call number, system call
* arguments, return value or even avoid executing the system call
* completely. */
if (ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL) == -1)
err(EXIT_FAILURE, "enter_syscall");
if (waitpid(child_pid, NULL, 0) == -1)
err(EXIT_FAILURE, "enter_syscall -> waitpid");
/* According to the x86-64 system call convention on Linux (see man 2
* syscall) the number identifying a syscall should be put into the rax
* general purpose register, with the rest of the arguments residing in
* other general purpose registers (rdi,rsi, rdx, r10, r8, r9). */
if (ptrace(PTRACE_GETREGS, child_pid, NULL, ®isters) == -1)
err(EXIT_FAILURE, "enter_syscall -> getregs");
/* Note how orig_rax is used here. That's because on x86-64 rax is used
* both for executing a syscall, and returning a value from it. To
* differentiate between the cases both rax and orig_rax are updated on
* syscall entry/exit, and only rax is updated on exit. */
print_syscall_enter(registers.orig_rax);
/* Exit syscall: execute of the syscall, and stop on system
* call exit.
*
* More system call tinkering possible: change the return value, record
* time it took to finish the system call, etc. */
if (ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL) == -1)
err(EXIT_FAILURE, "exit_syscall");
if (waitpid(child_pid, NULL, 0) == -1)
err(EXIT_FAILURE, "exit_syscall -> waitpid");
/* Retrieve register state again as we want to inspect system call
* return value. */
if (ptrace(PTRACE_GETREGS, child_pid, NULL, ®isters) == -1) {
/* ESRCH is returned when a child terminates using a syscall and no
* return value is possible, e.g. as a result of exit(2). */
if (errno == ESRCH) {
fprintf(stderr, "nTracee terminatedn");
break;
}
err(EXIT_FAILURE, "exit_syscall -> getregs");
}
/* Done with this system call, let the next iteration handle the next
* one */
print_syscall_exit(registers.rax);
}
เจเจน เจธเจพเจฐเจพ เจเจฐเฉเจธเจฐ เจนเฉเฅค เจนเฉเจฃ เจคเฉเจธเฉเจ เจเจพเจฃเจฆเฉ เจนเฉ เจเจฟ เจ
เจเจฒเฉ เจชเฉเจฐเจเจฟเฉฐเจ เจเจฟเฉฑเจฅเฉเจ เจธเจผเฉเจฐเฉ เจเจฐเจจเฉ เจนเฉ
เจฌเฉเจจเจฟเจเจฆ: เจเฉฑเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจเฉฑเจฒ เจฐเจฟเจนเจพ strace เจจเฉเฉฐ เจเจฒเจพเจเจฃเจพ
เจชเจนเจฟเจฒเฉ เจตเจฐเจคเฉเจ เจฆเฉ เจเฉเจธ เจตเจเฉเจ strace
, เจธเจผเจพเจเจฆ เจเจน เจธเจญ เจคเฉเจ เจธเจฐเจฒ เจตเจฟเจงเฉ เจฆเจพ เจนเจตเจพเจฒเจพ เจฆเฉเจฃ เจฆเฉ เจฏเฉเจ เจนเฉ - เจเฉฑเจฒ เจฐเจนเฉ เจเฉฑเจ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจจเฉเฉฐ เจฒเจพเจเจ เจเจฐเจจเจพ strace
.
เจเฉฑเจ เจเจฎ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฆเฉเจเจ เจเจพเจฒเจพเจ เจฆเฉ เจฌเฉเจ
เฉฐเจค เจธเฉเจเฉ เจตเจฟเฉฑเจ เจจเจพ เจเจพเจฃ เจฒเจ, เจ
เจธเฉเจ เจฒเจฟเจเจฆเฉ เจนเจพเจ write
:
int main(int argc, char *argv[])
{
char str[] = "write me to stdoutn";
/* write(2) is a simple wrapper around a syscall so it should be easy to
* find in the syscall trace. */
if (sizeof(str) != write(STDOUT_FILENO, str, sizeof(str))){
perror("write");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
เจเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฌเจฃเจพเจ เจ เจคเฉ เจฏเจเฉเจจเฉ เจฌเจฃเจพเจ เจเจฟ เจเจน เจเฉฐเจฎ เจเจฐเจฆเจพ เจนเฉ:
$ gcc examples/write-simple.c -o write-simple
$ ./write-simple
write me to stdout
เจ เจคเฉ เจ เฉฐเจค เจตเจฟเฉฑเจ, เจเจ เจเจธเจจเฉเฉฐ เจธเจเฉเจฐเฉเจธ เจจเจฟเจฏเฉฐเจคเจฐเจฃ เจตเจฟเฉฑเจ เจเจฒเจพเจเจ:
$ strace ./write-simple
pexecve("./write", ["./write"], 0x7ffebd6145b0 /* 71 vars */) = 0
brk(NULL) = 0x55ff5489e000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=197410, ...}) = 0
mmap(NULL, 197410, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7a2a633000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF21133>1260342"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7a2a631000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7a2a04c000
mprotect(0x7f7a2a233000, 2097152, PROT_NONE) = 0
mmap(0x7f7a2a433000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f7a2a433000
mmap(0x7f7a2a439000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7a2a439000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f7a2a6324c0) = 0
mprotect(0x7f7a2a433000, 16384, PROT_READ) = 0
mprotect(0x55ff52b52000, 4096, PROT_READ) = 0
mprotect(0x7f7a2a664000, 4096, PROT_READ) = 0
munmap(0x7f7a2a633000, 197410) = 0
write(1, "write me to stdoutn", 20write me to stdout
) = 20
exit_group(0) = ?
เจฌเจนเฉเจค "เจธเจผเจฌเจฆ" เจ
เจคเฉ เจฌเจนเฉเจค เจตเจฟเจฆเจฟเจ
เจ เจจเจนเฉเจเฅค เจเฉฑเจฅเฉ เจฆเฉ เจธเจฎเฉฑเจธเจฟเจเจตเจพเจ เจนเจจ: เจชเฉเจฐเฉเจเจฐเจพเจฎ เจเจเจเจชเฉเฉฑเจ เจจเฉเฉฐ เจเจเจเจชเฉเฉฑเจ เจจเจพเจฒ เจฎเจฟเจฒเจพเจเจ เจเจพเจเจฆเจพ เจนเฉ strace
เจ
เจคเฉ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจฆเฉ เจฌเจนเฉเจคเจพเจค เจเฉ เจธเจพเจกเฉ เจฆเจฟเจฒเจเจธเจชเฉ เจจเจนเฉเจ เจฐเฉฑเจเจฆเฉเฅค
เจคเฉเจธเฉเจ -o เจธเจตเจฟเฉฑเจ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจเฉ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฆเฉ เจธเจเฉเจเจกเจฐเจก เจเจเจเจชเฉเฉฑเจ เจธเจเฉเจฐเฉเจฎ เจ เจคเฉ เจธเจเฉเจฐเฉเจธ เจเจฐเจฐ เจเจเจเจชเฉเฉฑเจ เจจเฉเฉฐ เจตเฉฑเจ เจเจฐ เจธเจเจฆเฉ เจนเฉ, เจเฉ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจฆเฉ เจธเฉเจเฉ เจจเฉเฉฐ เจเฉฑเจ เจเจฐเจเฉเจฎเฉเจเจ เจซเจพเจเจฒ เจตเจฟเฉฑเจ เจฐเฉเจกเจพเจเจฐเฉเจเจ เจเจฐเจฆเจพ เจนเฉเฅค
เจเจน "เจตเจพเจงเฉ" เจเจพเจฒเจพเจ เจฆเฉ เจธเจฎเฉฑเจธเจฟเจ เจจเจพเจฒ เจจเจเจฟเฉฑเจ เจฃเจพ เจฌเจพเจเฉ เจนเฉเฅค เจเจฒเฉ เจเจน เจฎเฉฐเจจ เจฒเจ เจเจฟ เจ
เจธเฉเจ เจธเจฟเจฐเจซ เจเจพเจฒเจพเจ เจตเจฟเฉฑเจ เจฆเจฟเจฒเจเจธเจชเฉ เจฐเฉฑเจเจฆเฉ เจนเจพเจ write
. เจเฉเฉฐเจเฉ -e
เจคเฉเจนเจพเจจเฉเฉฐ เจธเจฎเฉเจเจฐเจจ เจจเจฟเจฐเจงเจพเจฐเจค เจเจฐเจจ เจฆเฉ เจเจเจพเจเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉ เจเจฟเจธ เจฆเฉเจเจฐเจพ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจซเจฟเจฒเจเจฐ เจเฉเจคเจพ เจเจพเจตเฉเจเจพเฅค เจธเจญ เจคเฉเจ เจชเฉเจฐเจธเจฟเฉฑเจง เจธเจฅเจฟเจคเฉ เจตเจฟเจเจฒเจช เจนเฉ, เจเฉเจฆเจฐเจคเฉ เจคเฉเจฐ 'เจคเฉ, trace=*
, เจเจฟเจธ เจจเจพเจฒ เจคเฉเจธเฉเจ เจธเจฟเจฐเจซเจผ เจเจนเจจเจพเจ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจเฉฑเจก เจธเจเจฆเฉ เจนเฉ เจเฉ เจธเจพเจกเฉ เจฆเจฟเจฒเจเจธเจชเฉ เจฐเฉฑเจเจฆเฉ เจนเจจเฅค
เจเจฆเฉเจ เจเฉฑเจเฉ เจธเจฎเฉเจ เจตเจฐเจคเจฟเจ เจเจพเจเจฆเจพ เจนเฉ -o
ะธ -e
เจธเจพเจจเฉเฉฐ เจฎเจฟเจฒเฉเจเจพ:
$ strace -e trace=write -owrite-simple.log ./write-simple
write me to stdout
$ cat write-simple.log
write(1, "write me to stdoutn", 20
) = 20
+++ exited with 0 +++
เจเจธ เจฒเจ, เจคเฉเจธเฉเจ เจฆเฉเจเฉ, เจเจน เจชเฉเฉเจนเจจเจพ เจฌเจนเฉเจค เจธเฉเจเจพ เจนเฉ.
เจคเฉเจธเฉเจ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจตเฉ เจนเจเจพ เจธเจเจฆเฉ เจนเฉ, เจเจฆเจพเจนเจฐเจจ เจฒเจ เจเฉ เจฎเฉเจฎเฉเจฐเฉ เจตเฉฐเจก เจ เจคเฉ เจเจพเจฒเฉ เจเจฐเจจ เจจเจพเจฒ เจธเจฌเฉฐเจงเจค เจนเจจ:
$ strace -e trace=!brk,mmap,mprotect,munmap -owrite-simple.log ./write-simple
write me to stdout
$ cat write-simple.log
execve("./write-simple", ["./write-simple"], 0x7ffe9972a498 /* 69 vars */) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=124066, ...}) = 0
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF21133>1260342"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f00f0be74c0) = 0
write(1, "write me to stdoutn", 20) = 20
exit_group(0) = ?
+++ exited with 0 +++
เจเฉฑเจขเฉเจเจ เจเจเจเจ เจเจพเจฒเจพเจ เจฆเฉ เจธเฉเจเฉ เจตเจฟเฉฑเจ เจฌเจเฉ เจตเจฟเจธเจฎเจฟเจ เจเจฟเฉฐเจจเฉเจน เจจเฉเฉฐ เจจเฉเจ เจเจฐเฉ: เจเจน เจเจฎเจพเจเจก เจธเจผเฉเฉฑเจฒ เจฆเฉเจเจฐเจพ เจฒเฉเฉเฉเจเจฆเจพ เจนเฉเฅค เจธเจผเฉเฉฑเจฒ).
glibc เจฆเฉ เจฎเฉเจฐเฉ เจธเฉฐเจธเจเจฐเจฃ เจตเจฟเฉฑเจ, เจเฉฑเจ เจธเจฟเจธเจเจฎ เจเจพเจฒ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจจเฉเฉฐ เจเจคเจฎ เจเจฐ เจฆเจฟเฉฐเจฆเฉ เจนเฉ exit_group
, เจฐเจตเจพเจเจคเฉ เจจเจนเฉเจ _exit
. เจเจน เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเจพเจฒ เจเฉฐเจฎ เจเจฐเจจ เจฆเฉ เจฎเฉเจธเจผเจเจฒ เจนเฉ: เจเฉฐเจเจฐเจซเฉเจธ เจเจฟเจธ เจจเจพเจฒ เจชเฉเจฐเฉเจเจฐเจพเจฎเจฐ เจเฉฐเจฎ เจเจฐเจฆเจพ เจนเฉ, เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเจพเจฒ เจธเจฟเฉฑเจงเฉ เจคเฉเจฐ 'เจคเฉ เจธเฉฐเจฌเฉฐเจงเจฟเจค เจจเจนเฉเจ เจนเฉเฅค เจเจธ เจคเฉเจ เจเจฒเจพเจตเจพ, เจเจน เจฒเจพเจเฉ เจเจฐเจจ เจ
เจคเฉ เจชเจฒเฉเจเจซเจพเจฐเจฎ 'เจคเฉ เจจเจฟเจฐเจญเจฐ เจเจฐเจฆเฉ เจนเฉเจ เจจเจฟเจฏเจฎเจฟเจค เจคเฉเจฐ 'เจคเฉ เจฌเจฆเจฒเจฆเจพ เจนเฉเฅค
เจฌเฉเจจเจฟเจเจฆ: เจเฉฑเจกเจฆเฉ เจนเฉเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจตเจฟเฉฑเจ เจธเจผเจพเจฎเจฒ เจนเฉเจฃเจพ
เจธเจผเฉเจฐเฉ เจตเจฟเฉฑเจ, ptrace เจธเจฟเจธเจเจฎ เจเจพเจฒ เจเจฟเจธ 'เจคเฉ เจเจธ เจจเฉเฉฐ เจฌเจฃเจพเจเจ เจเจฟเจ เจธเฉ strace
, เจธเจฟเจฐเจซ เจเจฆเฉเจ เจตเจฐเจคเจฟเจ เจเจพ เจธเจเจฆเจพ เจนเฉ เจเจฆเฉเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจจเฉเฉฐ เจเฉฑเจ เจตเจฟเจธเจผเฉเจธเจผ เจฎเฉเจก เจตเจฟเฉฑเจ เจเจฒเจพเจเจ เจเจพ เจฐเจฟเจนเจพ เจนเฉเจตเฉเฅค เจธเฉฐเจธเจเจฐเจฃ 6 เจฏเฉเจจเจฟเจเจธ เจฆเฉ เจฆเจฟเจจเจพเจ เจตเจฟเฉฑเจ เจเจน เจธเฉเจฎเจพ เจตเจพเจเจฌ เจฒเฉฑเจ เจธเจเจฆเฉ เจนเฉเฅค เจ
เฉฑเจเจเฉฑเจฒเฉเจน, เจเจน เจนเฉเจฃ เจเจพเจซเจผเฉ เจจเจนเฉเจ เจนเฉ: เจเจ เจตเจพเจฐ เจคเฉเจนเจพเจจเฉเฉฐ เจเจพเจฐเจเจธเจผเฉเจฒ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฆเฉเจเจ เจธเจฎเฉฑเจธเจฟเจเจตเจพเจ เจฆเฉ เจเจพเจเจ เจเจฐเจจ เจฆเฉ เจเจผเจฐเฉเจฐเจค เจนเฉเฉฐเจฆเฉ เจนเฉ. เจเฉฑเจ เจเจพเจธ เจเจฆเจพเจนเจฐเจจ เจนเฉเจเจกเจฒ เจเจพเจ เจธเจฒเฉเจชเจฟเฉฐเจ 'เจคเฉ เจฌเจฒเฉเจ เจเฉเจคเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจนเฉเฅค เจเจธ เจฒเจ เจเจงเฉเจจเจฟเจ strace
เจซเจฒเจพเจ 'เจคเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจตเจฟเฉฑเจ เจธเจผเจพเจฎเจฒ เจนเฉ เจธเจเจฆเฉ เจนเจจเฅค
เจ เฉฐเจขเจ เจฆเฉ เจเจฆเจพเจนเจฐเจจ
int main(int argc, char *argv[])
{
(void) argc; (void) argv;
char str[] = "write men";
write(STDOUT_FILENO, str, sizeof(str));
/* Sleep indefinitely or until a signal arrives */
pause();
write(STDOUT_FILENO, str, sizeof(str));
return EXIT_SUCCESS;
}
เจเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฌเจฃเจพเจ เจ เจคเฉ เจฏเจเฉเจจเฉ เจฌเจฃเจพเจ เจเจฟ เจเจน เจเฉฐเจฎเจฟเจ เจนเฉเจเจ เจนเฉ:
$ gcc examples/write-sleep.c -o write-sleep
$ ./write-sleep
./write-sleep
write me
^C
$
เจเจ เจนเฉเจฃ เจเจธ เจตเจฟเฉฑเจ เจธเจผเจพเจฎเจฒ เจนเฉเจฃ เจฆเฉ เจเฉเจธเจผเจฟเจธเจผ เจเจฐเฉเจ:
$ ./write-sleep &
[1] 15329
write me
$ strace -p 15329
strace: Process 15329 attached
pause(
^Cstrace: Process 15329 detached
<detached ...>
เจชเฉเจฐเฉเจเจฐเจพเจฎ เจเจพเจฒ เจฆเฉเจเจฐเจพ เจฌเจฒเฉเจ เจเฉเจคเจพ เจเจฟเจ pause
. เจเจ เจฆเฉเจเฉเจ เจเจฟ เจเจน เจธเจฟเจเจจเจฒเจพเจ 'เจคเฉ เจเจฟเจตเฉเจ เจชเฉเจฐเจคเฉเจเจฟเจฐเจฟเจ เจเจฐเจฆเฉ เจนเฉ:
$ strace -o write-sleep.log -p 15329 &
strace: Process 15329 attached
$
$ kill -CONT 15329
$ cat write-sleep.log
pause() = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=14989, si_uid=1001} ---
pause(
$
$ kill -TERM 15329
$ cat write-sleep.log
pause() = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=14989, si_uid=1001} ---
pause() = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=14989, si_uid=1001} ---
+++ killed by SIGTERM +++
เจ
เจธเฉเจ เจซเฉเจฐเฉเจเจผ เจเฉเจคเฉ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจจเฉเฉฐ เจฒเจพเจเจ เจเฉเจคเจพ เจ
เจคเฉ เจเจธเจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจเฉ เจธเจผเจพเจฎเจฒ เจนเฉเจ strace
. เจฆเฉ เจเฉฑเจฒเจพเจ เจธเจชเฉฑเจธเจผเจ เจนเฉ เจเจเจเจ: เจตเจฟเจฐเจพเจฎ เจธเจฟเจธเจเจฎ เจเจพเจฒ เจนเฉเจเจกเจฒเจฐ เจคเฉเจ เจฌเจฟเจจเจพเจ เจธเจฟเจเจจเจฒเจพเจ เจจเฉเฉฐ เจจเจเจผเจฐเจ
เฉฐเจฆเจพเจเจผ เจเจฐเจฆเฉ เจนเฉ เจ
เจคเฉ, เจตเจงเฉเจฐเฉ เจฆเจฟเจฒเจเจธเจช เจเฉฑเจฒ เจเจน เจนเฉ เจเจฟ, เจธเจเฉเจฐเฉเจธ เจฎเจพเจจเฉเจเจฐ เจจเจพ เจธเจฟเจฐเจซ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ, เจฌเจฒเจเจฟ เจเจเจฃ เจตเจพเจฒเฉ เจธเจฟเจเจจเจฒเจพเจ เจจเฉเฉฐ เจตเฉเฅค
เจเจฆเจพเจนเจฐเจจ: เจฌเจพเจฒ เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจจเฉเฉฐ เจเจฐเฉเจ เจเจฐเจจเจพ
เจเฉฑเจ เจเจพเจฒ เจฆเฉเจเจฐเจพ เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจจเจพเจฒ เจเฉฐเจฎ เจเจฐเจจเจพ fork
- เจธเจพเจฐเฉ เจฏเฉเจจเจฟเจเจธ เจฆเจพ เจเจงเจพเจฐ. เจเจ เจตเฉเจเฉเจ เจเจฟ เจธเจเฉเจฐเฉเจธ เจเฉฑเจ เจธเจงเจพเจฐเจจ "เจฌเฉเจฐเฉเจกเจฟเฉฐเจ" เจฆเฉ เจเจฆเจพเจนเจฐเจฃ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจฆเฉ เจนเฉเจ เจเฉฑเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฆเฉ เจฐเฉเฉฑเจ เจจเจพเจฒ เจเจฟเจตเฉเจ เจเฉฐเจฎ เจเจฐเจฆเจพ เจนเฉ
int main(int argc, char *argv[])
{
pid_t parent_pid = getpid();
pid_t child_pid = fork();
if (child_pid == 0) {
/* A child is born! */
child_pid = getpid();
/* In the end of the day printf is just a call to write(2). */
printf("child (self=%d)n", child_pid);
exit(EXIT_SUCCESS);
}
printf("parent (self=%d, child=%d)n", parent_pid, child_pid);
wait(NULL);
exit(EXIT_SUCCESS);
}
เจเฉฑเจฅเฉ เจฎเฉเจฒ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจเฉฑเจ เจเจพเจเจฒเจก เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฌเจฃเจพเจเจเจฆเฉ เจนเฉ, เจฆเฉเจตเฉเจ เจธเจเฉเจเจกเจฐเจก เจเจเจเจชเฉเฉฑเจ เจจเฉเฉฐ เจฒเจฟเจเจฆเฉ เจนเจจ:
$ gcc examples/fork-write.c -o fork-write
$ ./fork-write
parent (self=11274, child=11275)
child (self=11275)
เจกเจฟเจซเฉเจฒเจ เจฐเฉเจช เจตเจฟเฉฑเจ, เจ เจธเฉเจ เจธเจฟเจฐเจซ เจชเฉเจฐเฉเจเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจคเฉเจ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจฆเฉเจเจพเจเจเฉ:
$ strace -e trace=write -ofork-write.log ./fork-write
child (self=22049)
parent (self=22048, child=22049)
$ cat fork-write.log
write(1, "parent (self=22048, child=22049)"..., 33) = 33
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=22049, si_uid=1001, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++
เจซเจฒเฉเจ เจธเจพเจฐเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฆเฉ เจฐเฉเฉฑเจ เจจเฉเฉฐ เจเจฐเฉเจ เจเจฐเจจ เจตเจฟเฉฑเจ เจคเฉเจนเจพเจกเฉ เจฎเจฆเจฆ เจเจฐเจฆเจพ เจนเฉ -f
, เจเฉ strace
เจเจพเจเจฒเจก เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจตเจฟเฉฑเจ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจฆเฉ เจจเจฟเจเจฐเจพเจจเฉ เจเจฐเจฆเจพ เจนเฉเฅค เจเจน เจเจเจเจชเฉเฉฑเจ เจฆเฉ เจนเจฐเฉเจ เจฒเจพเจเจจ เจจเฉเฉฐ เจเฉเฉเจฆเจพ เจนเฉ pid
เจชเฉเจฐเจเจฟเจฐเจฟเจ เจเฉ เจธเจฟเจธเจเจฎ เจเจเจเจชเฉเฉฑเจ เจฌเจฃเจพเจเจเจฆเฉ เจนเฉ:
$ strace -f -e trace=write -ofork-write.log ./fork-write
parent (self=22710, child=22711)
child (self=22711)
$ cat fork-write.log
22710 write(1, "parent (self=22710, child=22711)"..., 33) = 33
22711 write(1, "child (self=22711)n", 19) = 19
22711 +++ exited with 0 +++
22710 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=22711, si_uid=1001, si_status=0, si_utime=0, si_stime=0} ---
22710 +++ exited with 0 +++
เจเจธ เจธเฉฐเจฆเจฐเจญ เจตเจฟเฉฑเจ, เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจฆเฉ เจธเจฎเฉเจน เจฆเฉเจเจฐเจพ เจซเจฟเจฒเจเจฐ เจเจฐเจจเจพ เจฒเจพเจญเจฆเจพเจเจ เจนเฉ เจธเจเจฆเจพ เจนเฉ:
$ strace -f -e trace=%process -ofork-write.log ./fork-write
parent (self=23610, child=23611)
child (self=23611)
$ cat fork-write.log
23610 execve("./fork-write", ["./fork-write"], 0x7fff696ff720 /* 63 vars */) = 0
23610 arch_prctl(ARCH_SET_FS, 0x7f3d03ba44c0) = 0
23610 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f3d03ba4790) = 23611
23610 wait4(-1, <unfinished ...>
23611 exit_group(0) = ?
23611 +++ exited with 0 +++
23610 <... wait4 resumed> NULL, 0, NULL) = 23611
23610 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=23611, si_uid=1001, si_status=0, si_utime=0, si_stime=0} ---
23610 exit_group(0) = ?
23610 +++ exited with 0 +++
เจคเจฐเฉเจเฉ เจจเจพเจฒ, เจจเจตเฉเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฌเจฃเจพเจเจฃ เจฒเจ เจเจฟเจนเฉเฉ เจธเจฟเจธเจเจฎ เจเจพเจฒ เจฆเฉ เจตเจฐเจคเฉเจ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจนเฉ?
เจเจฆเจพเจนเจฐเจจ: เจนเฉเจเจกเจฒ เจฆเฉ เจฌเจเจพเจ เจซเจพเจเจฒ เจชเจพเจฅ
เจซเจพเจเจฒ เจกเจฟเจธเจเฉเจฐเจฟเจชเจเจฐเจพเจ เจจเฉเฉฐ เจเจพเจฃเจจเจพ เจจเจฟเจธเจผเจเจค เจคเฉเจฐ 'เจคเฉ เจฒเจพเจญเจฆเจพเจเจ เจนเฉ, เจชเจฐ เจเจพเจธ เจซเจพเจเจฒเจพเจ เจฆเฉ เจจเจพเจฎ เจเจฟเจจเฉเจนเจพเจ เจจเฉเฉฐ เจเฉฑเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจเจเจธเฉเจธ เจเจฐเจฆเจพ เจนเฉ เจเจน เจตเฉ เจเฉฐเจฎ เจตเจฟเฉฑเจ เจ เจธเจเจฆเฉ เจนเจจเฅค
เจ
เจเจฒเจพ
void do_write(int out_fd)
{
char str[] = "write me to a filen";
if (sizeof(str) != write(out_fd, str, sizeof(str))){
perror("write");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
char tmp_filename_template[] = "/tmp/output_fileXXXXXX";
int out_fd = mkstemp(tmp_filename_template);
if (out_fd == -1) {
perror("mkstemp");
exit(EXIT_FAILURE);
}
do_write(out_fd);
return EXIT_SUCCESS;
}
เจเฉฑเจ เจเจฎ เจเจพเจฒ เจฆเฉเจฐเจพเจจ strace
เจธเจฟเจธเจเจฎ เจเจพเจฒ เจจเฉเฉฐ เจชเจพเจธ เจเฉเจคเฉ เจกเจฟเจธเจเฉเจฐเจฟเจชเจเจฐ เจจเฉฐเจฌเจฐ เจฆเจพ เจฎเฉเฉฑเจฒ เจฆเจฟเจเจพเจเจเจพ:
$ strace -e trace=write -o write-tmp-file.log ./write-tmp-file
$ cat write-tmp-file.log
write(3, "write me to a filen", 20) = 20
+++ exited with 0 +++
เจเฉฐเจกเฉ เจจเจพเจฒ -y
เจเจชเจฏเฉเจเจคเจพ เจซเจพเจเจฒ เจฆเจพ เจฎเจพเจฐเจ เจฆเจฐเจธเจพเจเจเจฆเฉ เจนเฉ เจเจฟเจธ เจจเจพเจฒ เจตเจฐเจฃเจจเจเจฐเจคเจพ เจ
เจจเฉเจธเจพเจฐเฉ เจนเฉ:
$ strace -y -e trace=write -o write-tmp-file.log ./write-tmp-file
$ cat write-tmp-file.log
write(3</tmp/output_fileCf5MyW>, "write me to a filen", 20) = 20
+++ exited with 0 +++
เจเจฆเจพเจนเจฐเจจ: เจซเจพเจเจฒ เจเจเจธเฉเจธ เจเฉเจฐเฉเจเจฟเฉฐเจ
เจเฉฑเจ เจนเฉเจฐ เจเจชเจฏเฉเจเฉ เจตเจฟเจธเจผเฉเจธเจผเจคเจพ: เจเฉฑเจ เจเจพเจธ เจซเจพเจเจฒ เจจเจพเจฒ เจธเฉฐเจฌเฉฐเจงเจฟเจค เจธเจฟเจฐเจซ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจชเฉเจฐเจฆเจฐเจธเจผเจฟเจค เจเจฐเฉเฅค เจ
เจเจฒเจพ
void do_write(int out_fd)
{
char str[] = "write me to a filen";
if (sizeof(str) != write(out_fd, str, sizeof(str))){
perror("write");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
/*
* Path will be provided by the first program argument.
* */
const char *path = argv[1];
/*
* Open an existing file for writing in append mode.
* */
int out_fd = open(path, O_APPEND | O_WRONLY);
if (out_fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
do_write(out_fd);
return EXIT_SUCCESS;
}
เจฎเฉเจฒ เจฐเฉเจช เจตเจฟเฉฑเจ strace
เจฌเจนเฉเจค เจธเจพเจฐเฉ เจฌเฉเจฒเฉเฉเฉ เจเจพเจฃเจเจพเจฐเฉ เจฆเจฟเจเจพเจเจเจฆเจพ เจนเฉเฅค เจเฉฐเจกเจพ -P
เจเฉฑเจ เจเจฐเจเฉเจฎเฉเจเจ เจฆเฉ เจจเจพเจฒ เจธเจเจฐเฉเจธ เจธเจฟเจฐเจซ เจจเจฟเจฐเจงเจพเจฐเจค เจซเจพเจเจฒ เจฒเจ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจชเฉเจฐเจฟเฉฐเจ เจเจฐเจจ เจฆเจพ เจเจพเจฐเจจ เจฌเจฃเจฆเจพ เจนเฉ:
$ strace -y -P/tmp/test_file.log -o write-file.log ./write-file /tmp/test_file.log
$ cat write-file.log
openat(AT_FDCWD, "/tmp/test_file.log", O_WRONLY|O_APPEND) = 3</tmp/test_file.log>
write(3</tmp/test_file.log>, "write me to a filen", 20) = 20
+++ exited with 0 +++
เจเจฆเจพเจนเจฐเจจ: เจฎเจฒเจเฉเจฅเฉเจฐเฉเจกเจก เจชเฉเจฐเฉเจเจฐเจพเจฎ
เจเจชเจฏเฉเจเจคเจพ strace
เจฎเจฒเจเฉ-เจฅเฉเจฐเฉเจกเจก เจจเจพเจฒ เจเฉฐเจฎ เจเจฐเจจ เจตเฉเจฒเฉ เจตเฉ เจฎเจฆเจฆ เจเจฐ เจธเจเจฆเจพ เจนเฉ
void *thread(void *arg)
{
(void) arg;
printf("Secondary thread: workingn");
sleep(1);
printf("Secondary thread: donen");
return NULL;
}
int main(int argc, char *argv[])
{
printf("Initial thread: launching a threadn");
pthread_t thr;
if (0 != pthread_create(&thr, NULL, thread, NULL)) {
fprintf(stderr, "Initial thread: failed to create a thread");
exit(EXIT_FAILURE);
}
printf("Initial thread: joining a threadn");
if (0 != pthread_join(thr, NULL)) {
fprintf(stderr, "Initial thread: failed to join a thread");
exit(EXIT_FAILURE);
};
printf("Initial thread: done");
exit(EXIT_SUCCESS);
}
เจเฉเจฆเจฐเจคเฉ เจคเฉเจฐ 'เจคเฉ, เจเจธ เจจเฉเฉฐ เจฒเจฟเฉฐเจเจฐ เจฒเจ เจเฉฑเจ เจตเจฟเจธเจผเฉเจธเจผ เจจเจฎเจธเจเจพเจฐ เจฆเฉ เจจเจพเจฒ เจเฉฐเจชเจพเจเจฒ เจเฉเจคเจพ เจเจพเจฃเจพ เจเจพเจนเฉเจฆเจพ เจนเฉ - the -pthread เจซเจฒเฉเจ:
$ gcc examples/thread-write.c -pthread -o thread-write
$ ./thread-write
/thread-write
Initial thread: launching a thread
Initial thread: joining a thread
Secondary thread: working
Secondary thread: done
Initial thread: done
$
เจซเจฒเฉเจ -f
, เจเจฟเจตเฉเจ เจเจฟ เจจเจฟเจฏเจฎเจค เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจฆเฉ เจฎเจพเจฎเจฒเฉ เจตเจฟเฉฑเจ, เจนเจฐเฉเจ เจฒเจพเจเจจ เจฆเฉ เจธเจผเฉเจฐเฉเจเจค เจตเจฟเฉฑเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฆเฉ pid เจจเฉเฉฐ เจเฉเฉ เจฆเฉเจตเฉเจเจพเฅค
เจเฉเจฆเจฐเจคเฉ เจคเฉเจฐ 'เจคเฉ, เจ เจธเฉเจ เจชเฉเจธเจฟเจเจธ เจฅเฉเจฐเฉเจกเจธ เจธเจเฉเจเจกเจฐเจก เจจเฉเฉฐ เจฒเจพเจเฉ เจเจฐเจจ เจฆเฉ เจ เจฐเจฅเจพเจ เจตเจฟเฉฑเจ เจเฉฑเจ เจฅเฉเจฐเฉเจก เจชเจเจพเจฃเจเจฐเจคเจพ เจฌเจพเจฐเฉ เจเฉฑเจฒ เจจเจนเฉเจ เจเจฐ เจฐเจนเฉ เจนเจพเจ, เจชเจฐ เจฒเฉเจจเจเจธ เจตเจฟเฉฑเจ เจเจพเจธเจ เจธเจผเจกเจฟเจเจฒเจฐ เจฆเฉเจเจฐเจพ เจตเจฐเจคเฉ เจเจ เจธเฉฐเจเจฟเจ เจฌเจพเจฐเฉ เจเฉฑเจฒ เจเจฐ เจฐเจนเฉ เจนเจพเจเฅค เจฌเจพเจ เจฆ เจฆเฉ เจฆเฉเจฐเจฟเจธเจผเจเฉเจเฉเจฃ เจคเฉเจ, เจเฉฑเจฅเฉ เจเฉเจ เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจเจพเจ เจฅเจฐเจฟเฉฑเจก เจจเจนเฉเจ เจนเจจ - เจ เจเจฟเจนเฉ เจเจพเจฐเจ เจนเจจ เจเจฟเจจเฉเจนเจพเจ เจจเฉเฉฐ เจฎเจธเจผเฉเจจ เจฆเฉ เจเจชเจฒเจฌเจง เจเฉเจฐเจพเจ เจตเจฟเฉฑเจ เจตเฉฐเจกเจฃ เจฆเฉ เจเจผเจฐเฉเจฐเจค เจนเฉ.
เจฎเจฒเจเฉเจชเจฒ เจฅเจฐเจฟเฉฑเจกเจพเจ เจตเจฟเฉฑเจ เจเฉฐเจฎ เจเจฐเจฆเฉ เจธเจฎเฉเจ, เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจฌเจนเฉเจค เจเจผเจฟเจเจฆเจพ เจนเฉ เจเจพเจเจฆเฉเจเจ เจนเจจ:
$ strace -f -othread-write.log ./thread-write
$ wc -l thread-write.log
60 thread-write.log
เจเจชเจฃเฉ เจเจช เจจเฉเฉฐ เจชเฉเจฐเฉเจธเฉเจธ เจฎเฉเจจเฉเจเจฎเฉเจเจ เจ
เจคเฉ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจคเฉฑเจ เจนเฉ เจธเฉเจฎเจค เจเจฐเจจเจพ เจธเจฎเจเจฆเจพเจฐ เจนเฉ write
:
$ strace -f -e trace="%process,write" -othread-write.log ./thread-write
$ cat thread-write.log
18211 execve("./thread-write", ["./thread-write"], 0x7ffc6b8d58f0 /* 64 vars */) = 0
18211 arch_prctl(ARCH_SET_FS, 0x7f38ea3b7740) = 0
18211 write(1, "Initial thread: launching a thre"..., 35) = 35
18211 clone(child_stack=0x7f38e9ba2fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f38e9ba39d0, tls=0x7f38e9ba3700, child_tidptr=0x7f38e9ba39d0) = 18212
18211 write(1, "Initial thread: joining a thread"..., 33) = 33
18212 write(1, "Secondary thread: workingn", 26) = 26
18212 write(1, "Secondary thread: donen", 23) = 23
18212 exit(0) = ?
18212 +++ exited with 0 +++
18211 write(1, "Initial thread: done", 20) = 20
18211 exit_group(0) = ?
18211 +++ exited with 0 +++
เจคเจฐเฉเจเฉ เจจเจพเจฒ, เจธเจตเจพเจฒ. เจจเจตเจพเจ เจฅเจฐเจฟเฉฑเจก เจฌเจฃเจพเจเจฃ เจฒเจ เจเจฟเจนเฉเฉ เจธเจฟเจธเจเจฎ เจเจพเจฒ เจฆเฉ เจตเจฐเจคเฉเจ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจนเฉ? เจฅเฉเจฐเฉเจกเจธ เจฒเจ เจเจน เจเจพเจฒ เจชเฉเจฐเจเจฟเจฐเจฟเจเจตเจพเจ เจฒเจ เจเจพเจฒ เจคเฉเจ เจเจฟเจตเฉเจ เจตเฉฑเจเจฐเฉ เจนเฉ?
เจฎเจพเจธเจเจฐ เจเจฒเจพเจธ: เจธเจฟเจธเจเจฎ เจเจพเจฒ เจฆเฉ เจธเจฎเฉเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจธเจเฉเจ
เจนเจพเจฒ เจนเฉ เจตเจฟเฉฑเจ เจชเฉเจฐเจเจ เจนเฉเจ เจตเจฟเฉฑเจเฉเจ เจเฉฑเจ strace
เจธเจฎเจฐเฉฑเจฅเจพเจตเจพเจ - เจธเจฟเจธเจเจฎ เจเจพเจฒ เจฆเฉ เจธเจฎเฉเจ เจซเฉฐเจเจธเจผเจจ เจเจพเจฒเจพเจ เจฆเฉ เจธเจเฉเจ เจจเฉเฉฐ เจชเฉเจฐเจฆเจฐเจธเจผเจฟเจค เจเจฐเจจเจพเฅค เจเจธเจพเจจ
void do_write(void)
{
char str[] = "write me to stdoutn";
if (sizeof(str) != write(STDOUT_FILENO, str, sizeof(str))){
perror("write");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
do_write();
return EXIT_SUCCESS;
}
เจเฉเจฆเจฐเจคเฉ เจคเฉเจฐ 'เจคเฉ, เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฆเฉ เจเจเจเจชเฉเฉฑเจ เจฌเจนเฉเจค เจตเฉฑเจกเฉ เจนเฉ เจเจพเจเจฆเฉ เจนเฉ, เจ
เจคเฉ, เจซเจฒเฉเจ เจคเฉเจ เจเจฒเจพเจตเจพ -k
(เจเจพเจฒ เจธเจเฉเจ เจกเจฟเจธเจชเจฒเฉเจ
), เจเจน เจจเจพเจฎ เจฆเฉเจเจฐเจพ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจซเจฟเจฒเจเจฐ เจเจฐเจจ เจฆเจพ เจ
เจฐเจฅ เจฐเฉฑเจเจฆเจพ เจนเฉ:
$ gcc examples/write-simple.c -o write-simple
$ strace -k -e trace=write -o write-simple.log ./write-simple
write me to stdout
$ cat write-simple.log
write(1, "write me to stdoutn", 20) = 20
> /lib/x86_64-linux-gnu/libc-2.27.so(__write+0x14) [0x110154]
> /home/vkazanov/projects-my/strace-post/write-simple(do_write+0x50) [0x78a]
> /home/vkazanov/projects-my/strace-post/write-simple(main+0x14) [0x7d1]
> /lib/x86_64-linux-gnu/libc-2.27.so(__libc_start_main+0xe7) [0x21b97]
> /home/vkazanov/projects-my/strace-post/write-simple(_start+0x2a) [0x65a]
+++ exited with 0 +++
เจฎเจพเจธเจเจฐ เจเจฒเจพเจธ: เจเจฒเจคเฉ เจเฉเจเจพ
เจ
เจคเฉ เจเฉฑเจ เจนเฉเจฐ เจจเจตเฉเจ เจ
เจคเฉ เจฌเจนเฉเจค เจเจชเจฏเฉเจเฉ เจตเจฟเจธเจผเฉเจธเจผเจคเจพ: เจเจฒเจคเฉ เจเฉเจเจพ. เจเจฅเฉ
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void do_write(const char *str, ssize_t len)
{
if (len != write(STDOUT_FILENO, str, (size_t)len)){
perror("write");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
(void) argc; (void) argv;
char str1[] = "write me 1n";
do_write(str1, sizeof(str1));
char str2[] = "write me 2n";
do_write(str2, sizeof(str2));
return EXIT_SUCCESS;
}
เจเจ เจฆเฉเจจเฉเจ เจฒเจฟเจเจคเฉ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจเจฐเฉเจธ เจเจฐเฉเจ:
$ gcc examples/write-twice.c -o write-twice
$ ./write-twice
write me 1
write me 2
$ strace -e trace=write -owrite-twice.log ./write-twice
write me 1
write me 2
$ cat write-twice.log
write(1, "write me 1n", 12) = 12
write(1, "write me 2n", 12) = 12
+++ exited with 0 +++
เจนเฉเจฃ เจ
เจธเฉเจ เจธเจฎเฉเจเจฐเจจ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจฆเฉ เจนเจพเจ inject
เจเฉฑเจ เจเจฒเจคเฉ เจชเจพเจเจฃ เจฒเจ EBADF
เจธเจพเจฐเฉเจเจ เจฒเจฟเจเจคเฉ เจเจพเจฒเจพเจ เจตเจฟเฉฑเจ:
$ strace -e trace=write -e inject=write:error=EBADF -owrite-twice.log ./write-twice
$ cat write-twice.log
write(1, "write me 1n", 12) = -1 EBADF (Bad file descriptor) (INJECTED)
write(3, "write: Bad file descriptorn", 27) = -1 EBADF (Bad file descriptor) (INJECTED)
+++ exited with 1 +++
เจเจน เจฆเจฟเจฒเจเจธเจช เจนเฉ เจเจฟ เจเจฟเจนเฉเฉเจเจ เจเจฒเจคเฉเจเจ เจตเจพเจชเจธ เจเฉเจคเฉเจเจ เจเจพเจเจฆเฉเจเจ เจนเจจ เจธเจพเจฐเฉ เจเฉเจฃเฉเจคเฉเจเจ write
, เจชเฉเจฐ เจฆเฉ เจชเจฟเฉฑเจเฉ เจเฉเจชเฉ เจนเฉเจ เจเจพเจฒ เจธเจฎเฉเจคเฅค เจเจน เจธเจฟเจฐเจซ เจชเจนเจฟเจฒเฉ เจเจพเจฒ เจฒเจ เจเฉฑเจ เจเจฒเจคเฉ เจตเจพเจชเจธ เจเจฐเจจ เจฒเจ เจธเจฎเจเจฆเจพ เจนเฉ:
$ strace -e trace=write -e inject=write:error=EBADF:when=1 -owrite-twice.log ./write-twice
write: Bad file descriptor
$ cat write-twice.log
write(1, "write me 1n", 12) = -1 EBADF (Bad file descriptor) (INJECTED)
write(3, "write: Bad file descriptorn", 27) = 27
+++ exited with 1 +++
เจเจพเจ เจฆเฉเจเจพ:
$ strace -e trace=write -e inject=write:error=EBADF:when=2 -owrite-twice.log ./write-twice
write me 1
write: Bad file descriptor
$ cat write-twice.log
write(1, "write me 1n", 12) = 12
write(1, "write me 2n", 12) = -1 EBADF (Bad file descriptor) (INJECTED)
write(3, "write: Bad file descriptorn", 27) = 27
+++ exited with 1 +++
เจเจฒเจคเฉ เจฆเฉ เจเจฟเจธเจฎ เจจเจฟเจฐเจงเจพเจฐเจค เจเจฐเจจเจพ เจเจผเจฐเฉเจฐเฉ เจจเจนเฉเจ เจนเฉ:
$ strace -e trace=write -e fault=write:when=1 -owrite-twice.log ./write-twice
$ cat write-twice.log
write(1, "write me 1n", 12) = -1 ENOSYS (Function not implemented) (INJECTED)
write(3, "write: Function not implementedn", 32) = 32
+++ exited with 1 +++
เจนเฉเจฐ เจซเจฒเฉเจเจพเจ เจฆเฉ เจจเจพเจฒ, เจคเฉเจธเฉเจ เจเฉฑเจ เจเจพเจธ เจซเจพเจเจฒ เจคเฉฑเจ เจชเจนเฉเฉฐเจ เจจเฉเฉฐ "เจฌเฉเจฐเฉเจ" เจเจฐ เจธเจเจฆเฉ เจนเฉเฅค เจเจฆเจพเจนเจฐเจจ:
$ strace -y -P/tmp/test_file.log -e inject=file:error=ENOENT -o write-file.log ./write-file /tmp/test_file.log
open: No such file or directory
$ cat write-file.log
openat(AT_FDCWD, "/tmp/test_file.log", O_WRONLY|O_APPEND) = -1 ENOENT (No such file or directory) (INJECTED)
+++ exited with 1 +++
เจเจฒเจคเฉ เจเฉฐเจเฉเจเจธเจผเจจ เจคเฉเจ เจเจฒเจพเจตเจพ,
เจฌเจพเจ เจฆ
เจเจชเจฏเฉเจเจคเจพ strace
- เจเฉฑเจ เจธเจงเจพเจฐเจจ เจ
เจคเฉ เจญเจฐเฉเจธเฉเจฎเฉฐเจฆ เจธเจพเจงเจจ. เจชเจฐ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจคเฉเจ เจเจฒเจพเจตเจพ, เจชเฉเจฐเฉเจเจฐเจพเจฎเจพเจ เจ
เจคเฉ เจเจชเจฐเฉเจเจฟเฉฐเจ เจธเจฟเจธเจเจฎ เจฆเฉ เจธเฉฐเจเจพเจฒเจจ เจฆเฉ เจนเฉเจฐ เจชเจนเจฟเจฒเฉเจเจ เจจเฉเฉฐ เจกเฉเจฌเฉฑเจ เจเฉเจคเจพ เจเจพ เจธเจเจฆเจพ เจนเฉเฅค เจเจฆเจพเจนเจฐเจจ เจฒเจ, เจเจน เจเจคเฉเจธเจผเฉเจฒ เจคเฉเจฐ 'เจคเฉ เจฒเจฟเฉฐเจเจก เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉเจเจ เจฒเจ เจเจพเจฒเจพเจ เจจเฉเฉฐ เจเจฐเฉเจ เจเจฐ เจธเจเจฆเจพ เจนเฉเฅค strace
- เจฎเฉเจฐเฉ เจเจชเจฃเฉ เจ
เจคเฉ เจนเฉเจฐ เจฒเฉเจเจพเจ เจฆเฉ เจชเฉเจฐเฉเจเจฐเจพเจฎเจพเจ เจจเจพเจฒ เจธเจฎเฉฑเจธเจฟเจเจตเจพเจ เจฆเฉ เจฎเจพเจฎเจฒเฉ เจตเจฟเฉฑเจ เจฌเจเจพเจ
เจฆเฉ เจชเจนเจฟเจฒเฉ เจฒเจพเจเจจ, เจ
เจคเฉ เจฎเฉเจ เจเจธเจจเฉเฉฐ เจนเจซเจผเจคเฉ เจตเจฟเฉฑเจ เจเฉฑเจเฉ เจเฉฑเจ เจฆเฉ เจตเจพเจฐ เจตเจฐเจคเจฆเจพ เจนเจพเจ.
เจธเฉฐเจเฉเจช เจตเจฟเฉฑเจ, เจเฉ เจคเฉเจธเฉเจ เจฏเฉเจจเจฟเจเจธ เจจเฉเฉฐ เจชเจฟเจเจฐ เจเจฐเจฆเฉ เจนเฉ, เจชเฉเฉเจนเฉ man 1 strace
เจ
เจคเฉ เจเจชเจฃเฉ เจชเฉเจฐเฉเจเจฐเจพเจฎเจพเจ 'เจคเฉ เจเจพเจค เจฎเจพเจฐเจจ เจฒเจ เจธเฉเจคเฉฐเจคเจฐ เจฎเจนเจฟเจธเฉเจธ เจเจฐเฉ!
เจธเจฐเฉเจค: www.habr.com