Bagikan melalui


Tips untuk melakukan debug utas

Artikel ini menyediakan informasi bermanfaat untuk melakukan debugging pada utas, termasuk informasi tentang pengaturan nama utas untuk kode natif dan terkelola.

Tips C/C++

Berikut adalah beberapa tips yang dapat Anda gunakan saat melakukan debugging pada utas dalam kode asli:

  • Anda dapat melihat konten Blok Informasi Utas dengan mengetik @TIB di jendela Pemantauan atau kotak dialog QuickWatch.

  • Anda dapat melihat kode kesalahan terakhir untuk utas saat ini dengan memasukkan @Err di jendela Pengawasan atau kotak dialog QuickWatch .

  • Fungsi C Run-Time Libraries (CRT) dapat berguna untuk men-debug aplikasi multithreaded. Untuk informasi selengkapnya, lihat _malloc_dbg.

Mengatur nama utas di C/C++

Penamaan utas dapat dilakukan dalam edisi Visual Studio apa pun. Penamaan utas berguna untuk mengidentifikasi utas yang menarik di jendela Utas saat men-debug proses yang sedang berjalan. Memiliki utas bernama yang dikenali juga dapat membantu saat melakukan debugging pasca-mortem melalui inspeksi crash dump dan saat menganalisis pengambilan performa menggunakan berbagai alat.

Cara mengatur nama utas

Ada dua cara untuk mengatur nama utas. Yang pertama adalah melalui fungsi SetThreadDescription . Yang kedua adalah dengan melemparkan pengecualian tertentu saat debugger Visual Studio dilampirkan ke proses. Setiap pendekatan memiliki manfaat dan peringatan. Penggunaan SetThreadDescription didukung mulai windows 10 versi 1607 atau Windows Server 2016.

Perlu dicatat bahwa kedua pendekatan dapat digunakan bersama-sama, jika diinginkan, karena mekanisme tempat mereka bekerja independen satu sama lain.

Mengatur nama utas dengan menggunakan SetThreadDescription

Keuntungan:

  • Nama utas terlihat saat debugging di Visual Studio, terlepas dari apakah debugger dilampirkan ke proses pada saat SetThreadDescription diaktifkan atau tidak.
  • Nama utas terlihat saat melakukan debugging pasca-mortem dengan memuat crash dump di Visual Studio.
  • Nama utas juga terlihat saat menggunakan alat lain, seperti debugger WinDbg dan penganalisis performa Windows Performance Analyzer .

Peringatan:

  • Nama benang hanya terlihat di Visual Studio 2017 versi 15.6 dan versi terbaru.
  • Ketika melakukan debugging post-mortem pada file dump crash, nama thread hanya terlihat jika crash tersebut dibuat pada Windows 10 versi 1607, Windows Server 2016, atau versi Windows yang lebih baru dari itu.

Example:

#include <windows.h>
#include <processthreadsapi.h>

int main()
{
    HRESULT r;
    r = SetThreadDescription(
        GetCurrentThread(),
        L"ThisIsMyThreadName!"
    );

    return 0;
}

Mengatur nama utas dengan melemparkan pengecualian

Cara lain untuk mengatur nama utas dalam program Anda adalah dengan mengomunikasikan nama utas yang diinginkan ke debugger Visual Studio dengan memberikan pengecualian yang dikonfigurasi secara khusus.

Keuntungan:

  • Berfungsi di semua versi Visual Studio.

Peringatan:

  • Hanya berfungsi jika debugger dilampirkan pada saat metode berbasis pengecualian digunakan.
  • Nama utas yang ditetapkan dengan menggunakan metode ini tidak akan tersedia di dump atau alat analisis performa.

Example:

Fungsi yang SetThreadName ditunjukkan di bawah ini menunjukkan pendekatan berbasis pengecualian ini. Perhatikan bahwa nama utas akan secara otomatis disalin ke dalam utas, sehingga memori untuk parameter threadName dapat dilepaskan setelah panggilan SetThreadName selesai.

//
// Usage: SetThreadName ((DWORD)-1, "MainThread");
//
#include <windows.h>
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
    DWORD dwType; // Must be 0x1000.
    LPCSTR szName; // Pointer to name (in user addr space).
    DWORD dwThreadID; // Thread ID (-1=caller thread).
    DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName(DWORD dwThreadID, const char* threadName) {
    THREADNAME_INFO info;
    info.dwType = 0x1000;
    info.szName = threadName;
    info.dwThreadID = dwThreadID;
    info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable: 6320 6322)
    __try{
        RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
    }
    __except (EXCEPTION_EXECUTE_HANDLER){
    }
#pragma warning(pop)
}

Mengatur nama utas dalam kode terkelola

Penamaan utas dimungkinkan dalam edisi Visual Studio apa pun. Penamaan utas penting untuk memantau utas di jendela Utas.

Untuk mengatur nama utas dalam kode terkelola, gunakan properti Name.

Example

public class Needle
{
    // This method will be called when the thread is started.
    public void Baz()
    {
        Console.WriteLine("Needle Baz is running on another thread");
    }
}

public void Main()
{
    Console.WriteLine("Thread Simple Sample");
    Needle oNeedle = new Needle();
    // Create a Thread object.
    System.Threading.Thread oThread = new System.Threading.Thread(oNeedle.Baz);
    // Set the Thread name to "MyThread".
    oThread.Name = "MyThread";
    // Starting the thread invokes the ThreadStart delegate
    oThread.Start();
}