Strace Linux-แƒจแƒ˜: แƒ˜แƒกแƒขแƒแƒ แƒ˜แƒ, แƒ“แƒ˜แƒ–แƒแƒ˜แƒœแƒ˜ แƒ“แƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ

Strace Linux-แƒจแƒ˜: แƒ˜แƒกแƒขแƒแƒ แƒ˜แƒ, แƒ“แƒ˜แƒ–แƒแƒ˜แƒœแƒ˜ แƒ“แƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ

Unix-แƒ˜แƒก แƒ›แƒกแƒ’แƒแƒ•แƒก แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒฃแƒš แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ”แƒ‘แƒจแƒ˜ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒก แƒ™แƒแƒ›แƒฃแƒœแƒ˜แƒ™แƒแƒชแƒ˜แƒ แƒ’แƒแƒ แƒ” แƒกแƒแƒ›แƒงแƒแƒ แƒแƒกแƒ—แƒแƒœ แƒ“แƒ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒฃแƒš แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒแƒกแƒ—แƒแƒœ แƒฎแƒ“แƒ”แƒ‘แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ›แƒชแƒ˜แƒ แƒ” แƒœแƒแƒ™แƒ แƒ”แƒ‘แƒ˜แƒก - แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ”แƒจแƒ•แƒ”แƒแƒ‘แƒ˜แƒ—. แƒ”แƒก แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก, แƒ แƒแƒ› แƒ’แƒแƒ›แƒแƒ แƒ—แƒ•แƒ˜แƒก แƒ›แƒ˜แƒ–แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒ˜แƒงแƒแƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒ—แƒ•แƒแƒšแƒ—แƒ•แƒแƒšแƒ˜.

แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ แƒ“แƒแƒ’แƒ”แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒแƒ— แƒแƒ™แƒแƒœแƒขแƒ แƒแƒšแƒแƒ— แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ”แƒ‘แƒ˜แƒก โ€žแƒ˜แƒœแƒขแƒ˜แƒ›แƒฃแƒ แƒ˜ แƒชแƒฎแƒแƒ•แƒ แƒ”แƒ‘แƒโ€œ Linux-แƒ–แƒ” strace, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒ—แƒ”แƒ›แƒแƒ. แƒฏแƒแƒจแƒฃแƒจแƒฃแƒ แƒ˜ แƒแƒฆแƒญแƒฃแƒ แƒ•แƒ˜แƒšแƒแƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ”แƒ‘แƒก แƒแƒฎแƒšแƒแƒ•แƒก แƒ›แƒแƒ™แƒšแƒ” แƒ˜แƒกแƒขแƒแƒ แƒ˜แƒ strace แƒ“แƒ แƒแƒกแƒ”แƒ—แƒ˜ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ”แƒ‘แƒ˜แƒก แƒ“แƒ˜แƒ–แƒแƒ˜แƒœแƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒ.

แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ˜แƒก

แƒกแƒแƒฎแƒ”แƒแƒ‘แƒ”แƒ‘แƒ˜แƒก แƒฌแƒแƒ แƒ›แƒแƒจแƒแƒ‘แƒ

Unix-แƒจแƒ˜ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ”แƒ‘แƒกแƒ แƒ“แƒ OS แƒ‘แƒ˜แƒ แƒ—แƒ•แƒก แƒจแƒแƒ แƒ˜แƒก แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜ แƒแƒ แƒ˜แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜. แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜, syscals), แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ”แƒ‘แƒ˜แƒก แƒฃแƒ แƒ—แƒ˜แƒ”แƒ แƒ—แƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ แƒ’แƒแƒ แƒ” แƒกแƒแƒ›แƒงแƒแƒ แƒแƒกแƒ—แƒแƒœ แƒฎแƒ“แƒ”แƒ‘แƒ แƒ”แƒฅแƒกแƒ™แƒšแƒฃแƒ–แƒ˜แƒฃแƒ แƒแƒ“ แƒ›แƒแƒ—แƒ˜ แƒ›แƒ”แƒจแƒ•แƒ”แƒแƒ‘แƒ˜แƒ—.

แƒ›แƒแƒ’แƒ แƒแƒ› Unix-แƒ˜แƒก แƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒกแƒแƒฏแƒแƒ แƒ แƒ•แƒ”แƒ แƒกแƒ˜แƒแƒจแƒ˜ (Unix แƒ•แƒ”แƒ แƒกแƒ˜แƒ 6, 1975) แƒแƒ  แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒ“แƒ แƒ›แƒแƒกแƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ’แƒ–แƒ”แƒ‘แƒ˜ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒ”แƒ‘แƒ˜แƒก แƒฅแƒชแƒ”แƒ•แƒ˜แƒก แƒ—แƒ•แƒแƒšแƒงแƒฃแƒ แƒ˜แƒก แƒ“แƒ”แƒ•แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒแƒ› แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ˜แƒก แƒ’แƒแƒ“แƒแƒกแƒแƒญแƒ แƒ”แƒšแƒแƒ“ Bell Labs แƒ’แƒแƒœแƒแƒฎแƒšแƒ“แƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ•แƒ”แƒ แƒกแƒ˜แƒแƒ–แƒ” (Unix แƒ•แƒ”แƒ แƒกแƒ˜แƒ 7, 1979) แƒจแƒ”แƒกแƒ—แƒแƒ•แƒแƒ–แƒ แƒแƒฎแƒแƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ›แƒแƒฌแƒแƒ“แƒ”แƒ‘แƒ - ptrace.

ptrace แƒจแƒ”แƒ˜แƒฅแƒ›แƒœแƒ แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒแƒ“ แƒ˜แƒœแƒขแƒ”แƒ แƒแƒฅแƒขแƒ˜แƒฃแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒ แƒ—แƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒแƒ’แƒ แƒแƒ› 80-แƒ˜แƒแƒœแƒ˜ แƒฌแƒšแƒ”แƒ‘แƒ˜แƒก แƒ‘แƒแƒšแƒแƒก (แƒ™แƒแƒ›แƒ”แƒ แƒชแƒ˜แƒฃแƒšแƒ˜ แƒ”แƒžแƒแƒฅแƒแƒจแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก V แƒ’แƒแƒ›แƒแƒจแƒ•แƒ”แƒ‘แƒ 4) แƒแƒ›แƒ˜แƒก แƒกแƒแƒคแƒฃแƒซแƒ•แƒ”แƒšแƒ–แƒ” แƒ’แƒแƒ›แƒแƒฉแƒœแƒ“แƒœแƒ”แƒœ แƒ“แƒ แƒคแƒแƒ แƒ—แƒแƒ“ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒก แƒ•แƒ˜แƒฌแƒ แƒ แƒคแƒแƒ™แƒฃแƒกแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒ แƒ—แƒ•แƒ”แƒ‘แƒ˜ - แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ–แƒแƒ แƒ˜แƒก แƒขแƒ แƒแƒกแƒ”แƒ แƒ˜.

แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ strace-แƒ˜แƒก แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒ’แƒแƒ›แƒแƒฅแƒ•แƒ”แƒงแƒœแƒ“แƒ แƒžแƒแƒš แƒ™แƒ แƒแƒœแƒ”แƒœแƒ‘แƒฃแƒ แƒ’แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  comp.sources.sun แƒกแƒแƒคแƒแƒกแƒขแƒ แƒกแƒ˜แƒแƒจแƒ˜ 1992 แƒฌแƒ”แƒšแƒก, แƒ แƒแƒ’แƒแƒ แƒช แƒ“แƒแƒฎแƒฃแƒ แƒฃแƒšแƒ˜ แƒ™แƒแƒ›แƒฃแƒœแƒแƒšแƒฃแƒ แƒ˜ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒก แƒแƒšแƒขแƒ”แƒ แƒœแƒแƒขแƒ˜แƒ•แƒ. trace แƒ›แƒ–แƒ˜แƒกแƒ’แƒแƒœ. แƒแƒ แƒ˜แƒ•แƒ” แƒ™แƒšแƒแƒœแƒ˜ แƒ“แƒ แƒแƒ แƒ˜แƒ’แƒ˜แƒœแƒแƒšแƒ˜ แƒ’แƒแƒœแƒ™แƒฃแƒ—แƒ•แƒœแƒ˜แƒšแƒ˜ แƒ˜แƒงแƒ SunOS-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒแƒ’แƒ แƒแƒ› 1994 แƒฌแƒšแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก strace แƒžแƒแƒ แƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ˜แƒงแƒ System V-แƒ–แƒ”, Solaris-แƒ–แƒ” แƒ“แƒ แƒกแƒฃแƒš แƒฃแƒคแƒ แƒ แƒžแƒแƒžแƒฃแƒšแƒแƒ แƒฃแƒš Linux-แƒ–แƒ”.

แƒ“แƒฆแƒ”แƒก strace แƒ›แƒฎแƒแƒ แƒก แƒฃแƒญแƒ”แƒ แƒก แƒ›แƒฎแƒแƒšแƒแƒ“ Linux-แƒก แƒ“แƒ แƒ”แƒงแƒ แƒ“แƒœแƒแƒ‘แƒ แƒ›แƒแƒก ptrace, แƒ’แƒแƒ“แƒแƒ–แƒ แƒ“แƒ˜แƒšแƒ˜ แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ แƒ’แƒแƒคแƒแƒ แƒ—แƒแƒ”แƒ‘แƒ˜แƒ—.

แƒ—แƒแƒœแƒแƒ›แƒ”แƒ“แƒ แƒแƒ•แƒ” (แƒ“แƒ แƒซแƒแƒšแƒ˜แƒแƒœ แƒแƒฅแƒขแƒ˜แƒฃแƒ แƒ˜) แƒจแƒ”แƒ›แƒœแƒแƒฎแƒ•แƒ”แƒšแƒ˜ strace - แƒ“แƒ˜แƒ›แƒ˜แƒขแƒ แƒ˜ แƒšแƒ”แƒ•แƒ˜แƒœแƒ˜. แƒ›แƒ˜แƒกแƒ˜ แƒฌแƒงแƒแƒšแƒแƒ‘แƒ˜แƒ—, แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒแƒ› แƒจแƒ”แƒ˜แƒซแƒ˜แƒœแƒ แƒ›แƒแƒฌแƒ˜แƒœแƒแƒ•แƒ” แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜, แƒ แƒแƒ’แƒแƒ แƒ˜แƒชแƒแƒ แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ˜แƒก แƒ˜แƒœแƒ”แƒฅแƒชแƒ˜แƒ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ  แƒ–แƒแƒ แƒ”แƒ‘แƒจแƒ˜, แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ˜แƒก แƒคแƒแƒ แƒ—แƒ แƒกแƒžแƒ”แƒฅแƒขแƒ แƒ˜แƒก แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ แƒ“แƒ, แƒ แƒแƒช แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜แƒ, แƒ—แƒ˜แƒšแƒ˜แƒกแƒ›แƒ. แƒแƒ แƒแƒแƒคแƒ˜แƒชแƒ˜แƒแƒšแƒฃแƒ แƒ˜ แƒฌแƒงแƒแƒ แƒแƒ”แƒ‘แƒ˜ แƒ˜แƒ แƒฌแƒ›แƒฃแƒœแƒ”แƒ‘แƒ˜แƒแƒœ, แƒ แƒแƒ› แƒแƒ แƒฉแƒ”แƒ•แƒแƒœแƒ˜ แƒกแƒ˜แƒ แƒแƒฅแƒšแƒ”แƒ›แƒแƒกแƒ–แƒ” แƒ“แƒแƒ”แƒชแƒ แƒ แƒฃแƒกแƒฃแƒš แƒกแƒ˜แƒขแƒงแƒ•แƒ โ€žแƒกแƒ˜แƒ แƒแƒฅแƒšแƒ”แƒ›แƒแƒกโ€œ แƒ“แƒ แƒ˜แƒœแƒ’แƒšแƒ˜แƒกแƒฃแƒ  แƒกแƒ˜แƒขแƒงแƒ•แƒ โ€žแƒกแƒขแƒ แƒแƒ˜แƒกแƒกโ€œ แƒจแƒแƒ แƒ˜แƒก แƒ—แƒแƒœแƒฎแƒ›แƒแƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ.

แƒแƒกแƒ”แƒ•แƒ” แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ•แƒแƒœแƒ˜แƒ, แƒ แƒแƒ› ptrace แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ˜ แƒ“แƒ แƒขแƒ แƒแƒกแƒ”แƒ แƒ”แƒ‘แƒ˜ แƒแƒ แƒแƒกแƒแƒ“แƒ”แƒก แƒงแƒแƒคแƒ˜แƒšแƒ แƒฉแƒแƒ แƒ—แƒฃแƒšแƒ˜ POSIX-แƒจแƒ˜, แƒ›แƒ˜แƒฃแƒฎแƒ”แƒ“แƒแƒ•แƒแƒ“ แƒฎแƒแƒœแƒ’แƒ แƒซแƒšแƒ˜แƒ•แƒ˜ แƒ˜แƒกแƒขแƒแƒ แƒ˜แƒ˜แƒกแƒ แƒ“แƒ แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ˜แƒกแƒ Linux-แƒจแƒ˜, FreeBSD-แƒจแƒ˜, OpenBSD-แƒกแƒ แƒ“แƒ แƒขแƒ แƒแƒ“แƒ˜แƒชแƒ˜แƒฃแƒš Unix-แƒจแƒ˜.

แƒกแƒขแƒ แƒแƒ˜แƒก แƒ›แƒแƒฌแƒงแƒแƒ‘แƒ˜แƒšแƒแƒ‘แƒ แƒ›แƒแƒ™แƒšแƒ”แƒ“: Piglet Trace

"แƒ—แƒฅแƒ•แƒ”แƒœ แƒแƒ  แƒ’แƒ”แƒกแƒ›แƒ˜แƒ— แƒแƒ›แƒ˜แƒก แƒ’แƒแƒ’แƒ”แƒ‘แƒ" (แƒ“แƒ”แƒœแƒ˜แƒก แƒ แƒ˜แƒฉแƒ˜, แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜ Unix-แƒ˜แƒก 6-แƒ” แƒ•แƒ”แƒ แƒกแƒ˜แƒแƒจแƒ˜)

แƒแƒ“แƒ แƒ”แƒฃแƒšแƒ˜ แƒ‘แƒแƒ•แƒจแƒ•แƒแƒ‘แƒ˜แƒ“แƒแƒœ แƒ•แƒ”แƒ  แƒ•แƒ˜แƒขแƒแƒœ แƒจแƒแƒ• แƒงแƒฃแƒ—แƒ”แƒ‘แƒก: แƒ›แƒ” แƒแƒ  แƒ•แƒ—แƒแƒ›แƒแƒจแƒแƒ‘แƒ“แƒ˜ แƒกแƒแƒ—แƒแƒ›แƒแƒจแƒแƒ”แƒ‘แƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ•แƒชแƒ“แƒ˜แƒšแƒแƒ‘แƒ“แƒ˜ แƒ’แƒแƒ›แƒ”แƒ’แƒ แƒ›แƒแƒ—แƒ˜ แƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒ (แƒ›แƒแƒ–แƒแƒ แƒ“แƒ”แƒ‘แƒ˜ แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ“แƒœแƒ”แƒœ แƒกแƒ˜แƒขแƒงแƒ•แƒแƒก "แƒ’แƒแƒขแƒ”แƒฎแƒ", แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒ  แƒ›แƒฏแƒ”แƒ แƒ แƒ‘แƒแƒ แƒแƒขแƒ˜ แƒ”แƒœแƒ”แƒ‘แƒ˜แƒก). แƒแƒšแƒ‘แƒแƒ— แƒแƒ›แƒ˜แƒขแƒแƒ›แƒแƒ, แƒ แƒแƒ› แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ Unix-แƒ˜แƒก แƒ“แƒ แƒ—แƒแƒœแƒแƒ›แƒ”แƒ“แƒ แƒแƒ•แƒ” แƒฆแƒ˜แƒ แƒฌแƒงแƒแƒ แƒแƒก แƒ›แƒแƒซแƒ แƒแƒแƒ‘แƒ˜แƒก แƒแƒ แƒแƒคแƒแƒ แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒ™แƒฃแƒšแƒขแƒฃแƒ แƒ แƒแƒกแƒ” แƒแƒฎแƒšแƒแƒกแƒแƒ แƒฉแƒ”แƒ›แƒ—แƒแƒœ.

แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒ›แƒ˜แƒ–แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒ˜แƒ–แƒแƒœแƒจแƒ”แƒฌแƒแƒœแƒ˜แƒšแƒ˜ แƒแƒ  แƒแƒ แƒ˜แƒก แƒแƒ—แƒฌแƒšแƒ”แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜ แƒ’แƒแƒ–แƒ แƒ“แƒ˜แƒšแƒ˜ แƒกแƒขแƒ แƒแƒกแƒ˜แƒก แƒฌแƒงแƒแƒ แƒแƒก แƒ™แƒแƒ“แƒ˜แƒก แƒ“แƒแƒจแƒšแƒ. แƒ›แƒแƒ’แƒ แƒแƒ› แƒ›แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ”แƒšแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒกแƒแƒ˜แƒ“แƒฃแƒ›แƒšแƒ แƒแƒ  แƒฃแƒœแƒ“แƒ แƒ“แƒแƒ แƒฉแƒ”แƒก. แƒ›แƒแƒจแƒแƒกแƒแƒ“แƒแƒ›แƒ”, แƒแƒกแƒ”แƒ—แƒ˜ แƒกแƒขแƒ แƒแƒขแƒ”แƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ”แƒ‘แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒก แƒžแƒ แƒ˜แƒœแƒชแƒ˜แƒžแƒ˜แƒก แƒกแƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒšแƒแƒ“, แƒ›แƒ” แƒ›แƒ˜แƒ•แƒชแƒ”แƒ› แƒ™แƒแƒ“แƒก แƒ›แƒ˜แƒœแƒ˜แƒแƒขแƒฃแƒ แƒฃแƒšแƒ˜ แƒขแƒ แƒแƒกแƒ”แƒ แƒ˜แƒก - แƒ’แƒแƒญแƒ˜แƒก แƒ™แƒ•แƒแƒšแƒ˜ (แƒžแƒขแƒ ). แƒ›แƒแƒœ แƒแƒ  แƒ˜แƒชแƒ˜แƒก แƒ แƒแƒ’แƒแƒ  แƒ’แƒแƒแƒ™แƒ”แƒ—แƒแƒก แƒ แƒแƒ˜แƒ›แƒ” แƒ’แƒแƒœแƒกแƒแƒ™แƒฃแƒ—แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜แƒ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜ - แƒ’แƒแƒ›แƒแƒ“แƒ˜แƒก:

$ 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

Piglet Trace แƒแƒ›แƒแƒ˜แƒชแƒœแƒแƒ‘แƒก Linux-แƒ˜แƒก แƒแƒกแƒแƒ‘แƒ˜แƒ— แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ  แƒ–แƒแƒ แƒก (แƒ˜แƒฎ. แƒฉแƒแƒ แƒขแƒจแƒ˜) แƒ“แƒ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒ›แƒฎแƒแƒšแƒแƒ“ x86-64 แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒแƒ–แƒ”. แƒ”แƒก แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜แƒ แƒกแƒแƒ’แƒแƒœแƒ›แƒแƒœแƒแƒ—แƒšแƒ”แƒ‘แƒšแƒ แƒ›แƒ˜แƒ–แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒฎแƒ”แƒ“แƒแƒ— แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ™แƒšแƒแƒœแƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒแƒก. Linux-แƒ˜แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, debugger แƒ“แƒ tracers แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ”แƒœ, แƒ แƒแƒ’แƒแƒ แƒช แƒ–แƒ”แƒ›แƒแƒ— แƒแƒฆแƒ˜แƒœแƒ˜แƒจแƒœแƒ, ptrace แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ–แƒแƒ แƒก. แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒจแƒ˜ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ˜แƒ“แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒ˜แƒ—, แƒ แƒแƒ›แƒ”แƒšแƒ—แƒแƒ’แƒแƒœ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒฉแƒ•แƒ”แƒœ แƒ’แƒ•แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ PTRACE_TRACEME, PTRACE_SYSCALL ะธ PTRACE_GETREGS.

แƒขแƒ แƒแƒกแƒ”แƒ แƒ˜ แƒ˜แƒฌแƒงแƒ”แƒ‘แƒ แƒฉแƒ•แƒ”แƒฃแƒšแƒ”แƒ‘แƒ แƒ˜แƒ•แƒ˜ Unix แƒกแƒขแƒ˜แƒšแƒ˜แƒ—: 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, &registers) == -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, &registers) == -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);
}

แƒ”แƒก แƒแƒ แƒ˜แƒก แƒ›แƒ—แƒ”แƒšแƒ˜ แƒขแƒ แƒแƒกแƒ”แƒ แƒ˜. แƒแƒฎแƒšแƒ แƒ—แƒฅแƒ•แƒ”แƒœ แƒ˜แƒชแƒ˜แƒ—, แƒกแƒแƒ“ แƒฃแƒœแƒ“แƒ แƒ“แƒแƒ˜แƒฌแƒงแƒแƒ— แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒžแƒแƒ แƒขแƒ˜แƒ แƒ”แƒ‘แƒ DTrace Linux-แƒ–แƒ”.

แƒกแƒแƒคแƒฃแƒซแƒ•แƒšแƒ”แƒ‘แƒ˜: แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒก แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ 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 แƒ“แƒ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ›แƒ แƒแƒ•แƒšแƒ”, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒแƒ  แƒ’แƒ•แƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒ”แƒ‘แƒก.

แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ’แƒแƒœแƒแƒกแƒฎแƒ•แƒแƒ•แƒแƒ— แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒก แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒฃแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ แƒœแƒแƒ™แƒแƒ“แƒ˜ แƒ“แƒ 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 +++

แƒ’แƒแƒ˜แƒ—แƒ•แƒแƒšแƒ˜แƒกแƒฌแƒ˜แƒœแƒ”แƒ— แƒ’แƒแƒ›แƒแƒ แƒ˜แƒชแƒฎแƒฃแƒšแƒ˜ แƒซแƒแƒฎแƒ˜แƒšแƒ˜แƒก แƒœแƒ˜แƒจแƒแƒœแƒ˜ แƒ’แƒแƒ›แƒแƒ แƒ˜แƒชแƒฎแƒฃแƒšแƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒแƒจแƒ˜: แƒแƒ›แƒแƒก แƒ›แƒแƒ˜แƒ—แƒฎแƒแƒ•แƒก แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒกแƒ˜. shell).

glibc-แƒ˜แƒก แƒฉแƒ”แƒ›แƒก แƒ•แƒ”แƒ แƒกแƒ˜แƒแƒจแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ˜ แƒฌแƒงแƒ•แƒ”แƒขแƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒก exit_group, แƒแƒ แƒ แƒขแƒ แƒแƒ“แƒ˜แƒชแƒ˜แƒฃแƒšแƒ˜ _exit. แƒ”แƒก แƒแƒ แƒ˜แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ  แƒ–แƒแƒ แƒ”แƒ‘แƒ—แƒแƒœ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒก แƒกแƒ˜แƒ แƒ—แƒฃแƒšแƒ”: แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜, แƒ แƒแƒ›แƒšแƒ˜แƒ—แƒแƒช แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒกแƒขแƒ˜, แƒžแƒ˜แƒ แƒ“แƒแƒžแƒ˜แƒ  แƒแƒ  แƒแƒ แƒ˜แƒก แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ  แƒ–แƒแƒ แƒ”แƒ‘แƒ—แƒแƒœ. แƒฃแƒคแƒ แƒ แƒ›แƒ”แƒขแƒ˜แƒช, แƒ˜แƒก แƒ แƒ”แƒ’แƒฃแƒšแƒแƒ แƒฃแƒšแƒแƒ“ แƒ˜แƒชแƒ•แƒšแƒ”แƒ‘แƒ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ˜แƒกแƒ แƒ“แƒ แƒžแƒšแƒแƒขแƒคแƒแƒ แƒ›แƒ˜แƒก แƒ›แƒ˜แƒฎแƒ”แƒ“แƒ•แƒ˜แƒ—.

แƒกแƒแƒคแƒฃแƒซแƒ•แƒšแƒ”แƒ‘แƒ˜: แƒžแƒ แƒแƒชแƒ”แƒกแƒ˜แƒก แƒ’แƒแƒฌแƒ”แƒ•แƒ แƒ˜แƒแƒœแƒ”แƒ‘แƒ

แƒ—แƒแƒ•แƒ“แƒแƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒแƒ“, ptrace แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ–แƒแƒ แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ–แƒ”แƒช แƒ˜แƒก แƒแƒจแƒ”แƒœแƒ“แƒ strace, แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒš แƒ˜แƒฅแƒœแƒแƒก แƒ›แƒฎแƒแƒšแƒแƒ“ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒก แƒกแƒžแƒ”แƒชแƒ˜แƒแƒšแƒฃแƒ  แƒ แƒ”แƒŸแƒ˜แƒ›แƒจแƒ˜ แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ˜แƒกแƒแƒก. แƒ”แƒก แƒจแƒ”แƒ–แƒฆแƒฃแƒ“แƒ•แƒ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒœแƒ˜แƒ•แƒ แƒฃแƒšแƒแƒ“ แƒŸแƒฆแƒ”แƒ แƒ“แƒ Unix 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 แƒ“แƒแƒ‘แƒ”แƒญแƒ“แƒแƒก แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜ แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒš แƒคแƒแƒ˜แƒšแƒ–แƒ”:

$ 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);
}

แƒ‘แƒฃแƒœแƒ”แƒ‘แƒ แƒ˜แƒ•แƒ˜แƒ, แƒ˜แƒก แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ˜แƒšแƒ˜ แƒšแƒ˜แƒœแƒ™แƒ”แƒ แƒ˜แƒกแƒแƒ“แƒ›แƒ˜ แƒกแƒžแƒ”แƒชแƒ˜แƒแƒšแƒฃแƒ แƒ˜ แƒ›แƒ˜แƒกแƒแƒšแƒ›แƒ”แƒ‘แƒ˜แƒ— - -pthread flag:

$ 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, แƒ แƒแƒ’แƒแƒ แƒช แƒ แƒ”แƒ’แƒฃแƒšแƒแƒ แƒฃแƒšแƒ˜ แƒžแƒ แƒแƒชแƒ”แƒกแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒ“แƒแƒแƒ›แƒแƒขแƒ”แƒ‘แƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒ˜แƒก แƒžแƒ˜แƒ“แƒก แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒฎแƒแƒ–แƒ˜แƒก แƒ“แƒแƒกแƒแƒฌแƒงแƒ˜แƒกแƒจแƒ˜.

แƒ‘แƒฃแƒœแƒ”แƒ‘แƒ แƒ˜แƒ•แƒ˜แƒ, แƒฉแƒ•แƒ”แƒœ แƒแƒ  แƒ•แƒกแƒแƒฃแƒ‘แƒ แƒแƒ‘แƒ— แƒซแƒแƒคแƒ”แƒ‘แƒ˜แƒก แƒ˜แƒ“แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ–แƒ” POSIX Threads แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒ˜แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ’แƒ”แƒ‘แƒ˜แƒ—, แƒแƒ แƒแƒ›แƒ”แƒ“ แƒšแƒ˜แƒœแƒฃแƒฅแƒกแƒ˜แƒก แƒ“แƒแƒ•แƒแƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ แƒ˜แƒชแƒฎแƒ•แƒ–แƒ”. แƒแƒ› แƒฃแƒ™แƒแƒœแƒแƒกแƒ™แƒœแƒ”แƒšแƒ˜แƒก แƒ—แƒ•แƒแƒšแƒกแƒแƒ–แƒ แƒ˜แƒกแƒ˜แƒ—, แƒแƒ  แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒ”แƒ‘แƒ˜ แƒแƒœ แƒซแƒแƒคแƒ”แƒ‘แƒ˜ - แƒแƒ แƒ˜แƒก แƒ“แƒแƒ•แƒแƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒฃแƒœแƒ“แƒ แƒ’แƒแƒ“แƒแƒœแƒแƒฌแƒ˜แƒšแƒ“แƒ”แƒก แƒแƒžแƒแƒ แƒแƒขแƒ˜แƒก แƒแƒ แƒกแƒ”แƒ‘แƒฃแƒš แƒ‘แƒ˜แƒ แƒ—แƒ•แƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก.

แƒ›แƒ แƒแƒ•แƒแƒš แƒซแƒแƒคแƒจแƒ˜ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒกแƒแƒก, แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜ แƒซแƒแƒšแƒ˜แƒแƒœ แƒ‘แƒ”แƒ•แƒ แƒ˜ แƒฎแƒ“แƒ”แƒ‘แƒ:

$ 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 +++

แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ˜แƒก แƒ˜แƒœแƒ”แƒฅแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒ แƒ“แƒ, แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ˜แƒกแƒแƒก แƒแƒœ แƒกแƒ˜แƒ’แƒœแƒแƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ˜แƒกแƒแƒก แƒจแƒ”แƒคแƒ”แƒ แƒฎแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒœแƒ”แƒ แƒ’แƒ•แƒ.

Afterword

แƒ™แƒแƒ›แƒฃแƒœแƒแƒšแƒฃแƒ แƒ˜ strace - แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜ แƒ“แƒ แƒกแƒแƒ˜แƒ›แƒ”แƒ“แƒ แƒ˜แƒœแƒกแƒขแƒ แƒฃแƒ›แƒ”แƒœแƒขแƒ˜. แƒ›แƒแƒ’แƒ แƒแƒ› แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ“แƒ, แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ”แƒ‘แƒ˜แƒกแƒ แƒ“แƒ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒฃแƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒก แƒกแƒฎแƒ•แƒ แƒแƒกแƒžแƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒ แƒ—แƒฃแƒšแƒ˜ แƒ˜แƒงแƒแƒก. แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ›แƒแƒก แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒ แƒ—แƒ•แƒแƒšแƒงแƒฃแƒ แƒ˜ แƒแƒ“แƒ”แƒ•แƒœแƒแƒก แƒ–แƒแƒ แƒ”แƒ‘แƒก แƒ“แƒ˜แƒœแƒแƒ›แƒ˜แƒฃแƒ แƒแƒ“ แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒš แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ”แƒ‘แƒจแƒ˜. แƒ™แƒ•แƒแƒšแƒ˜, แƒ›แƒแƒ— แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒแƒ— แƒ“แƒแƒแƒ—แƒ•แƒแƒšแƒ˜แƒ”แƒ แƒแƒœ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒฃแƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ SystemTap ะธ แƒคแƒขแƒ”แƒ แƒแƒกแƒ˜แƒ“แƒ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒฆแƒ แƒ›แƒแƒ“ แƒ’แƒแƒ›แƒแƒ˜แƒ™แƒ•แƒšแƒ˜แƒแƒ— แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ perf. แƒ›แƒ˜แƒฃแƒฎแƒ”แƒ“แƒแƒ•แƒแƒ“ แƒแƒ›แƒ˜แƒกแƒ, แƒ”แƒก แƒแƒ แƒ˜แƒก strace - แƒ—แƒแƒ•แƒ“แƒแƒชแƒ•แƒ˜แƒก แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒฎแƒแƒ–แƒ˜ แƒกแƒแƒ™แƒฃแƒ—แƒแƒ  แƒ“แƒ แƒกแƒฎแƒ•แƒ˜แƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ”แƒ‘แƒ—แƒแƒœ แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒ— แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒ“แƒ แƒ™แƒ•แƒ˜แƒ แƒแƒจแƒ˜ แƒแƒ แƒฏแƒ”แƒ  แƒ›แƒแƒ˜แƒœแƒช แƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘.

แƒ›แƒแƒ™แƒšแƒ”แƒ“, แƒ—แƒฃ แƒ’แƒ˜แƒงแƒ•แƒแƒ แƒ— Unix, แƒฌแƒแƒ˜แƒ™แƒ˜แƒ—แƒฎแƒ”แƒ— man 1 strace แƒ“แƒ แƒ—แƒแƒ•แƒ˜แƒกแƒฃแƒคแƒšแƒแƒ“ แƒ’แƒแƒ“แƒแƒฎแƒ”แƒ“แƒ”แƒ— แƒ—แƒฅแƒ•แƒ”แƒœแƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ”แƒ‘แƒก!

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ