Aracılığıyla paylaş


DTrace ETW

Mevcut ETW olaylarını işlemek ve yeni ETW olayları eklemek için Windows için DTrace kullanın.

Windows için Olay İzleme (ETW), çekirdek veya uygulama tanımlı olayları bir günlük dosyasına kaydetmenizi sağlayan çekirdek düzeyinde bir izleme tesisidir. Olayları gerçek zamanlı olarak veya bir günlük dosyasından kullanabilir ve bir uygulamada hata ayıklamak veya uygulamada performans sorunlarının nerede oluştuğunu belirlemek için kullanabilirsiniz. ETW hakkında genel bilgi için bkz. Olay İzleme Hakkında.

Uyarı

DTrace, Sürüm 18980 ve Windows Server Derlemesi 18975'in ardından Windows'un Insider derlemelerinde desteklenir.

Windows üzerinde DTrace ile çalışma hakkında genel bilgi için bkz. DTrace.

ETW Windows DTrace Sağlayıcısı

İz günlüğüne kaydedilen ve manifesto tabanlı ETW olaylarını yakalamak ve raporlamak için DTrace kullanabilirsiniz. Belirli anahtar sözcükleri/düzeyleri/eventID'leri araştırmak için, joker karakter kullanmazsanız ETW yoklamaları çok daha güvenilir bir şekilde çalışır. Bunun yerine yoklamanızı şu kurallara göre tam olarak belirtin:

Probename = etw

Modname = Tüm küçük harf karakterlerini kullanarak xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx biçiminde sağlanan GUID.

Funcname = 0x00_0x0000000000000000 biçimindeki Level_Keyword. Her şeyi eşleştirmek için bu, 0xff_0xffffffffffffffff olarak ayarlanmalıdır.

Probename = Tamsayı Etkinlik Kimliği veya "generic_event" ile tüm olay kimlikleri eşleşir.

Probename'e göre filtreleme yalnızca manifest olunan olaylar için çalışır. İzlenmiş olaylar için joker karakter (*) kullanın.

ETW yüküne arg0 üzerinden erişilir. Bu, nt'_EVENT_HEADER ve ardından olaya özgü tarihten oluşur.

Kullanılabilir ETW sağlayıcılarını belirleme

Etkin ETW sağlayıcılarını ve sağlayıcı GUID'lerini görüntülemek için logman komutunu kullanın.

C:\>logman query providers
...
Microsoft-Windows-Kernel-Memory {D1D93EF7-E1F2-4F45-9943-03D245FE6C00}
Microsoft-Windows-Kernel-Network {7DD42A49-5329-4832-8DFD-43D979153A88}
Microsoft-Windows-Kernel-PnP {9C205A39-1250-487D-ABD7-E831C6290539}
Microsoft-Windows-Kernel-Power {331C3B3A-2005-44C2-AC5E-77220C37D6B4}
Microsoft-Windows-Kernel-Prefetch {5322D61A-9EFA-4BC3-A3F9-14BE95C144F8}
Microsoft-Windows-Kernel-Process {22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}
...

Mevcut ETW sağlayıcısı bilgilerini görüntüleme

DTrace, ETW olaylarını çıktı olarak verebilme yeteneğine sahiptir. Bu, raporlamak, toplamak ve analiz etmek için mevcut ETW işlem hattının bulunduğu senaryolar için yararlıdır.

Microsoft-Windows-Kernel-Memory sağlayıcı olaylarını raporlamak için bu örnek DTrace komutunu kullanın.

C:\>dtrace -n "etw:d1d93ef7-e1f2-4f45-9943-03d245fe6c00:0xff_0xffffffffffffffff:12"
dtrace: description 'etw:d1d93ef7-e1f2-4f45-9943-03d245fe6c00:0xff_0xffffffffffffffff:12' matched 1 probe
CPU     ID                    FUNCTION:NAME
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12
  0   3271       0xff_0xffffffffffffffff:12

Yeni ETW olayları ekleme

etw izleme olayları, etw_trace makro çağrılarak oluşturulabilir. Olaylar yalnızca belirtilen izleme sağlayıcısı için etkin bir dinleyici varsa günlüğe kaydedilir, aksi takdirde bunlar atlanır.

etw_trace makro, int8, uint8, int16, uint16, int32, uint32, int64, uint64, hexint32, hexint64 ve string gibi temel veri türlerini destekler. Daha fazla ayrıntı için aşağıdaki Desteklenen ETW veri türleri tablosuna bakın.

Örnek ETW_TRACE makrosu:

Sistem çağrısı rutini 0xc0000001 - STATUS_UNSUCCESSFUL döndüğünde bu betik özel bir ETW olayı oluşturur.

this->status değerini, farklı syscall dönüş değerlerini kaydetmek için farklı NTSTATUS değerleri kullanacak şekilde değiştirebilirsiniz.

syscall:::return 
{ 
	this->status = (uint32_t) arg0;

	if (this->status == 0xc0000001UL) 
	{ 
		etw_trace
		(
    		"Tools.DTrace.Platform", /* Provider Name */
   	 		"AAD330CC-4BB9-588A-B252-08276853AF02", /* Provider GUID */
    		"My custom event from DTrace", /* Event Name */
    		1, /* Event Level (0 - 5) */
    		0x0000000000000020, /* Flag */
    		"etw_int32", /* Field_1 Name */
    		"PID",/* Field_1 Type */
     		(int32_t)pid, /* Field_1 Value  */
     		"etw_string", /* Field_2 Name */
     		"Execname", /* Field_2 type */
      		execname, /* Field_2 Value */
     		"etw_string", /* Field_3 Name */
     		"Probefunc", /* Field_3 type */
      		probefunc /* Field_3 Value */   
			);
	}
}
C:\> dtrace -s addnewetwevent.d
dtrace: script 'addnewetwevent.d' matched 1881 probes
CPU     ID                    FUNCTION:NAME
  0     93 NtAlpcSendWaitReceivePort:return
  0     93 NtAlpcSendWaitReceivePort:return
  0     93 NtAlpcSendWaitReceivePort:return

ETW NUMA MEM İSTATS örnek kodu

Bu örnek betik, NUMA düğüm belleği dökümünü almak için Microsoft-Windows-Kernel-Memory ETW sağlayıcısını kullanır. Sayfa boyutu, 4 ile çarpılarak KB cinsinden boyuta dönüştürülebilir. NUMA hakkında genel bilgi için bkz. NUMA Desteği.

Bu kod aynı zamanda https://github.com/microsoft/DTrace-on-Windows/blob/windows/samples/windows/etw/numamemstats.d konumlandırılmıştır.

typedef struct KernelMemInfoEvent
{
        struct nt`_EVENT_HEADER _EH;
	uint32_t PartitionId;
	uint32_t Count;
	uint32_t NodeNumber;
}kmi;

typedef struct MemoryNodeInfo
{
	uint64_t TotalPageCount;
	uint64_t SmallFreePageCount;
	uint64_t SmallZeroPageCount;
	uint64_t MediumFreePageCount;
	uint64_t MediumZeroPageCount;
	uint64_t LargeFreePageCount;
	uint64_t LargeZeroPageCount;
	uint64_t HugeFreePageCount;
	uint64_t HugeZeroPageCount;
}m_nodeinfo;

int printcounter;

BEGIN
{
	printcounter = 0;
}

/* MemNodeInfo */
etw:d1d93ef7-e1f2-4f45-9943-03d245fe6c00:0xff_0xffffffffffffffff:12
{
	if (printcounter%10 == 0)
	{
		printf ("\n \n");
		printf("Partition ID: %d \n",((kmi *)arg0)->PartitionId);
		printf("Count: %d \n", ((kmi *)arg0)->Count);
		
		printf("Node number: %d\n", ((kmi *)arg0)->NodeNumber);
		counters = (m_nodeinfo*)(arg0 + sizeof(struct nt`_EVENT_HEADER) + 12);
		print(*counters);

		/* Dump rest of the NUMA node info */

		if (((kmi *)arg0)->Count > 1)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(1)) + (sizeof(uint32_t)*(1)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(1)) + (sizeof(uint32_t)*(1)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 2)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(2)) + (sizeof(uint32_t)*(2)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(2)) + (sizeof(uint32_t)*(2)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 3)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(3)) + (sizeof(uint32_t)*(3)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(3)) + (sizeof(uint32_t)*(3)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 4)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(4)) + (sizeof(uint32_t)*(4)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(4)) + (sizeof(uint32_t)*(4)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 5)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(5)) + (sizeof(uint32_t)*(5)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(5)) + (sizeof(uint32_t)*(5)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 6)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(6)) + (sizeof(uint32_t)*(6)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(6)) + (sizeof(uint32_t)*(6)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 7)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(7)) + (sizeof(uint32_t)*(7)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(7)) + (sizeof(uint32_t)*(7)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 8)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(8)) + (sizeof(uint32_t)*(8)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(8)) + (sizeof(uint32_t)*(8)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 9)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(9)) + (sizeof(uint32_t)*(9)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(9)) + (sizeof(uint32_t)*(9)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 10)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(10)) + (sizeof(uint32_t)*(10)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(10)) + (sizeof(uint32_t)*(10)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 11)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(11)) + (sizeof(uint32_t)*(11)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(11)) + (sizeof(uint32_t)*(11)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 12)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(12)) + (sizeof(uint32_t)*(12)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(12)) + (sizeof(uint32_t)*(12)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 13)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(13)) + (sizeof(uint32_t)*(13)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(13)) + (sizeof(uint32_t)*(13)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 14)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(14)) + (sizeof(uint32_t)*(14)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(14)) + (sizeof(uint32_t)*(14)) + sizeof(uint32_t));
			print(*counters);
		}
		if (((kmi *)arg0)->Count > 15)
		{
			nodenumber = (uint32_t *) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(15)) + (sizeof(uint32_t)*(15)) );
			printf ("Node Number: %d \n", *nodenumber);
			counters = (m_nodeinfo*) (arg0 + sizeof(struct nt`_EVENT_HEADER) + 8 + (sizeof(m_nodeinfo)*(15)) + (sizeof(uint32_t)*(15)) + sizeof(uint32_t));
			print(*counters);
		}

	}
	exit(1);
	printcounter++;
}

Dosyayı etwnumamemstats.d olarak kaydedin

Yönetici olarak bir komut istemi açın ve -s seçeneğini kullanarak betiği çalıştırın.

Bir istemci Windows bilgisayarında çalışan bir uygulama veya işlem, tek bir NUMA düğümünü görüntüler.

C:\> dtrace -s etwnumamemstats.d
trace: script 'etwnumamemstats.d' matched 36 probes
CPU     ID                    FUNCTION:NAME
  0  42735       0xff_0xffffffffffffffff:12

Partition ID: 0
Count: 1
Node number: 1
m_nodeinfo {
    uint64_t TotalPageCount = 0xab98d
    uint64_t SmallFreePageCount = 0
    uint64_t SmallZeroPageCount = 0x1bec
    uint64_t MediumFreePageCount = 0
    uint64_t MediumZeroPageCount = 0x5a
    uint64_t LargeFreePageCount = 0
    uint64_t LargeZeroPageCount = 0
    uint64_t HugeFreePageCount = 0
    uint64_t HugeZeroPageCount = 0
}
  0  42735       0xff_0xffffffffffffffff:12

Desteklenen ETW veri türleri

ETW türü D Dili veri türü Notlar
etw_struct Integer Bu türdeki yük değeri, yeni bir yapının sahip olacağı üye sayısını temsil eder.
etw_string String Mevcut Değil
etw_mbcsstring String Mevcut Değil
etw_int8 Integer Tür boyutunun uyuşması gerekir ve D betiğinde 'int8_t' olarak dönüştürme yapılması tavsiye edilir.
etw_uint8 Integer Tip boyutu uyumlu olmalıdır ve D betiğinde 'uint8_t' olarak atama yapılması tavsiye edilir.
etw_int16 Integer Tip boyutu uyumlu olmalıdır ve D dilinde 'int16_t' olarak atama yapılması tavsiye edilir.
etw_uint16 Integer Tür boyutu eşleşmelidir ve D betiğinde 'uint16_t' olarak atama yapılması tavsiye edilir
etw_int32 Integer Mevcut Değil
etw_uint32 Integer Mevcut Değil
etw_int64 Integer D varsayılan olarak 'int32_t' olduğundan tür açıkça 'int64_t' olmalıdır
etw_uint64 Integer D varsayılan olarak 'int32_t' olduğundan tür açıkça 'int64_t' olmalıdır
etw_float Skaler Kayan nokta sabitlerine D betiğinde izin verilmez, ancak yüklenen sembollerde izin verir
etw_double Skaler Kayan nokta sabitlerine D betiğinde izin verilmez, ancak yüklenen sembollerde izin verir
etw_bool32 Integer Mevcut Değil
etw_hexint32 Integer Mevcut Değil
etw_hexint64 Integer D varsayılan olarak 'int32_t' olduğundan tür açıkça 'int64_t' olmalıdır
etw_countedmbcsstring Integer Mevcut Değil
etw_intptr Integer Veri türü boyutu mimariye göre değişir ('int32_t' ile 'int64_t' karşılaştırması)
etw_uintptr Integer Veri türü boyutu mimariye göre değişir ('int32_t' ile 'int64_t' karşılaştırması)
etw_pointer Integer Veri türü boyutu mimariye göre değişir ('int32_t' ile 'int64_t' karşılaştırması)
etw_char16 Integer Tip boyutu uyumlu olmalı ve D betiğinde `int16_t`'ye dönüştürülmesi tavsiye edilir.
etw_char8 Integer Veri türü boyutu eşleşmelidir ve D betiğinde 'int8_t' olarak dönüştürme yapılması tavsiye edilir.
etw_bool8 Integer Tür boyutu eşleşmelidir ve D betiğinde 'int8_t' olarak atama yapılması tavsiye edilir
etw_hexint8 Integer Tip boyutu eşleşmelidir ve D betiğinde 'int8_t' olarak dönüştürme yapılması tavsiye edilir.
etw_hexint16 Integer Veri türü boyutu eşleşmelidir ve D betiğinde 'int16_t' olarak döndürme yapılması tavsiye edilir.
etw_pid Integer Mevcut Değil
etw_tid Integer Mevcut Değil
etw_mbcsxml Integer Mevcut Değil
etw_mbcsjson Integer Mevcut Değil
etw_countedmbcsxml Integer Mevcut Değil
etw_countedmbcsjson Integer Mevcut Değil
etw_win32error Integer Mevcut Değil
etw_ntstatus Integer Mevcut Değil
etw_hresult Integer Mevcut Değil

Ayrıca Bkz.

Windows'da DTrace

Windows için DTrace Programlaması

DTrace Windows Kod Örnekleri

DTrace Canlı Dökümü