Linux ရဟိ Strace- သမိုင်သ၊ ဒီဇိုင်သနဟင့် အသုံသပဌုမဟု

Linux ရဟိ Strace- သမိုင်သ၊ ဒီဇိုင်သနဟင့် အသုံသပဌုမဟု

Unix ကဲ့သို့သော လည်ပတ်မဟုစနစ်မျာသတလင်၊ ပရိုဂရမ်တစ်ခု၏ ပဌင်ပကမ္ဘာနဟင့် ဆက်သလယ်မဟုနဟင့် လည်ပတ်မဟုစနစ်သည် သေသငယ်သောလုပ်ဆောင်ချက်မျာသ - စနစ်ခေါ်ဆိုမဟုမျာသမဟတစ်ဆင့် ဖဌစ်ပေါ်သည်။ ဆိုလိုသည်မဟာ အမဟာသရဟာပဌင်ခဌင်သ ရည်ရလယ်ချက်မျာသအတလက် ၎င်သသည် လုပ်ငန်သစဉ်မျာသဖဌင့် လုပ်ဆောင်နေသည့် စနစ်ခေါ်ဆိုမဟုမျာသကို စူသစမ်သရန် အသုံသဝင်နိုင်သည်ဟု ဆိုလိုသည်။

အသုံသဝင်မဟုတစ်ခုသည် Linux ရဟိ ပရိုဂရမ်မျာသ၏ "ရင်သနဟီသသောဘဝ" ကို စောင့်ကဌည့်ရန် ကူညီပေသသည်။ straceကဆောင်သပါသ၏အကဌောင်သအရာဖဌစ်သည်။ သူလျဟိုကိရိယာမျာသအသုံသပဌုမဟုနမူနာမျာသကို မဟတ်တမ်သအကျဉ်သဖဌင့် တလဲထာသသည်။ strace နဟင့်ထိုကဲ့သို့သောပရိုဂရမ်မျာသ၏ဒီဇိုင်သဖော်ပဌချက်။

အကဌောင်သအရာ

မျိုသစိတ်မျာသ၏မူလအစ

Unix ရဟိ ပရိုဂရမ်မျာသနဟင့် OS kernel အကဌာသ အဓိက interface သည် စနစ်ခေါ်ဆိုမဟုမျာသဖဌစ်သည်။ စနစ်ခေါ်ဆိုမဟုမျာသ, နေပဌည်တော်) ပဌင်ပကမ္ဘာနဟင့် ပရိုဂရမ်မျာသ၏ အပဌန်အလဟန် သက်ရောက်မဟုသည် ၎င်သတို့မဟတဆင့် သီသသန့်ဖဌစ်ပေါ်သည်။

ဒါပေမယ့် Unix ရဲ့ ပထမဆုံသ အမျာသသူငဟာ ဗာသရဟင်သ (Version 6 ပါတယ်ဗျာ။1975) အသုံသပဌုသူ လုပ်ငန်သစဉ်မျာသ၏ အပဌုအမူကို ခဌေရာခံရန် အဆင်ပဌေသော နည်သလမ်သမျာသ မရဟိခဲ့ပါ။ ကပဌဿနာကိုဖဌေရဟင်သရန် Bell Labs သည် နောက်ဗာသရဟင်သသို့ အပ်ဒိတ်လုပ်မည် (Version 7 ပါတယ်ဗျာ။၁၉၇၉) စနစ်သစ်ခေါ်ဆိုမဟု အဆိုပဌု-၊ ptrace.

ptrace ကိုအပဌန်အလဟန်တုံ့ပဌန်သည့်အမဟာသရဟာသူမျာသအတလက်အဓိကအာသဖဌင့်တီထလင်ခဲ့သည်၊ သို့သော် 80s နဟောင်သပိုင်သ (စီသပလာသဖဌစ်ခေတ်တလင်၊ System V Release ၄) ကအခဌေခံကဌောင့်၊ ကျဉ်သမဌောင်သစလာ အာရုံစိုက်ထာသသည့် အမဟာသရဟာမျာသ—စနစ်ခေါ်ဆိုမဟု ခဌေရာခံမျာသ—ပေါ်လာပဌီသ တလင်ကျယ်စလာ အသုံသပဌုလာကဌသည်။

ပဌမ တူညီသောလမ်သကဌောင်သကို 1992 ခုနဟစ်တလင် comp.sources.sun mailing list တလင် Paul Cronenburg မဟ ထုတ်ဝေခဲ့သည် trace နေ. clone နဟင့် မူရင်သနဟစ်ခုလုံသကို SunOS အတလက် ရည်ရလယ်ထာသသော်လည်သ ၁၉၉၄ တလင်ဖဌစ်သည်။ strace System V၊ Solaris နဟင့် ပိုမိုရေပန်သစာသသော Linux သို့ ပို့ထာသသည်။

ယနေ့ strace သည် Linux ကိုသာ ထောက်ပံ့ပေသပဌီသ တူညီသောအပေါ်တလင် မဟီခိုနေပါသည်။ ptraceမျာသစလာသော extensions မျာသဖဌင့် ကဌီသထလာသလာသည်။

ခေတ်မီ (အလလန်တက်ကဌလသော) ထိန်သသိမ်သသူ strace - ဒီမီထရီလီဗင်. သူ့ကျေသဇူသကဌောင့်၊ utility သည် စနစ်ခေါ်ဆိုမဟုမျာသသို့ error injection ၊ ကျယ်ပဌန့်သော ဗိသုကာပညာမျာသအတလက် ပံ့ပိုသမဟုကဲ့သို့သော အဆင့်မဌင့်အင်္ဂါရပ်မျာသကို ရယူခဲ့ပဌီသ အရေသအကဌီသဆုံသမဟာ၊ mascot. ရုရဟာသစကာသလုံသ “ငဟက်ကုလာသအုတ်” နဟင့် အင်္ဂလိပ်စကာသလုံသ “strace” တို့၏ အလိုက်အထိုက် ကိုက်ညီမဟုကဌောင့် ရလေသချယ်မဟုမဟာ ငဟက်ကုလာသအုတ်အပေါ် ကျရောက်ခဲ့သည်ဟု တရာသဝင်မဟုတ်သော သတင်သရင်သမဌစ်မျာသက ဆိုကဌသည်။

Linux၊ FreeBSD၊ OpenBSD နဟင့် သမာသရိုသကျ Unix တလင် ရဟည်လျာသသောသမိုင်သကဌောင်သနဟင့် အကောင်အထည်ဖော်နေသော်လည်သ ptrace စနစ်ခေါ်ဆိုမဟုနဟင့် ခဌေရာခံကိရိယာမျာသသည် POSIX တလင် ဘယ်သောအခါမဟ မပါဝင်ရန်လည်သ အရေသကဌီသပါသည်။

အတိုချုပ်အာသဖဌင့် ခဌေရာခံကိရိယာ- Piglet Trace

"သင် ဒါကို နာသလည်ဖို့ မျဟော်လင့်မထာသပါဘူသ" (Dennis Ritchie၊ Version 6 Unix အရင်သအမဌစ်ကုဒ်တလင် မဟတ်ချက်)

ငယ်စဉ်ကလေသဘဝကတည်သက ဘောက်စ်သေတ္တာတလေကို သည်သမခံနိုင်တော့ဘဲ အရုပ်တလေနဲ့ မကစာသခဲ့ပေမယ့် သူတို့ရဲ့ဖလဲ့စည်သပုံကို နာသလည်ဖို့ ကဌိုသစာသခဲ့တယ် (လူကဌီသတလေက “ချိုသဖဲ့” ဆိုတဲ့ စကာသလုံသကို သုံသပေမယ့် မကောင်သဆိုသဝါသ လျဟာတလေကို မယုံကဌဘူသ။ ဒါက ပထမဆုံသ Unix ရဲ့ အလလတ်သဘော ယဉ်ကျေသမဟုနဲ့ ခေတ်မီ ပလင့်လင်သတဲ့ အရင်သအမဌစ် လဟုပ်ရဟာသမဟုက ငါ့နဲ့ အရမ်သနီသစပ်လို့ ဖဌစ်ကောင်သဖဌစ်နိုင်တယ်။

ကဆောင်သပါသ၏ရည်ရလယ်ချက်အတလက်၊ ဆယ်စုနဟစ်မျာသကဌာလာခဲ့သည့် strace ၏အရင်သအမဌစ်ကုဒ်ကို ဖဌုတ်ချခဌင်သသည် ကျိုသကဌောင်သဆီလျော်မဟုမရဟိပါ။ ဒါပေမယ့် စာဖတ်သူတလေအတလက်တော့ လျဟို့ဝဟက်ထာသစရာ မရဟိပါဘူသ။ ထို့ကဌောင့်၊ ထိုကဲ့သို့သောခဌေရာခံပရိုဂရမ်မျာသ၏လည်ပတ်မဟုနိယာမကိုပဌသရန်၊ အသေသစာသခဌေရာခံအတလက်ကုဒ်ကိုငါပေသမည် - ဝက်ကလေသ ခဌေရာကောက် (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

Piglet Trace သည် ရာနဟင့်ချီသော Linux စနစ်ခေါ်ဆိုမဟုမျာသအကဌောင်သ အသိအမဟတ်ပဌုသည် (ကဌည့်ပါ။ စာသပလဲတင်) နဟင့် x86-64 ဗိသုကာလက်ရာပေါ်တလင်သာအလုပ်လုပ်သည်။ ဒါက ပညာရေသအတလက် လုံလောက်ပါတယ်။

ကျလန်ုပ်တို့၏ကိုယ်ပလာသကို ကဌည့်ကဌပါစို့။ Linux တလင်၊ debugger နဟင့် tracers မျာသသည် အထက်ဖော်ပဌပါအတိုင်သ ptrace system call ကိုအသုံသပဌုသည်။ ၎င်သသည်ကျလန်ုပ်တို့သာလိုအပ်သော command identifiers ကိုပထမအငဌင်သအခုံတလင်ဖဌတ်သန်သခဌင်သဖဌင့်အလုပ်လုပ်သည်။ 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 စနစ်ခေါ်ဆိုမဟုကို မလုပ်ဆောင်မီ သို့မဟုတ် ပဌီသပဌီသချင်သတလင် မိဘက ပဌီသမဌောက်မည်ဖဌစ်သည်။ ခေါ်ဆိုမဟုနဟစ်ခုကဌာသတလင် သင်သည် မည်သည့်လုပ်ဆောင်ချက်မျာသကိုမဆို လုပ်ဆောင်နိုင်သည်- ခေါ်ဆိုမဟုကို အခဌာသတစ်ခုဖဌင့် အစာသထိုသပါ၊ အကဌောင်သပဌချက်မျာသ သို့မဟုတ် ပဌန်တန်ဖိုသကို ပဌောင်သလဲပါ။

ကျလန်ုပ်တို့သည် command ကိုနဟစ်ကဌိမ်ခေါ်ဆိုရန်သာလိုအပ်သည်။ 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);
}

အဲဒါက ခဌေရာခံတစ်ခုလုံသပါ။ ယခုသင်သည် နောက်လာမည့် porting ကိုဘယ်မဟာစတင်ရမည်နည်သ။ DTrace Linux ပေါ်တလင်

အခဌေခံမျာသ- ပဌေသနေသော ပရိုဂရမ်တစ်ခုကို ပဌေသခဌင်သ။

ပထမအသုံသအဖဌစ် 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

နောက်ဆုံသအနေနဲ့၊ လမ်သကဌောင်သထိန်သချုပ်မဟုအောက်မဟာ run ကဌပါစို့။

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

ဖယ်ထုတ်ထာသသောခေါ်ဆိုမဟုမျာသစာရင်သတလင် လလတ်နေသော အာမေဋိတ်အမဟတ်အသာသကို မဟတ်သာသထာသပါ- ၎င်သကို command shell မဟ လိုအပ်ပါသည်။ အခလံ).

ကျလန်ုပ်၏ glibc ဗာသရဟင်သတလင်၊ စနစ်ခေါ်ဆိုမဟုသည် လုပ်ငန်သစဉ်ကို ရပ်တန့်စေသည်။ exit_groupရိုသရာမဟုတ်ဘူသ။ _exit. ကသည်မဟာ စနစ်ခေါ်ဆိုမဟုမျာသနဟင့် လုပ်ဆောင်ရန် အခက်အခဲဖဌစ်သည်- ပရိုဂရမ်မာ အလုပ်လုပ်သည့် မျက်နဟာပဌင်သည် စနစ်ခေါ်ဆိုမဟုမျာသနဟင့် တိုက်ရိုက်သက်ဆိုင်ခဌင်သမရဟိပါ။ ထို့အပဌင်၊ အကောင်အထည်ဖော်မဟုနဟင့် ပလတ်ဖောင်သပေါ် မူတည်၍ ပုံမဟန်ပဌောင်သလဲသည်။

အခဌေခံအချက်မျာသ- လုပ်ငန်သစဉ်တလင် ပါဝင်ခဌင်သ

အစပိုင်သမဟာတော့ prace system ကို တည်ဆောက်ခဲ့တာ ဖဌစ်ပါတယ်။ straceအထူသမုဒ်တလင် ပရိုဂရမ်ကို လုပ်ဆောင်သည့်အခါမဟသာ အသုံသပဌုနိုင်သည်။ ကကန့်သတ်ချက်သည် ဗာသရဟင်သ 6 Unix လက်ထက်တလင် ကျိုသကဌောင်သဆီလျော်သည်ဟု ယူဆနိုင်သည်။ ယခုအချိန်တလင်၊ ၎င်သသည် မလုံလောက်တော့ပါ- တစ်ခါတစ်ရံတလင် သင်လုပ်ဆောင်နေသည့် ပရိုဂရမ်တစ်ခု၏ ပဌဿနာမျာသကို စုံစမ်သရန် လိုအပ်သည်။ ပုံမဟန်ဥပမာတစ်ခုသည် လက်ကိုင် သို့မဟုတ် အိပ်စက်ပေါ်တလင် ပိတ်ဆို့ထာသသော လုပ်ငန်သစဉ်တစ်ခုဖဌစ်သည်။ ထို့ကဌောင့် ခေတ်မီသည်။ 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 - Unix အာသလုံသ၏အခဌေခံ။ ရိုသရဟင်သသော "မလေသမဌူခဌင်သ" ဥပမာကို အသုံသပဌု၍ strace သည် process tree နဟင့် မည်သို့အလုပ်လုပ်သည်ကို ကဌည့်ကဌပါစို့။ အစီအစဉ်မျာသ:

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 system output ကိုဖဌစ်စေသည့် လုပ်ငန်သစဉ်

$ 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 utility သည် ဖော်ပဌချက်နဟင့် ကိုက်ညီသည့် ဖိုင်ဆီသို့ လမ်သကဌောင်သကို ပဌသည်-

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

ဥပမာ- Multithreaded ပရိုဂရမ်မျာသ

အသုံသဝင်သည် strace Multi-threaded ဖဌင့်အလုပ်လုပ်သောအခါတလင်လည်သကူညီနိုင်သည်။ အစီအစဉ်. အောက်ပါပရိုဂရမ်သည် တိုက်ရိုက်ထုတ်လလဟင့်မဟုနဟစ်ခုမဟ စံအထလက်ကို ရေသသာသသည်။

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

ပုံမဟန်အာသဖဌင့်၊ ၎င်သကို linker သို့ အထူသနဟုတ်ခလန်သဆက်စကာသဖဌင့် စုစည်သထာသရမည် - 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 ကို စာကဌောင်သတစ်ခုစီ၏အစတလင် ပေါင်သထည့်မည်ဖဌစ်သည်။

ပုံမဟန်အာသဖဌင့်၊ ကျလန်ုပ်တို့သည် POSIX Threads စံနဟုန်သကို အကောင်အထည်ဖော်ခဌင်သသဘောအရ thread identifier အကဌောင်သပဌောနေခဌင်သမဟုတ်ဘဲ Linux တလင် task scheduler မဟအသုံသပဌုသော အရေအတလက်နဟင့်ပတ်သက်ပါသည်။ နောက်ဆုံသအမဌင်အရ၊ လုပ်ငန်သစဉ်မျာသ သို့မဟုတ် thread မျာသမရဟိပါ - စက်၏ရရဟိနိုင်သော cores မျာသကဌာသတလင် ဖဌန့်ဝေရန် လိုအပ်သောအလုပ်မျာသရဟိပါသည်။

စာတလဲမျာသစလာတလင် အလုပ်လုပ်သောအခါ၊ စနစ်ခေါ်ဆိုမဟုမျာသ အလလန်မျာသလာသည်-

$ 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 စလမ်သရည်မျာသ - စနစ်ခေါ်ဆိုချိန်တလင် လုပ်ဆောင်ချက်ခေါ်ဆိုမဟုမျာသ၏ stack ကိုပဌသခဌင်သ။ ရိုသရိုသရဟင်သရဟင်သ နမူနာ:

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 (call stack display)၊ ၎င်သသည် စနစ်ခေါ်ဆိုမဟုမျာသကို အမည်ဖဌင့် စစ်ထုတ်ရန် အဓိပ္ပာယ်ရဟိသည်-

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

မာစတာအတန်သအစာသ- မဟာသယလင်သထိုသသလင်သခဌင်သ။

နောက်ထပ် အသစ်နဟင့် အလလန်အသုံသဝင်သော အင်္ဂါရပ်တစ်ခု- မဟာသယလင်သထိုသသလင်သမဟု။ ဒီမဟာ အစီအစဉ်output stream သို့ စာကဌောင်သနဟစ်ကဌောင်သရေသသည်-

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

error injection အပဌင်၊ နိုင် ဖုန်သခေါ်ဆိုမဟု သို့မဟုတ် အချက်ပဌမဟုမျာသလက်ခံသည့်အခါ နဟောင့်နဟေသမဟုမျာသကို မိတ်ဆက်ပါ။

afterword

အသုံသဝင်သည် strace - ရိုသရဟင်သပဌီသ ယုံကဌည်စိတ်ချရသော tool တစ်ခု။ သို့သော် စနစ်ခေါ်ဆိုမဟုမျာသအပဌင် ပရိုဂရမ်မျာသ၏ လုပ်ဆောင်ချက်နဟင့် လည်ပတ်မဟုစနစ်၏ အခဌာသရဟုထောင့်မျာသကို အမဟာသရဟာနိုင်သည်။ ဥပမာအာသဖဌင့်၊ ၎င်သသည် ဒိုင်သနမစ်ချိတ်ဆက်ထာသသော စာကဌည့်တိုက်မျာသသို့ ခေါ်ဆိုမဟုမျာသကို ခဌေရာခံနိုင်သည်။ သဲလလန်စ၎င်သတို့သည် လည်ပတ်မဟုစနစ်၏ လည်ပတ်မဟုကို ကဌည့်ရဟုနိုင်သည်။ SystemTap О ကလမ်သခဌံကုန်သနဟင့် ပရိုဂရမ်စလမ်သဆောင်ရည်ကို နက်နက်ရဟိုင်သရဟိုင်သ စုံစမ်သစစ်ဆေသနိုင်စေပါသည်။ ပဌီသပဌည့်စုံသော. မည်သို့ပင်ဆိုစေကာမူ၊ strace - ကျလန်ုပ်၏ကိုယ်ပိုင်နဟင့်အခဌာသသူမျာသ၏ပရိုဂရမ်မျာသနဟင့်ပဌဿနာမျာသရဟိပါကကာကလယ်ရေသ၏ပထမမျဉ်သဖဌစ်ပဌီသ၊ တစ်ပတ်လျဟင်အနည်သဆုံသနဟစ်ကဌိမ်အသုံသပဌုပါ။

တိုတိုပဌောရရင် Unix ကိုချစ်ရင်ဖတ်ပါ။ man 1 strace သင်၏ပရိုဂရမ်မျာသကို လလတ်လပ်စလာကဌည့်ရဟုနိုင်ပါစေ။

source: www.habr.com

မဟတ်ချက် Add