āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ā§‡ āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸: āĻ‡āĻ¤āĻŋāĻšāĻžāĻ¸, āĻ¨āĻ•āĻļāĻž āĻāĻŦāĻ‚ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°

āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ā§‡ āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸: āĻ‡āĻ¤āĻŋāĻšāĻžāĻ¸, āĻ¨āĻ•āĻļāĻž āĻāĻŦāĻ‚ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°

āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸-āĻāĻ° āĻŽāĻ¤ā§‹ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻŋāĻ‚ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡, āĻŦāĻšāĻŋāĻ°ā§āĻŦāĻŋāĻļā§āĻŦ āĻāĻŦāĻ‚ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻŋāĻ‚ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽā§‡āĻ° āĻ¯ā§‹āĻ—āĻžāĻ¯ā§‹āĻ— āĻāĻ•āĻŸāĻŋ āĻ›ā§‹āĻŸ āĻĢāĻžāĻ‚āĻļāĻ¨ - āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛ā§‡āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ˜āĻŸā§‡āĨ¤ āĻāĻ° āĻŽāĻžāĻ¨ā§‡ āĻšāĻ˛ āĻ¯ā§‡ āĻĄāĻŋāĻŦāĻžāĻ—āĻŋāĻ‚ āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ā§‡ āĻāĻŸāĻŋ āĻĒā§āĻ°āĻ¸ā§‡āĻ¸ āĻĻā§āĻŦāĻžāĻ°āĻž āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻ•āĻ°āĻž āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛āĻ—ā§āĻ˛āĻŋāĻ° āĻ‰āĻĒāĻ° āĻ—ā§āĻĒā§āĻ¤āĻšāĻ°āĻŦā§ƒāĻ¤ā§āĻ¤āĻŋ āĻ•āĻ°āĻ¤ā§‡ āĻ‰āĻĒāĻ¯ā§‹āĻ—ā§€ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĨ¤

āĻāĻ•āĻŸāĻŋ āĻ‡āĻ‰āĻŸāĻŋāĻ˛āĻŋāĻŸāĻŋ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ā§‡ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻ—ā§āĻ˛āĻŋāĻ° "āĻ˜āĻ¨āĻŋāĻˇā§āĻ  āĻœā§€āĻŦāĻ¨" āĻ¨āĻŋāĻ°ā§€āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻ¤ā§‡ āĻ¸āĻšāĻžāĻ¯āĻŧāĻ¤āĻž āĻ•āĻ°ā§‡ strace, āĻ¯āĻž āĻāĻ‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡āĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧ. āĻ—ā§āĻĒā§āĻ¤āĻšāĻ° āĻ¸āĻ°āĻžā§āĻœāĻžāĻŽ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§‡āĻ° āĻ‰āĻĻāĻžāĻšāĻ°āĻŖ āĻāĻ•āĻŸāĻŋ āĻ¸āĻ‚āĻ•ā§āĻˇāĻŋāĻĒā§āĻ¤ āĻ‡āĻ¤āĻŋāĻšāĻžāĻ¸ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡ strace āĻāĻŦāĻ‚ āĻāĻ‡ āĻ§āĻ°āĻ¨ā§‡āĻ° āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽā§‡āĻ° āĻĄāĻŋāĻœāĻžāĻ‡āĻ¨ā§‡āĻ° āĻŦāĻ°ā§āĻŖāĻ¨āĻžāĨ¤

āĻ¸āĻ¨ā§āĻ¤ā§āĻˇā§āĻŸ

āĻĒā§āĻ°āĻœāĻžāĻ¤āĻŋāĻ° āĻ‰āĻ¤āĻĒāĻ¤ā§āĻ¤āĻŋ

āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸ā§‡ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽ āĻāĻŦāĻ‚ āĻ“āĻāĻ¸ āĻ•āĻžāĻ°ā§āĻ¨ā§‡āĻ˛ā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻ‡āĻ¨ā§āĻŸāĻžāĻ°āĻĢā§‡āĻ¸ āĻšāĻ˛ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛āĨ¤ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛, syscalls), āĻŦāĻšāĻŋāĻ°ā§āĻŦāĻŋāĻļā§āĻŦā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻ—ā§āĻ˛āĻŋāĻ° āĻŽāĻŋāĻĨāĻ¸ā§āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¤āĻžāĻĻā§‡āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻāĻ•āĻšā§‡āĻŸāĻŋāĻ¯āĻŧāĻžāĻ­āĻžāĻŦā§‡ āĻ˜āĻŸā§‡āĨ¤

āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸ā§‡āĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻĒāĻžāĻŦāĻ˛āĻŋāĻ• āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖā§‡ (āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ 6 āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸, 1975) āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€āĻ° āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻ†āĻšāĻ°āĻŖ āĻŸā§āĻ°ā§āĻ¯āĻžāĻ• āĻ•āĻ°āĻžāĻ° āĻ•ā§‹āĻ¨ āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻœāĻ¨āĻ• āĻ‰āĻĒāĻžāĻ¯āĻŧ āĻ›āĻŋāĻ˛ āĻ¨āĻžāĨ¤ āĻāĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻŸāĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻ•āĻ°āĻ¤ā§‡, āĻŦā§‡āĻ˛ āĻ˛ā§āĻ¯āĻžāĻŦāĻ¸ āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§€ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖā§‡ āĻ†āĻĒāĻĄā§‡āĻŸ āĻšāĻŦā§‡ (āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ 7 āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸, 1979) āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛ āĻĒā§āĻ°āĻ¸ā§āĻ¤āĻžāĻŦ āĻ•āĻ°ā§‡āĻ›ā§‡ - ptrace.

ptrace āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ•āĻ­āĻžāĻŦā§‡ āĻ‡āĻ¨ā§āĻŸāĻžāĻ°ā§‡āĻ•ā§āĻŸāĻŋāĻ­ āĻĄāĻŋāĻŦāĻžāĻ—āĻžāĻ°āĻĻā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ 80 āĻāĻ° āĻĻāĻļāĻ•ā§‡āĻ° āĻļā§‡āĻˇā§‡āĻ° āĻĻāĻŋāĻ•ā§‡ (āĻŦāĻžāĻŖāĻŋāĻœā§āĻ¯āĻŋāĻ• āĻ¯ā§āĻ—ā§‡ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ­āĻŋ āĻ°āĻŋāĻ˛āĻŋāĻœ 4) āĻāĻ‡ āĻ­āĻŋāĻ¤ā§āĻ¤āĻŋāĻ¤ā§‡, āĻ¸āĻ‚āĻ•ā§€āĻ°ā§āĻŖāĻ­āĻžāĻŦā§‡ āĻĢā§‹āĻ•āĻžāĻ¸āĻĄ āĻĄāĻŋāĻŦāĻžāĻ—āĻžāĻ°-āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛ āĻŸā§āĻ°ā§‡āĻ¸āĻžāĻ°-āĻ†āĻŦāĻŋāĻ°ā§āĻ­ā§‚āĻ¤ āĻšāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻŦā§āĻ¯āĻžāĻĒāĻ•āĻ­āĻžāĻŦā§‡ āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻšāĻ¯āĻŧāĨ¤

āĻĒā§āĻ°āĻĨāĻŽ āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸ā§‡āĻ° āĻāĻ•āĻ‡ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ āĻĒāĻ˛ āĻ•ā§āĻ°ā§‹āĻ¨ā§‡āĻ¨āĻŦāĻžāĻ°ā§āĻ— āĻĻā§āĻŦāĻžāĻ°āĻž 1992 āĻ¸āĻžāĻ˛ā§‡ āĻāĻ•āĻŸāĻŋ āĻŦāĻ¨ā§āĻ§ āĻ‡āĻ‰āĻŸāĻŋāĻ˛āĻŋāĻŸāĻŋāĻ° āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āĻšāĻŋāĻ¸āĻžāĻŦā§‡ comp.sources.sun āĻŽā§‡āĻ˛āĻŋāĻ‚ āĻ¤āĻžāĻ˛āĻŋāĻ•āĻžāĻ¯āĻŧ āĻĒā§āĻ°āĻ•āĻžāĻļāĻŋāĻ¤ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛āĨ¤ trace āĻ¸ā§‚āĻ°ā§āĻ¯ āĻĨā§‡āĻ•ā§‡āĨ¤ āĻ•ā§āĻ˛ā§‹āĻ¨ āĻāĻŦāĻ‚ āĻ†āĻ¸āĻ˛ āĻ‰āĻ­āĻ¯āĻŧāĻ‡ SunOS-āĻāĻ° āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ā§‡ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ 1994 āĻ¸āĻžāĻ˛ā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ strace āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ V, āĻ¸ā§‹āĻ˛āĻžāĻ°āĻŋāĻ¸ āĻāĻŦāĻ‚ āĻ•ā§āĻ°āĻŽāĻŦāĻ°ā§āĻ§āĻŽāĻžāĻ¨ āĻœāĻ¨āĻĒā§āĻ°āĻŋāĻ¯āĻŧ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ā§‡ āĻĒā§‹āĻ°ā§āĻŸ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛āĨ¤

āĻ†āĻœ āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨ āĻ•āĻ°ā§‡ āĻāĻŦāĻ‚ āĻāĻ° āĻ‰āĻĒāĻ° āĻ¨āĻŋāĻ°ā§āĻ­āĻ° āĻ•āĻ°ā§‡ ptrace, āĻ…āĻ¨ā§‡āĻ• āĻāĻ•ā§āĻ¸āĻŸā§‡āĻ¨āĻļāĻ¨ āĻ¸āĻ™ā§āĻ—ā§‡ overgrown.

āĻ†āĻ§ā§āĻ¨āĻŋāĻ• (āĻāĻŦāĻ‚ āĻ–ā§āĻŦ āĻ¸āĻ•ā§āĻ°āĻŋāĻ¯āĻŧ) āĻ°āĻ•ā§āĻˇāĻŖāĻžāĻŦā§‡āĻ•ā§āĻˇāĻŖāĻ•āĻžāĻ°ā§€ strace - āĻĻāĻŋāĻŽāĻŋāĻ¤ā§āĻ°āĻŋ āĻ˛ā§‡āĻ­āĻŋāĻ¨. āĻ¤āĻžāĻ•ā§‡ āĻ§āĻ¨ā§āĻ¯āĻŦāĻžāĻĻ, āĻ‡āĻ‰āĻŸāĻŋāĻ˛āĻŋāĻŸāĻŋ āĻ‰āĻ¨ā§āĻ¨āĻ¤ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯āĻ—ā§āĻ˛āĻŋ āĻ…āĻ°ā§āĻœāĻ¨ āĻ•āĻ°ā§‡āĻ›ā§‡ āĻ¯ā§‡āĻŽāĻ¨ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛āĻ—ā§āĻ˛āĻŋāĻ¤ā§‡ āĻ¤ā§āĻ°ā§āĻŸāĻŋ āĻ‡āĻ¨āĻœā§‡āĻ•āĻļāĻ¨, āĻŦāĻŋāĻ¸ā§āĻ¤ā§ƒāĻ¤ āĻ¸ā§āĻĨāĻžāĻĒāĻ¤ā§āĻ¯ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨ āĻāĻŦāĻ‚ āĻ¸āĻŦāĻšā§‡āĻ¯āĻŧā§‡ āĻ—ā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖāĻ­āĻžāĻŦā§‡, āĻŽāĻžāĻ¸āĻ•āĻŸ. āĻ…āĻ¨āĻžāĻ¨ā§āĻˇā§āĻ āĻžāĻ¨āĻŋāĻ• āĻ¸ā§‚āĻ¤ā§āĻ°āĻ—ā§āĻ˛āĻŋ āĻĻāĻžāĻŦāĻŋ āĻ•āĻ°ā§‡āĻ›ā§‡ āĻ¯ā§‡ āĻ°āĻžāĻļāĻŋāĻ¯āĻŧāĻžāĻ¨ āĻļāĻŦā§āĻĻ "āĻ‰āĻŸāĻĒāĻžāĻ–āĻŋ" āĻāĻŦāĻ‚ āĻ‡āĻ‚āĻ°ā§‡āĻœāĻŋ āĻļāĻŦā§āĻĻ "āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸" āĻāĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻŦā§āĻ¯āĻžā§āĻœāĻ¨āĻžāĻ° āĻ•āĻžāĻ°āĻŖā§‡ āĻĒāĻ›āĻ¨ā§āĻĻāĻŸāĻŋ āĻ‰āĻŸāĻĒāĻžāĻ–āĻŋāĻ° āĻ‰āĻĒāĻ° āĻĒāĻĄāĻŧā§‡āĻ›ā§‡āĨ¤

āĻāĻŸāĻžāĻ“ āĻ—ā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻ¯ā§‡ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸, āĻĢā§āĻ°āĻŋāĻŦāĻŋāĻāĻ¸āĻĄāĻŋ, āĻ“āĻĒā§‡āĻ¨āĻŦāĻŋāĻāĻ¸āĻĄāĻŋ āĻāĻŦāĻ‚ āĻāĻ¤āĻŋāĻšā§āĻ¯āĻŦāĻžāĻšā§€ āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸ā§‡ āĻĻā§€āĻ°ā§āĻ˜ āĻ‡āĻ¤āĻŋāĻšāĻžāĻ¸ āĻāĻŦāĻ‚ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻ¸āĻ¤ā§āĻ¤ā§āĻŦā§‡āĻ“ ptrace āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛ āĻāĻŦāĻ‚ āĻŸā§āĻ°ā§‡āĻ¸āĻžāĻ°āĻ—ā§āĻ˛āĻŋ POSIX-āĻ āĻ…āĻ¨ā§āĻ¤āĻ°ā§āĻ­ā§āĻ•ā§āĻ¤ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧāĻ¨āĻŋāĨ¤

āĻ¸āĻ‚āĻ•ā§āĻˇā§‡āĻĒā§‡ āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸ āĻĄāĻŋāĻ­āĻžāĻ‡āĻ¸: āĻĒāĻŋāĻ—āĻ˛ā§‡āĻŸ āĻŸā§āĻ°ā§‡āĻ¸

"āĻ†āĻĒāĻ¨āĻŋ āĻāĻŸāĻŋ āĻŦā§āĻāĻ¤ā§‡ āĻĒāĻžāĻ°āĻŦā§‡āĻ¨ āĻŦāĻ˛ā§‡ āĻ†āĻļāĻž āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡ āĻ¨āĻž" (āĻĄā§‡āĻ¨āĻŋāĻ¸ āĻ°āĻŋāĻšāĻŋ, āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ 6 āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸ āĻ¸ā§‹āĻ°ā§āĻ¸ āĻ•ā§‹āĻĄā§‡ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯)

āĻļā§ˆāĻļāĻŦāĻ•āĻžāĻ˛ āĻĨā§‡āĻ•ā§‡āĻ‡, āĻ†āĻŽāĻŋ āĻŦā§āĻ˛ā§āĻ¯āĻžāĻ• āĻŦāĻ•ā§āĻ¸āĻ—ā§āĻ˛āĻŋ āĻĻāĻžāĻāĻĄāĻŧāĻžāĻ¤ā§‡ āĻĒāĻžāĻ°āĻŋ āĻ¨āĻž: āĻ†āĻŽāĻŋ āĻ–ā§‡āĻ˛āĻ¨āĻž āĻ¨āĻŋāĻ¯āĻŧā§‡ āĻ–ā§‡āĻ˛āĻ¤āĻžāĻŽ āĻ¨āĻž, āĻ¤āĻŦā§‡ āĻ¤āĻžāĻĻā§‡āĻ° āĻ—āĻ āĻ¨ āĻŦā§‹āĻāĻžāĻ° āĻšā§‡āĻˇā§āĻŸāĻž āĻ•āĻ°āĻ¤āĻžāĻŽ (āĻĒā§āĻ°āĻžāĻĒā§āĻ¤āĻŦāĻ¯āĻŧāĻ¸ā§āĻ•āĻ°āĻž "āĻŦā§āĻ°ā§‡āĻ•" āĻļāĻŦā§āĻĻāĻŸāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻ¤āĻŦā§‡ āĻŽāĻ¨ā§āĻĻ āĻœāĻŋāĻšā§āĻŦāĻžāĻ•ā§‡ āĻŦāĻŋāĻļā§āĻŦāĻžāĻ¸ āĻ•āĻ°āĻŦā§‡āĻ¨ āĻ¨āĻž)āĨ¤ āĻ¸āĻŽā§āĻ­āĻŦāĻ¤ āĻāĻ‡ āĻ•āĻžāĻ°āĻŖā§‡āĻ‡ āĻĒā§āĻ°āĻĨāĻŽ āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸ā§‡āĻ° āĻ…āĻ¨āĻžāĻ¨ā§āĻˇā§āĻ āĻžāĻ¨āĻŋāĻ• āĻ¸āĻ‚āĻ¸ā§āĻ•ā§ƒāĻ¤āĻŋ āĻāĻŦāĻ‚ āĻ†āĻ§ā§āĻ¨āĻŋāĻ• āĻ“āĻĒā§‡āĻ¨-āĻ¸ā§‹āĻ°ā§āĻ¸ āĻ†āĻ¨ā§āĻĻā§‹āĻ˛āĻ¨ āĻ†āĻŽāĻžāĻ° āĻ–ā§āĻŦ āĻ•āĻžāĻ›āĻžāĻ•āĻžāĻ›āĻŋāĨ¤

āĻāĻ‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŸāĻŋāĻ° āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ā§‡, āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸ā§‡āĻ° āĻ¸ā§‹āĻ°ā§āĻ¸ āĻ•ā§‹āĻĄāĻŸāĻŋ āĻŦāĻŋāĻšā§āĻ›āĻŋāĻ¨ā§āĻ¨ āĻ•āĻ°āĻž āĻ…āĻ¯ā§ŒāĻ•ā§āĻ¤āĻŋāĻ•, āĻ¯āĻž āĻ•āĻ¯āĻŧā§‡āĻ• āĻĻāĻļāĻ• āĻ§āĻ°ā§‡ āĻŦā§‡āĻĄāĻŧā§‡āĻ›ā§‡āĨ¤ āĻ¤āĻŦā§‡ āĻĒāĻžāĻ āĻ•āĻĻā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ•ā§‹āĻ¨ āĻ—ā§‹āĻĒāĻ¨ā§€āĻ¯āĻŧāĻ¤āĻž āĻĨāĻžāĻ•āĻž āĻ‰āĻšāĻŋāĻ¤ āĻ¨āĻ¯āĻŧāĨ¤ āĻ…āĻ¤āĻāĻŦ, āĻāĻ‡ āĻœāĻžāĻ¤ā§€āĻ¯āĻŧ āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻ—ā§āĻ˛āĻŋāĻ° āĻĒāĻ°āĻŋāĻšāĻžāĻ˛āĻ¨āĻžāĻ° āĻ¨ā§€āĻ¤āĻŋ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹āĻ° āĻœāĻ¨ā§āĻ¯, āĻ†āĻŽāĻŋ āĻāĻ•āĻŸāĻŋ āĻ•ā§āĻˇā§āĻĻā§āĻ° āĻŸā§āĻ°ā§‡āĻ¸āĻžāĻ°ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ•ā§‹āĻĄ āĻ¸āĻ°āĻŦāĻ°āĻžāĻš āĻ•āĻ°āĻŦ - āĻĒāĻŋāĻ—āĻ˛ā§‡āĻŸ āĻŸā§āĻ°ā§‡āĻ¸ (ptr)āĨ¤ āĻāĻŸāĻŋ āĻ•ā§€āĻ­āĻžāĻŦā§‡ āĻŦāĻŋāĻļā§‡āĻˇ āĻ•āĻŋāĻ›ā§ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻ¯āĻŧ āĻ¤āĻž āĻœāĻžāĻ¨ā§‡ āĻ¨āĻž, āĻ¤āĻŦā§‡ āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻœāĻŋāĻ¨āĻŋāĻ¸āĻŸāĻŋ āĻš'āĻ˛ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻŸāĻŋāĻ° āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛ - āĻāĻŸāĻŋ āĻ†āĻ‰āĻŸāĻĒā§āĻŸ āĻĻā§‡āĻ¯āĻŧ:

$ 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

āĻĒāĻŋāĻ—āĻ˛ā§‡āĻŸ āĻŸā§āĻ°ā§‡āĻ¸ āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻļāĻ¤ āĻļāĻ¤ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛āĻ•ā§‡ āĻ¸ā§āĻŦā§€āĻ•ā§ƒāĻ¤āĻŋ āĻĻā§‡āĻ¯āĻŧ (āĻĻā§‡āĻ–ā§āĻ¨āĨ¤ āĻŸā§‡āĻŦāĻŋāĻ˛) āĻāĻŦāĻ‚ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° x86-64 āĻ†āĻ°ā§āĻ•āĻŋāĻŸā§‡āĻ•āĻšāĻžāĻ°ā§‡ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡āĨ¤ āĻāĻŸāĻŋ āĻļāĻŋāĻ•ā§āĻˇāĻžāĻ—āĻ¤ āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ā§‡ āĻ¯āĻĨā§‡āĻˇā§āĻŸāĨ¤

āĻ†āĻ¸ā§āĻ¨ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ•ā§āĻ˛ā§‹āĻ¨ā§‡āĻ° āĻ•āĻžāĻœ āĻĻā§‡āĻ–āĻŋāĨ¤ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ā§‡āĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻĄāĻŋāĻŦāĻžāĻ—āĻžāĻ° āĻāĻŦāĻ‚ āĻŸā§āĻ°ā§‡āĻ¸āĻžāĻ°āĻ°āĻž āĻ‰āĻĒāĻ°ā§‡ āĻ‰āĻ˛ā§āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻšāĻŋāĻ¸āĻžāĻŦā§‡, 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, &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 āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ā§‡āĨ¤

āĻŦā§‡āĻ¸āĻŋāĻ•: āĻ¸ā§āĻŸā§āĻ°ā§‡āĻ¸ āĻšāĻ˛āĻŽāĻžāĻ¨ āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽ āĻšāĻžāĻ˛āĻžāĻ¨ā§‹

āĻĒā§āĻ°āĻĨāĻŽ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§‡āĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡ 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);
}

āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ•āĻ­āĻžāĻŦā§‡āĻ‡, āĻāĻŸāĻŋ āĻ…āĻŦāĻļā§āĻ¯āĻ‡ āĻ˛āĻŋāĻ™ā§āĻ•āĻžāĻ°āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻŦāĻŋāĻļā§‡āĻˇ āĻļā§āĻ­ā§‡āĻšā§āĻ›āĻž āĻ¸āĻš āĻ¸āĻ‚āĻ•āĻ˛āĻŋāĻ¤ āĻ•āĻ°āĻž āĻ‰āĻšāĻŋāĻ¤ - -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, āĻ¨āĻŋāĻ¯āĻŧāĻŽāĻŋāĻ¤ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ˛āĻžāĻ‡āĻ¨ā§‡āĻ° āĻļā§āĻ°ā§āĻ¤ā§‡ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻŸāĻŋāĻ° āĻĒāĻŋāĻĄ āĻ¯ā§‹āĻ— āĻ•āĻ°āĻŦā§‡āĨ¤

āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ•āĻ­āĻžāĻŦā§‡āĻ‡, āĻ†āĻŽāĻ°āĻž POSIX āĻĨā§āĻ°ā§‡āĻĄ āĻ¸ā§āĻŸā§āĻ¯āĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§‡āĻ° āĻ…āĻ°ā§āĻĨā§‡ āĻāĻ•āĻŸāĻŋ āĻĨā§āĻ°ā§‡āĻĄ āĻļāĻ¨āĻžāĻ•ā§āĻ¤āĻ•āĻžāĻ°ā§€ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ•āĻĨāĻž āĻŦāĻ˛āĻ›āĻŋ āĻ¨āĻž, āĻ¤āĻŦā§‡ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ā§‡ āĻŸāĻžāĻ¸ā§āĻ• āĻļāĻŋāĻĄāĻŋāĻ‰āĻ˛āĻžāĻ°ā§‡āĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ•āĻĨāĻž āĻŦāĻ˛āĻ›āĻŋāĨ¤ āĻĒāĻ°ā§‡āĻ°āĻŸāĻŋāĻ° āĻĻā§ƒāĻˇā§āĻŸāĻŋāĻ•ā§‹āĻŖ āĻĨā§‡āĻ•ā§‡, āĻ•ā§‹āĻ¨āĻ“ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻŦāĻž āĻĨā§āĻ°ā§‡āĻĄ āĻ¨ā§‡āĻ‡ - āĻāĻŽāĻ¨ āĻ•āĻžāĻœ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡ āĻ¯āĻž āĻŽā§‡āĻļāĻŋāĻ¨ā§‡āĻ° āĻ‰āĻĒāĻ˛āĻŦā§āĻ§ āĻ•ā§‹āĻ°āĻ—ā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻ•āĻ°āĻž āĻĻāĻ°āĻ•āĻžāĻ°āĨ¤

āĻāĻ•āĻžāĻ§āĻŋāĻ• āĻĨā§āĻ°ā§‡āĻĄā§‡ āĻ•āĻžāĻœ āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ, āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛ āĻ…āĻ¨ā§‡āĻ• āĻŦā§‡āĻļāĻŋ āĻšāĻ¯āĻŧā§‡ āĻ¯āĻžāĻ¯āĻŧ:

$ 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 - āĻāĻ•āĻŸāĻŋ āĻ¸āĻšāĻœ āĻāĻŦāĻ‚ āĻ¨āĻŋāĻ°ā§āĻ­āĻ°āĻ¯ā§‹āĻ—ā§āĻ¯ āĻŸā§āĻ˛āĨ¤ āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛ āĻ›āĻžāĻĄāĻŧāĻžāĻ“, āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽ āĻĒāĻ°āĻŋāĻšāĻžāĻ˛āĻ¨āĻžāĻ° āĻ…āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻĻāĻŋāĻ• āĻāĻŦāĻ‚ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻŋāĻ‚ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻĄāĻŋāĻŦāĻžāĻ— āĻ•āĻ°āĻž āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĨ¤ āĻ‰āĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§‚āĻĒ, āĻāĻŸāĻŋ āĻ—āĻ¤āĻŋāĻļā§€āĻ˛āĻ­āĻžāĻŦā§‡ āĻ˛āĻŋāĻ™ā§āĻ•āĻ¯ā§āĻ•ā§āĻ¤ āĻ˛āĻžāĻ‡āĻŦā§āĻ°ā§‡āĻ°āĻŋāĻ¤ā§‡ āĻ•āĻ˛ āĻŸā§āĻ°ā§āĻ¯āĻžāĻ• āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĨ¤ ltrace, āĻ¤āĻžāĻ°āĻž āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻŋāĻ‚ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡āĻ° āĻ…āĻĒāĻžāĻ°ā§‡āĻļāĻ¨ āĻĻā§‡āĻ–āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽāĻŸā§āĻ¯āĻžāĻĒ и ftrace, āĻāĻŦāĻ‚ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽā§‡āĻ° āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻžāĻ°āĻŋāĻ¤āĻž āĻ—āĻ­ā§€āĻ°āĻ­āĻžāĻŦā§‡ āĻ¤āĻĻāĻ¨ā§āĻ¤ āĻ•āĻ°āĻ¤ā§‡ āĻĻā§‡āĻ¯āĻŧ āĻĒāĻžāĻ°āĻĢ. āĻ¤āĻŦā§āĻ“, āĻāĻŸāĻž āĻšāĻ¯āĻŧ strace - āĻ†āĻŽāĻžāĻ° āĻ¨āĻŋāĻœā§‡āĻ° āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ˛ā§‹āĻ•ā§‡āĻĻā§‡āĻ° āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻ—ā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻĨā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡ āĻĒā§āĻ°āĻ¤āĻŋāĻ°āĻ•ā§āĻˇāĻžāĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻ˛āĻžāĻ‡āĻ¨, āĻāĻŦāĻ‚ āĻ†āĻŽāĻŋ āĻāĻŸāĻŋ āĻ¸āĻĒā§āĻ¤āĻžāĻšā§‡ āĻ…āĻ¨ā§āĻ¤āĻ¤ āĻ•āĻ¯āĻŧā§‡āĻ•āĻŦāĻžāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻŋāĨ¤

āĻ¸āĻ‚āĻ•ā§āĻˇā§‡āĻĒā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻ‡āĻ‰āĻ¨āĻŋāĻ•ā§āĻ¸ āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āĻ°ā§‡āĻ¨ āĻ¤āĻŦā§‡ āĻĒāĻĄāĻŧā§āĻ¨ man 1 strace āĻāĻŦāĻ‚ āĻ†āĻĒāĻ¨āĻžāĻ° āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽ āĻ āĻ‰āĻāĻ•āĻŋ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻŦāĻŋāĻ§āĻžāĻ¯āĻŧ!

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨