Bagikan melalui


Melacak Hog Prosesor

Jika satu aplikasi mengonsumsi ("hogging") semua perhatian prosesor, proses lain akan berakhir "kelaparan" dan tidak dapat berjalan.

Gunakan prosedur berikut untuk memperbaiki bug semacam ini.

Men-debug aplikasi yang menggunakan semua siklus CPU

  1. Identifikasi aplikasi mana yang menyebabkan masalah ini: Gunakan Task Manager atau Perfmon untuk menemukan proses mana yang menggunakan 99% atau 100% dari siklus prosesor. Ini mungkin memberi tahu Anda utas yang menyinggung juga.

  2. Lampirkan WinDbg, KD, atau CDB ke proses ini.

  3. Identifikasi utas mana yang menyebabkan masalah: Memecah ke dalam aplikasi yang menyinggung. Gunakan ekstensi !runaway 3 untuk mengambil "rekam jepret" tempat semua waktu CPU berlangsung. Gunakan g (Go) dan tunggu beberapa detik. Kemudian break in dan gunakan !runaway 3 lagi.

    0:002> !runaway 3
     User Mode Time
     Thread    Time
     4e0        0:12:16.0312
     268        0:00:00.0000
     22c        0:00:00.0000
     Kernel Mode Time
     Thread    Time
     4e0        0:00:05.0312
     268        0:00:00.0000
     22c        0:00:00.0000
    
    0:002> g
    
    0:001> !runaway 3
     User Mode Time
     Thread    Time
     4e0        0:12:37.0609
     3d4        0:00:00.0000
     22c        0:00:00.0000
     Kernel Mode Time
     Thread    Time
     4e0        0:00:07.0421
     3d4        0:00:00.0000
     22c        0:00:00.0000
    

    Bandingkan dua set angka dan cari utas yang waktu mode pengguna atau waktu mode kernelnya telah meningkat paling banyak. Karena !runaway mengurutkan berdasarkan waktu CPU menurun, utas yang menyinggung biasanya adalah yang ada di bagian atas daftar. Dalam hal ini, utas 0x4E0 menyebabkan masalah.

  4. Gunakan perintah ~ (Status Utas) dan ~s (Atur Alur Saat Ini) untuk menjadikannya utas saat ini:

    0:001> ~
       0  Id: 3f4.3d4 Suspend: 1 Teb: 7ffde000 Unfrozen
    .  1  Id: 3f4.22c Suspend: 1 Teb: 7ffdd000 Unfrozen
     2  Id: 3f4.4e0 Suspend: 1 Teb: 7ffdc000 Unfrozen
    
    0:001> ~2s
    
  5. Gunakan kb (Display Stack Backtrace) untuk mendapatkan jejak tumpukan utas ini:

    0:002> kb
    FramePtr  RetAddr   Param1   Param2   Param3   Function Name
    0b4ffc74  77f6c600  000000c8.00000000 77fa5ad0 BuggyProgram!CreateMsgFile+0x1b
    0b4ffce4  01836060  0184f440 00000001 0b4ffe20 BuggyProgram!OpenDestFileStream+0xb3
    0b4ffd20  01843eba  02b5b920 00000102 02b1e0e0 BuggyProgram!SaveMsgToDestFolder+0xb3
    0b4ffe20  01855924  0b4ffef0 00145970 0b4ffef0 BuggyProgram!DispatchToConn+0xa4
    0b4ffe5c  77e112e6  01843e16 0b4ffef0 0b4fff34 RPCRT4!DispatchToStubInC+0x34
    0b4ffeb0  77e11215  0b4ffef0 00000000 0b4fff34 RPCRT4!?DispatchToStubWorker@RPC_INTERFACE@@AAEJPAU_RPC_MESSAGE@@IPAJ@Z+0xb0
    0b4ffed0  77e1a3b1  0b4ffef0 00000000 0b4fff34 RPCRT4!?DispatchToStub@RPC_INTERFACE@@QAEJPAU_RPC_MESSAGE@Z+0x41
    0b4fff40  77e181e4  02b1e0b0 00000074 0b4fff90 RPCRT4!?ReceiveOriginalCall@OSF_SCONNECTION@Z+0x14b
    0b4fff60  77e1a5df  02b1e0b0 00000074 00149210 RPCRT4!?DispatchPacket@OSF_SCONNECTION@+0x91
    0b4fff90  77e1ac1c  77e15eaf 00149210 0b4fffec RPCRT4!?ReceiveLotsaCalls@OSF_ADDRESS@@QAEXXZ+0x76
    
  6. Atur titik henti pada alamat pengembalian fungsi yang sedang berjalan. Dalam hal ini, alamat pengembalian ditampilkan pada baris pertama sebagai 0x77F6C600. Alamat pengembalian setara dengan offset fungsi yang ditunjukkan pada baris kedua (BuggyProgram! OpenDestFileStream+0xB3). Jika tidak ada simbol yang tersedia untuk aplikasi, nama fungsi mungkin tidak muncul. Gunakan perintah g (Go) untuk mengeksekusi hingga alamat pengembalian ini tercapai, menggunakan alamat simbolis atau heksadesimal:

    0:002> g BuggyProgram!OpenDestFileStream+0xb3
    
  7. Jika titik henti ini tertembak, ulangi prosesnya. Misalnya, misalkan titik henti ini terpukul. Langkah-langkah berikut harus diambil:

    0:002> kb
    FramePtr  RetAddr   Param1   Param2   Param3   Function Name
    0b4ffce4  01836060  0184f440 00000001 0b4ffe20 BuggyProgram!OpenDestFileStream+0xb3
    0b4ffd20  01843eba  02b5b920 00000102 02b1e0e0 BuggyProgram!SaveMsgToDestFolder+0xb3
    0b4ffe20  01855924  0b4ffef0 00145970 0b4ffef0 BuggyProgram!DispatchToConn+0xa4
    0b4ffe5c  77e112e6  01843e16 0b4ffef0 0b4fff34 RPCRT4!DispatchToStubInC+0x34
    0b4ffeb0  77e11215  0b4ffef0 00000000 0b4fff34 RPCRT4!?DispatchToStubWorker@RPC_INTERFACE@@AAEJPAU_RPC_MESSAGE@@IPAJ@Z+0xb0
    0b4ffed0  77e1a3b1  0b4ffef0 00000000 0b4fff34 RPCRT4!?DispatchToStub@RPC_INTERFACE@@QAEJPAU_RPC_MESSAGE@Z+0x41
    0b4fff40  77e181e4  02b1e0b0 00000074 0b4fff90 RPCRT4!?ReceiveOriginalCall@OSF_SCONNECTION@Z+0x14b
    0b4fff60  77e1a5df  02b1e0b0 00000074 00149210 RPCRT4!?DispatchPacket@OSF_SCONNECTION@+0x91
    0b4fff90  77e1ac1c  77e15eaf 00149210 0b4fffec RPCRT4!?ReceiveLotsaCalls@OSF_ADDRESS@@QAEXXZ+0x76
    
    0:002> g BuggyProgram!SaveMsgToDestFolder+0xb3
    

    Jika ini terpukul, lanjutkan dengan:

    0:002> kb
    FramePtr  RetAddr   Param1   Param2   Param3   Function Name
    0b4ffd20  01843eba  02b5b920 00000102 02b1e0e0 BuggyProgram!SaveMsgToDestFolder+0xb3
    0b4ffe20  01855924  0b4ffef0 00145970 0b4ffef0 BuggyProgram!DispatchToConn+0xa4
    0b4ffe5c  77e112e6  01843e16 0b4ffef0 0b4fff34 RPCRT4!DispatchToStubInC+0x34
    0b4ffeb0  77e11215  0b4ffef0 00000000 0b4fff34 RPCRT4!?DispatchToStubWorker@RPC_INTERFACE@@AAEJPAU_RPC_MESSAGE@@IPAJ@Z+0xb0
    0b4ffed0  77e1a3b1  0b4ffef0 00000000 0b4fff34 RPCRT4!?DispatchToStub@RPC_INTERFACE@@QAEJPAU_RPC_MESSAGE@Z+0x41
    0b4fff40  77e181e4  02b1e0b0 00000074 0b4fff90 RPCRT4!?ReceiveOriginalCall@OSF_SCONNECTION@Z+0x14b
    0b4fff60  77e1a5df  02b1e0b0 00000074 00149210 RPCRT4!?DispatchPacket@OSF_SCONNECTION@+0x91
    0b4fff90  77e1ac1c  77e15eaf 00149210 0b4fffec RPCRT4!?ReceiveLotsaCalls@OSF_ADDRESS@@QAEXXZ+0x76
    
    0:002> g BuggyProgram!DispatchToConn+0xa4
    
  8. Akhirnya Anda akan menemukan titik henti yang tidak terpukul. Dalam hal ini, Anda harus berasumsi bahwa perintah g terakhir menetapkan target yang berjalan dan tidak rusak. Ini berarti bahwa fungsi SaveMsgToDestFolder() tidak akan pernah kembali.

  9. Masuk ke utas lagi dan atur titik henti pada BuggyProgram! SaveMsgToDestFolder+0xB3 dengan perintah bp (Set Breakpoint). Kemudian gunakan perintah g berulang kali. Jika titik henti ini segera mengenai, terlepas dari berapa kali Anda telah menjalankan target, sangat mungkin Anda telah mengidentifikasi fungsi yang menyinggung:

    0:002> bp BuggyProgram!SaveMsgToDestFolder+0xb3
    
    0:002> g 
    
    0:002> g 
    
  10. Gunakan perintah p (Langkah) untuk melanjutkan melalui fungsi hingga Anda mengidentifikasi tempat urutan instruksi perulangan berada. Anda kemudian dapat menganalisis kode sumber aplikasi untuk mengidentifikasi penyebab utas berputar. Penyebabnya biasanya akan menjadi masalah dalam logika sementara waktu, do-while, goto, atau untuk perulangan.