ฉันมีสองกระบวนการที่กินเวลา CPU ของระบบมาก (ตามที่พิจารณาโดยดูที่ vmstat) มีวิธีง่าย ๆ ในการค้นหาชนิดของการเรียกระบบหรือไม่?
ฉันรู้ว่ามี strace แต่มีวิธีที่เร็วและง่ายขึ้นหรือไม่ มีบางอย่างเช่น "top" สำหรับการโทรของระบบหรือไม่?
ฉันมีสองกระบวนการที่กินเวลา CPU ของระบบมาก (ตามที่พิจารณาโดยดูที่ vmstat) มีวิธีง่าย ๆ ในการค้นหาชนิดของการเรียกระบบหรือไม่?
ฉันรู้ว่ามี strace แต่มีวิธีที่เร็วและง่ายขึ้นหรือไม่ มีบางอย่างเช่น "top" สำหรับการโทรของระบบหรือไม่?
คำตอบ:
ฉันคิดว่า strace กับ-c
ธงน่าจะใกล้เคียงที่สุดที่ฉันรู้ หากคุณไม่ได้ใช้-c
แฟล็กลอง:
$ sudo strace -c -p 12345
โดยที่ 12345 คือ ID กระบวนการ (PID) ของกระบวนการที่เป็นปัญหา โปรดทราบว่าการบีบอัดกระบวนการเพิ่มค่าใช้จ่ายเพิ่มเติมดังนั้นในขณะที่คุณติดตามกระบวนการจะทำงานช้าลง
หลังจากรันสิ่งนั้นเป็นเวลานานที่คุณต้องการรวบรวมข้อมูลกดCtrl-C
เพื่อหยุดการรวบรวมข้อมูลของคุณและส่งออกผลลัพธ์ มันจะสร้างสิ่งนี้:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
31.88 0.001738 145 12 futex
16.79 0.000915 11 80 tgkill
12.36 0.000674 34 20 read
9.76 0.000532 266 2 statfs
8.42 0.000459 13 35 time
4.38 0.000239 6 40 gettimeofday
3.65 0.000199 4 48 sigprocmask
2.94 0.000160 18 9 open
2.88 0.000157 12 13 stat64
1.32 0.000072 9 8 munmap
0.90 0.000049 6 8 mmap2
0.88 0.000048 3 14 7 sigreturn
0.79 0.000043 5 9 close
0.77 0.000042 4 10 rt_sigprocmask
0.64 0.000035 3 12 setitimer
0.55 0.000030 5 6 6 rt_sigsuspend
0.53 0.000029 4 8 fstat64
0.29 0.000016 8 2 setresuid32
0.13 0.000007 4 2 _llseek
0.09 0.000005 3 2 prctl
0.04 0.000002 2 1 geteuid32
------ ----------- ----------- --------- --------- ----------------
100.00 0.005451 341 13 total
อย่างที่คุณเห็นนี่เป็นรายละเอียดของการเรียกใช้ระบบทั้งหมดที่ทำโดยแอพพลิเคชั่นเรียงตามเวลาทั้งหมดและรวมเวลาเฉลี่ยต่อการโทรและจำนวนการโทรสำหรับแต่ละ syscall หากคุณต้องการจัดเรียงต่างกันให้ดูหน้า man สำหรับ strace เนื่องจากมีตัวเลือกสองทาง
อาจลองใช้หนึ่งในโปรไฟล์การสุ่มตัวอย่างเช่น oprofile หรือเมล็ดที่ใหม่กว่า หากคุณโชคดี "perf top" อาจบอกคุณได้อย่างแม่นยำในสิ่งที่คุณต้องการ ดูที่นี่สำหรับตัวอย่าง
ชนิดของสวิตช์ strace ที่ฉันมักจะใช้คือ
strace -ffttT -p pid -o /tmp/strace.out
ตัวอย่างนี้จะดูเหมือน
19:35:57.485493 mprotect(0x7f35e7472000, 16384, PROT_READ) = 0 <0.000037>
19:35:57.485599 mprotect(0x7f35e7692000, 4096, PROT_READ) = 0 <0.000030>
19:35:57.485697 mprotect(0x7f35e78b7000, 4096, PROT_READ) = 0 <0.000030>
19:35:57.485782 munmap(0x7f35e7896000, 129588) = 0 <0.000037>
19:35:57.485875 set_tid_address(0x7f35e78949d0) = 10730 <0.000029>
19:35:57.485960 set_robust_list(0x7f35e78949e0, 0x18) = 0 <0.000024>
19:35:57.486048 futex(0x7fff8f58628c, FUTEX_WAKE_PRIVATE, 1) = 0 <0.000025>
19:35:57.486131 futex(0x7fff8f58628c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, NULL, 7f35e7894700) = -1 EAGAIN (Resource temporarily unavailable) <0.000024>
คุณเห็นความแตกต่างของเวลาที่ด้านขวามือของการโทรของระบบแสดงเวลาที่ใช้ในการเปลี่ยนจากการโทรของระบบหนึ่งไปยังอีกระบบหนึ่ง
มันจะจับคุณแตกต่างของเวลาระหว่างระบบโทร ดังนั้นเมื่อคุณเห็นว่าการโทรของระบบมีช่องว่างค่อนข้างน้อยในการโทรของระบบครั้งถัดไปดังนั้นจะมีเสียงดัง
อีกวิธีคือการ coredump ด้วย gcore อย่างไรก็ตามนั่นต้องใช้ประสบการณ์เล็กน้อยในการนำทางผ่าน gdb
แต่ถ้าเธรดนั้นเป็นเคอร์เนลเธรดคุณจะไม่สามารถ strace หรือ coredump ได้ ในกรณีนี้เราต้องใช้อะไรที่ซับซ้อนกว่านี้ ในเคอร์เนล RHEL5 เราใช้ oprofile ใน RHEL6 เราใช้ perf ฉันชอบความสมบูรณ์แบบมากกว่า oprofile ข้อมูลที่สมบูรณ์สามารถรวบรวมได้ด้วยกราฟเช่นรูปแบบที่แสดงการเรียกใช้ระบบซึ่งมีการใช้เปอร์เซ็นต์สูงสุดของ CPU
ด้วยการทดสอบที่สมบูรณ์แบบฉันเห็นสิ่งนี้
38.06% swapper [kernel.kallsyms] [k] mwait_idle_with_hints ↑
29.45% swapper [kernel.kallsyms] [k] read_hpet
4.90% swapper [kernel.kallsyms] [k] acpi_os_read_port ▒
4.74% swapper [kernel.kallsyms] [k] hpet_next_event
มันแสดงฟังก์ชั่นเคอร์เนลที่ใช้เวลา CPU 38% ตอนนี้เราสามารถตรวจสอบฟังก์ชั่นและดูว่ามันกำลังทำอะไรและมันควรจะทำอะไร
ด้วยตัวอย่างเล็ก ๆ น้อย ๆ มันไม่ยากเท่าไหร่