يونڪس جهڙو آپريٽنگ سسٽم ۾، ٻاهرين دنيا ۽ آپريٽنگ سسٽم سان هڪ پروگرام جو ڪميونيڪيشن، ڪم جي هڪ ننڍڙي سيٽ ذريعي ٿئي ٿو - سسٽم ڪالز. هن جو مطلب اهو آهي ته ڊيبگنگ جي مقصدن لاء اهو ڪارائتو ٿي سگهي ٿو جاسوسي ڪرڻ لاء سسٽم ڪالن تي عمل ڪيو پيو وڃي پروسيس ذريعي.
هڪ افاديت توهان کي لينڪس تي پروگرامن جي ”انٽم لائف“ مانيٽر ڪرڻ ۾ مدد ڪري ٿي strace، جيڪو هن مضمون جو موضوع آهي. جاسوسي سامان جي استعمال جا مثال مختصر تاريخ سان گڏ آهن strace ۽ اهڙن پروگرامن جي ڊيزائن جو تفصيل.
يونڪس ۾ پروگرامن ۽ او ايس ڪنيل جي وچ ۾ مکيه انٽرفيس سسٽم ڪالز آهي. سسٽم ڪالون, اسڪيمون)، ٻاهرين دنيا سان پروگرامن جو رابطو خاص طور تي انهن جي ذريعي ٿئي ٿو.
پر يونڪس جي پهرين عوامي ورزن ۾ (نسخو 6 يونڪس, 1975) صارف جي عملن جي رويي کي ٽريڪ ڪرڻ لاء ڪو به آسان طريقا نه هئا. ھن مسئلي کي حل ڪرڻ لاءِ، Bell Labs ايندڙ ورزن ۾ تازه ڪاري ڪندو (نسخو 7 يونڪس، 1979) تجويز ڪيل نئين سسٽم ڪال - ptrace.
ptrace بنيادي طور تي انٽرايڪٽو ڊيبگرز لاءِ ترقي ڪئي وئي، پر 80 جي ڏهاڪي جي آخر تائين (تجارتي دور ۾ سسٽم V رليز 4) هن بنياد تي، تنگ طور تي مرڪوز ڊيبگرز-سسٽم ڪال ٽريڪرز-ظاهر ٿيا ۽ وڏي پيماني تي استعمال ڪيا ويا.
پهرين اسٽريس جو ساڳيو نسخو پال ڪروننبرگ طرفان 1992 ۾ comp.sources.sun ميلنگ لسٽ تي شايع ڪيو ويو هو هڪ بند يوٽيلٽي جي متبادل طور. trace سج کان. ٻئي ڪلون ۽ اصل سنوس لاءِ هئا، پر 1994 تائين strace سسٽم V، سولاريس ۽ وڌندڙ مقبول لينڪس ڏانهن پورٽ ڪيو ويو.
اڄ strace صرف لينڪس کي سپورٽ ڪري ٿو ۽ ساڳئي تي ڀاڙي ٿو ptrace, گھڻن واڌارن سان overgrown.
جديد (۽ تمام سرگرم) سنڀاليندڙ strace - دمتري ليون. هن جي مهرباني، يوٽيلٽي ترقي يافته خاصيتون حاصل ڪيون جهڙوڪ سسٽم ڪالن ۾ غلطي انجڻ، وسيع رينج جي تعمير لاء سپورٽ ۽، سڀ کان اهم، ماسڪوٽ. غير سرڪاري ذريعن جو چوڻ آهي ته چونڊ شتر مرغ تي ٿي، ڇاڪاڻ ته روسي لفظ "ostrich" ۽ انگريزي لفظ "strace" جي وچ ۾ مطابقت جي ڪري.
اهو پڻ اهم آهي ته لينڪس، فري بي ايس ڊي، اوپن بي ايس ڊي ۽ روايتي يونڪس ۾ هڪ ڊگهي تاريخ ۽ عمل جي باوجود، ptrace سسٽم ڪال ۽ ٽريڪرز ڪڏهن به POSIX ۾ شامل نه ڪيا ويا.
اسٽريس ڊيوائس مختصر ۾: Piglet Trace
"توهان کي اهو سمجهڻ جي اميد نه آهي" (ڊينس رچي، ورزن 6 ۾ تبصرو يونڪس سورس ڪوڊ)
ننڍپڻ کان وٺي، مان ڪارو باڪس برداشت نه ٿو ڪري سگهان: مون رانديڪن سان نه کيڏيو، پر انهن جي ساخت کي سمجهڻ جي ڪوشش ڪئي (بالغ لفظ "بروڪ" استعمال ڪيو، پر برائي زبانن تي يقين نه رکو). شايد اهو ئي سبب آهي جو پهريون يونڪس جو غير رسمي ڪلچر ۽ جديد اوپن سورس تحريڪ مون کي تمام گهڻو ويجهو آهي.
هن آرٽيڪل جي مقصدن لاءِ، اسٽريس جي سورس ڪوڊ کي ڌار ڪرڻ غير معقول آهي، جيڪو ڏهاڪن کان وڌي چڪو آهي. پر پڙهندڙن لاءِ ڪو به راز نه ڇڏڻ گهرجي. تنهن ڪري، اهڙن اسٽريس پروگرامن جي آپريشن جا اصول ڏيکارڻ لاءِ، مان هڪ ننڍڙي ٽريڪٽر لاءِ ڪوڊ مهيا ڪندس. سور جو نشان (پي ٽي آر). اها خبر ناهي ته ڪجهه خاص ڪيئن ڪجي، پر بنيادي شيء آهي پروگرام جي سسٽم ڪالز - اهو نڪتو:
Piglet Trace اٽڪل سوين لينڪس سسٽم ڪالن کي سڃاڻي ٿو (ڏسو. ٽيبل) ۽ صرف 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, ®isters) == -1)
err(EXIT_FAILURE, "enter_syscall -> getregs");
/* Note how orig_rax is used here. That's because on x86-64 rax is used
* both for executing a syscall, and returning a value from it. To
* differentiate between the cases both rax and orig_rax are updated on
* syscall entry/exit, and only rax is updated on exit. */
print_syscall_enter(registers.orig_rax);
/* Exit syscall: execute of the syscall, and stop on system
* call exit.
*
* More system call tinkering possible: change the return value, record
* time it took to finish the system call, etc. */
if (ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL) == -1)
err(EXIT_FAILURE, "exit_syscall");
if (waitpid(child_pid, NULL, 0) == -1)
err(EXIT_FAILURE, "exit_syscall -> waitpid");
/* Retrieve register state again as we want to inspect system call
* return value. */
if (ptrace(PTRACE_GETREGS, child_pid, NULL, ®isters) == -1) {
/* ESRCH is returned when a child terminates using a syscall and no
* return value is possible, e.g. as a result of exit(2). */
if (errno == ESRCH) {
fprintf(stderr, "nTracee terminatedn");
break;
}
err(EXIT_FAILURE, "exit_syscall -> getregs");
}
/* Done with this system call, let the next iteration handle the next
* one */
print_syscall_exit(registers.rax);
}
اهو سڄو ٽريڪٽر آهي. هاڻي توهان کي خبر آهي ته ايندڙ پورٽنگ ڪٿي شروع ڪجي ڊي ٽريس لينڪس تي.
بنياديات: هڪ پروگرام هلائڻ وارو اسٽريس
پهرين استعمال جي صورت ۾ strace، شايد اهو آسان طريقو بيان ڪرڻ جي قابل آهي - هڪ ايپليڪيشن کي هلائڻ شروع ڪرڻ strace.
هڪ عام پروگرام جي ڪالن جي لامحدود فهرست ۾ نه وڃڻ لاء، اسان لکندا آهيون گهٽ ۾ گهٽ پروگرام вокруг 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 ۽ سسٽم ڪالن جي گهڻائي جيڪا اسان جي دلچسپي نه آهي.
توهان -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 پرواز تي عمل ۾ شامل ٿي سگھي ٿو.
$ ./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);
}
هتي اصل عمل هڪ ٻار جي عمل کي ٺاهي ٿو، ٻئي معياري پيداوار ڏانهن لکڻ:
پرچم توهان کي سڄي عمل جي وڻ کي ٽريڪ ڪرڻ ۾ مدد ڪري ٿي -f، ڪھڙي strace ٻار جي عملن ۾ سسٽم ڪالن جي نگراني ڪندو آهي. هي پيداوار جي هر قطار ۾ اضافو ڪري ٿو pid پروسيس جيڪو سسٽم آئوٽ ٺاهي ٿو:
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 +++
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);
}
قدرتي طور تي، ان کي لازمي طور تي لنڪر کي خاص سلام سان گڏ ڪيو وڃي - پيٿڊ پرچم:
$ 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 -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، اهي آپريٽنگ سسٽم جي آپريشن ۾ نظر ڪري سگهن ٿا سسٽم ٽيپ и سڌو، ۽ توهان کي پروگرام جي ڪارڪردگي جي تمام گهڻي تحقيق ڪرڻ جي اجازت ڏئي ٿي عجيب. تنهن هوندي به، اهو آهي strace - دفاع جي پهرين لائن منهنجي پنهنجي ۽ ٻين ماڻهن جي پروگرامن سان مسئلن جي صورت ۾، ۽ آئون ان کي هفتي ۾ گهٽ ۾ گهٽ ٻه ڀيرا استعمال ڪريان ٿو.
مختصر ۾، جيڪڏھن توھان يونڪس سان پيار ڪريو، پڙھو man 1 strace ۽ توهان جي پروگرامن کي ڏسڻ لاء آزاد محسوس ڪريو!