Aracılığıyla paylaş


C++ Derleme İçgörüleri SDK’sı

C++ Derleme Analizler SDK'sı Visual Studio 2017 ve sonraki sürümlerle uyumludur. Bu sürümlerin belgelerini görmek için bu makalenin Visual Studio Sürüm seçici denetimini Visual Studio 2017 veya üzeri olarak ayarlayın. Bu sayfadaki içindekiler tablosunun en üstünde bulunur.

C++ Derleme Analizler SDK'sı, C++ Derleme Analizler platformunun üzerinde kişiselleştirilmiş araçlar oluşturmanıza olanak sağlayan bir API koleksiyonudur. Bu sayfa, başlamanıza yardımcı olacak üst düzey bir genel bakış sağlar.

SDK'yi edinme

Şu adımları izleyerek C++ Derleme Analizler SDK'sını NuGet paketi olarak indirebilirsiniz:

  1. Visual Studio 2017 ve üzeri sürümlerde yeni bir C++ projesi oluşturun.
  2. Çözüm Gezgini bölmesinde projenize sağ tıklayın.
  3. Bağlam menüsünden NuGet Paketlerini Yönet'i seçin.
  4. Sağ üst kısımda nuget.org paket kaynağını seçin.
  5. Microsoft.Cpp.Build Analizler paketinin en son sürümünü arayın.
  6. Yükle'yi seçin.
  7. Lisansı kabul edin.

SDK'yi çevreleyen genel kavramlar hakkında bilgi için okumaya devam edin. Sdk kullanan gerçek C++ uygulamalarının örneklerini görmek için resmi C++ Derleme Analizler örnekleri GitHub deposuna da erişebilirsiniz.

İzleme toplama

MSVC araç zincirinden çıkan olayları analiz etmek için C++ Derleme Analizler SDK'sını kullanmak için önce bir izleme toplamanız gerekir. SDK, temel izleme teknolojisi olarak Windows için Olay İzleme 'yi (ETW) kullanır. İzleme toplama işlemi iki yolla yapılabilir:

Yöntem 1: Visual Studio 2019 ve üzerinde vcperf kullanma

  1. VS 2019 için yükseltilmiş bir x64 Yerel Araçlar Komut İstemi açın.

  2. Aşağıdaki konumu çalıştırın: vcperf /start MySessionName

  3. Projenizi derleyin.

  4. Aşağıdaki konumu çalıştırın: vcperf /stopnoanalyze MySessionName outputTraceFile.etl

    Önemli

    /stopnoanalyze vcperf ile izlemenizi durdururken komutunu kullanın. Normal /stop komut tarafından durdurulan izlemeleri analiz etmek için C++ Derleme Analizler SDK'sını kullanamazsınız.

Yöntem 2: program aracılığıyla

İzlemeleri program aracılığıyla başlatmak ve durdurmak için bu C++ Derleme Analizler SDK izleme koleksiyonu işlevlerinden herhangi birini kullanın. Bu işlev çağrılarını yürüten programın yönetici ayrıcalıkları olmalıdır. Yalnızca başlatma ve durdurma izleme işlevleri yönetici ayrıcalıkları gerektirir. C++ Derleme Analizler SDK'sı içindeki diğer tüm işlevler bunlar olmadan yürütülebilir.

İşlev C++ API C API'si
İzleme başlatma StartTracingSession StartTracingSessionA
StartTracingSessionW
İzlemeyi durdurma StopTracingSession StopTracingSessionA
StopTracingSessionW
İzlemeyi durdurma ve
sonucu hemen analiz etme
StopAndAnalyzeTracingSession StopAndAnalyzeTracingSessionA
StopAndAnalyzeTracingSession
İzlemeyi durdurma ve
sonucu hemen yeniden dağıtma
StopAndRelogTracingSession StopAndRelogTracingSessionA
StopAndRelogTracingSessionW

Aşağıdaki bölümlerde, bir analizin veya yeniden dağıtma oturumunun nasıl yapılandırıldığınız gösterilir. StopAndAnalyzeTracingSession gibi birleşik işlevler için gereklidir.

İzleme kullanma

ETW izlemesine sahip olduktan sonra, paketi açmak için C++ Derleme Analizler SDK'sını kullanın. SDK, olayları araçlarınızı hızlı bir şekilde geliştirmenizi sağlayan bir biçimde sunar. SDK kullanmadan ham ETW izlemesini kullanmanızı önermiyoruz. MSVC tarafından kullanılan olay biçimi belgelenmemiştir, büyük derlemelere ölçeklendirilecek şekilde iyileştirilmiştir ve anlamlı olması zordur. Ayrıca, C++ Derleme Analizler SDK API'si kararlıyken ham ETW izleme biçimi bildirimde bulunmadan değiştirilebilir.

İşlev C++ API C API'si Notlar
Olay geri çağırmalarını ayarlama IAnalyzer
IRelogger
ANALYSIS_CALLBACKS
RELOG_CALLBACKS
C++ Derleme Analizler SDK'sı geri çağırma işlevleri aracılığıyla olaylar sağlar. C++'ta, IAnalyzer veya IRelogger arabirimini devralan bir çözümleyici veya relogger sınıfı oluşturarak geri çağırma işlevlerini uygulayın. C'de, genel işlevlerde geri çağırmaları uygulayın ve bunlara ANALYSIS_CALLBACKS veya RELOG_CALLBACKS yapısında işaretçiler sağlayın.
Grup oluşturma MakeStaticAnalyzerGroup
MakeStaticReloggerGroup
MakeDynamicAnalyzerGroup
MakeDynamicReloggerGroup
C++ API'si, birden çok çözümleyiciyi gruplandırmak ve nesneleri birlikte yeniden günlüğe kaydetmek için yardımcı işlevler ve türler sağlar. Gruplar, karmaşık bir analizi daha basit adımlara bölmenin düzgün bir yoludur. vcperf bu şekilde düzenlenmiştir.
Analiz etme veya yeniden dağıtma Çözümleme
Relog
Çözümle
ÇözümleW
RelogA
Yeniden Oturum Aç

Analiz etme ve yeniden dağıtma

İzlemeyi kullanma işlemi bir analiz oturumu veya yeniden dağıtma oturumu aracılığıyla gerçekleştirilir.

Normal analiz kullanmak çoğu senaryo için uygundur. Bu yöntem size çıkış biçiminizi seçme esnekliği sağlar: printf metin, xml, JSON, veritabanı, REST çağrıları vb.

Yeniden dağıtma, ETW çıkış dosyası üretmesi gereken özel amaçlı analizler içindir. Yeniden dağıtmayı kullanarak C++ Derleme Analizler olaylarını kendi ETW olay biçiminize çevirebilirsiniz. Yeniden dağıtmanın uygun bir kullanımı, C++ Derleme Analizler verilerini mevcut ETW araçlarınıza ve altyapınıza bağlamaktır. Örneğin, vcperf yeniden yer tutucu arabirimleri kullanır. Bunun nedeni, bir ETW aracı olan Windows Performans Analizi'nin anlayabileceği veriler üretmesi gerekir. Yeniden dağıtım arabirimlerini kullanmayı planlıyorsanız ETW'nin nasıl çalıştığı hakkında önceden bilgi sahibi olmanız gerekir.

Çözümleyici grupları oluşturma

Grupların nasıl oluşturulacağını bilmek önemlidir. Aldığı her etkinlik başlangıç olayı için Hello, world! yazdıran bir çözümleyici grubunun nasıl oluşturulacağını gösteren bir örnek aşağıda verilmiştir.

using namespace Microsoft::Cpp::BuildInsights;

class Hello : public IAnalyzer
{
public:
    AnalysisControl OnStartActivity(
        const EventStack& eventStack) override
    {
        std::cout << "Hello, " << std::endl;
        return AnalysisControl::CONTINUE;
    }
};

class World : public IAnalyzer
{
public:
    AnalysisControl OnStartActivity(
        const EventStack& eventStack) override
    {
        std::cout << "world!" << std::endl;
        return AnalysisControl::CONTINUE;
    }
};

int main()
{
    Hello hello;
    World world;

    // Let's make Hello the first analyzer in the group
    // so that it receives events and prints "Hello, "
    // first.
    auto group = MakeStaticAnalyzerGroup(&hello, &world);

    unsigned numberOfAnalysisPasses = 1;

    // Calling this function initiates the analysis and
    // forwards all events from "inputTrace.etl" to my analyzer
    // group.
    Analyze("inputTrace.etl", numberOfAnalysisPasses, group);

    return 0;
}

Olayları kullanma

İşlev C++ API C API'si Notlar
Olayları eşleştirme ve filtreleme MatchEventStackInMemberFunction
MatchEventStack
MatchEventInMemberFunction
MatchEvent
C++ API'si, izlemelerinizden önem ettiğiniz olayları ayıklamayı kolaylaştıran işlevler sunar. C API'si ile bu filtreleme el ile yapılmalıdır.
Olay veri türleri Etkinlik
BackEndPass
BottomUp
C1DLL
C2DLL
CodeGeneration
Commandline
Derleyici
Derleyici Geçidi
EnvironmentVariable
Olay
EventGroup
EventStack
ExecutableImageOutput
ExpOutput
FileInput
FileOutput
ForceInlinee
FrontEndFile
FrontEndFileGroup
FrontEndPass
İşlev
HeaderUnit
ImpLibOutput
Çağırma
InvocationGroup
LibOutput
Bağlayıcı
LinkerGroup
LinkerPass
LTCG
Modül
ObjOutput
OptICF
OptLBR
OptRef
Geçiş1
Geçiş2
Önceden DerlenmişHeader
PreLTCGOptRef
SimpleEvent
SymbolName
TemplateInstantiation
TemplateInstantiationGroup
Iş parçacığı
Topdown
Traceınfo
TranslationUnitType
WholeProgramAnalysis
CL_PASS_DATA
EVENT_COLLECTION_DATA
EVENT_DATA
EVENT_ID
FILE_DATA
FILE_TYPE_CODE
FRONT_END_FILE_DATA
FUNCTION_DATA
FUNCTION_FORCE_INLINEE_DATA
INVOCATION_DATA
INVOCATION_VERSION_DATA
MSVC_TOOL_CODE
NAME_VALUE_PAIR_DATA
SYMBOL_NAME_DATA
TEMPLATE_INSTANTIATION_DATA
TEMPLATE_INSTANTIATION_KIND_CODE
TRACE_INFO_DATA
TRANSLATION_UNIT_PASS_CODE
TRANSLATION_UNIT_TYPE
TRANSLATION_UNIT_TYPE_DATA

Etkinlikler ve basit etkinlikler

Etkinlikler iki kategoriye ayrılır: etkinlikler ve basit olaylar. Etkinlikler, bir başlangıcı ve sonu olan zaman içinde devam eden süreçlerdir. Basit olaylar dakik oluşumlardır ve süresi yoktur. C++ Derleme Analizler SDK'sı ile MSVC izlemelerini analiz ederken, bir etkinlik başladığında ve durduğunda ayrı olaylar alırsınız. Basit bir olay gerçekleştiğinde yalnızca bir olay alırsınız.

Üst-alt öğe ilişkileri

Etkinlikler ve basit olaylar, üst-alt ilişkiler aracılığıyla birbiriyle ilişkilidir. Bir etkinliğin veya basit olayın üst öğesi, bunların oluştuğu kapsayan etkinliktir. Örneğin, bir kaynak dosyayı derlerken derleyicinin dosyayı ayrıştırıp kodu oluşturması gerekir. Ayrıştırma ve kod oluşturma etkinlikleri, derleyici etkinliğinin alt öğeleridir.

Basit olayların süresi yoktur, bu nedenle bunların içinde başka bir şey olamaz. Bu nedenle, hiç çocukları olmaz.

Her etkinliğin ve basit olayın üst-alt ilişkileri olay tablosunda gösterilir. C++ Derleme Analizler olayları kullanılırken bu ilişkileri bilmek önemlidir. Bir olayın tüm bağlamını anlamak için genellikle bunlara güvenmeniz gerekir.

Properties

Tüm olaylar aşağıdaki özelliklere sahiptir:

Özellik Tanım
Tür tanımlayıcısı Olay türünü benzersiz olarak tanımlayan bir sayı.
Örnek tanımlayıcısı İzleme içindeki olayı benzersiz olarak tanımlayan bir sayı. Bir izlemede aynı türde iki olay gerçekleşirse, her ikisi de benzersiz bir örnek tanımlayıcısı alır.
Başlangıç zamanı Bir etkinliğin başladığı zaman veya basit bir olayın gerçekleştiği zaman.
İşlem tanımlayıcısı Olayın gerçekleştiği işlemi tanımlayan bir sayı.
İş parçacığı tanımlayıcısı Olayın oluştuğu iş parçacığını tanımlayan bir sayı.
İşlemci dizini Olayın hangi mantıksal işlemci tarafından yayıldığını gösteren sıfır tabanlı dizin.
Olay adı Olay türünü açıklayan bir dize.

Basit olaylar dışındaki tüm etkinlikler de şu özelliklere sahiptir:

Özellik Tanım
Durdurma süresi Etkinliğin durduğu zaman.
Özel kullanım süresi Bir etkinlikte harcanan süre, alt etkinliklerinde harcanan zaman hariç.
CPU süresi CPU'nun etkinliğe bağlı iş parçacığında kod yürütmek için harcadığı süre. Etkinliğe bağlı iş parçacığının uykuda olduğu zamanı içermez.
Özel CPU süresi CPU süresiyle aynıdır, ancak alt etkinlikler tarafından harcanan CPU süresini dışlar.
Duvar saati zamanı sorumluluğu Etkinliğin genel duvar saati zamanına katkısı. Duvar saati zaman sorumluluğu, etkinlikler arasındaki paralelliği dikkate alır. Örneğin, iki ilgisiz etkinliğin paralel olarak çalıştığını varsayalım. Her ikisinin de süresi 10 saniyedir ve tam olarak aynı başlangıç ve durdurma süresine sahiptir. Bu durumda Build Analizler her ikisine de 5 saniyelik duvar saati süresi sorumluluğu atar. Buna karşılık, bu etkinlikler birbiri ardına çakışma olmadan çalıştırılırsa, her ikisine de 10 saniyelik duvar saati süresi sorumluluğu atanır.
Özel duvar saati zaman sorumluluğu Duvar saati saat sorumluluğuyla aynıdır, ancak çocuk etkinliklerinin duvar saati zaman sorumluluğunu dışlar.

Bazı olayların belirtilenlerin ötesinde kendi özellikleri vardır. Bu durumda, bu ek özellikler olay tablosunda listelenir.

C++ Derleme Analizler SDK'sı tarafından sağlanan olayları kullanma

Olay yığını

C++ Derleme Analizler SDK'sı size bir olay verdiğinde yığın biçiminde gelir. Yığındaki son girdi geçerli olaydır ve üst hiyerarşisi olmadan önceki girdilerdir. Örneğin, LTCG başlatma ve durdurma olayları bağlayıcının 1. geçişi sırasında gerçekleşir. Bu durumda alacağınız yığın şunları içerir: [LINKER, PASS1, LTCG]. Bir olayı köküne kadar izleyebildiğiniz için üst hiyerarşi kullanışlıdır. Yukarıda bahsedilen LTCG etkinliği yavaşsa, hangi bağlayıcı çağrısının söz konusu olduğunu hemen öğrenebilirsiniz.

Eşleşen olaylar ve olay yığınları

C++ Derleme Analizler SDK'sı size bir izlemedeki her olayı verir, ancak çoğu zaman bunların yalnızca bir alt kümesini önemsersiniz. Bazı durumlarda, olay yığınlarının yalnızca bir alt kümesini önemseyebilirsiniz. SDK, ihtiyacınız olan olayları veya olay yığınını hızla ayıklamanıza ve olmadığınız olayları reddetmenize yardımcı olacak olanaklar sağlar. Bu işlem şu eşleşen işlevler aracılığıyla gerçekleştirilir:

İşlev Tanım
MatchEvent Belirtilen türlerden biriyle eşleşiyorsa bir olayı tutun. Eşleşen olayları bir lambdaya veya başka bir çağrılabilen türe iletin. Olayın üst hiyerarşisi bu işlev tarafından dikkate alınmaz.
MatchEventInMemberFunction Bir üye işlevinin parametresinde belirtilen türle eşleşiyorsa bir olayı tutun. Eşleşen olayları üye işlevine iletin. Olayın üst hiyerarşisi bu işlev tarafından dikkate alınmaz.
MatchEventStack Hem olay hem de üst hiyerarşisi belirtilen türlere uyuyorsa bir olayı tutun. Olayı ve eşleşen üst hiyerarşi olaylarını bir lambda veya başka bir çağrılabilir türe iletin.
MatchEventStackInMemberFunction Hem olay hem de üst hiyerarşisi üye işlevinin parametre listesinde belirtilen türlere uyuyorsa olayı tutun. Olayı ve eşleşen üst hiyerarşi olaylarını üye işlevine iletin.

Eşleşmesi gereken üst hiyerarşiyi açıklarken boşluklara izin verme gibi MatchEventStack olay yığını eşleştirme işlevleri. Örneğin, [LINKER, LTCG] yığınıyla ilgilendiğinizi söyleyebilirsiniz. [LINKER, PASS1, LTCG] yığınıyla da eşleşer. Belirtilen son türün eşleşmesi gereken olay türü olması gerekir ve üst hiyerarşinin bir parçası değildir.

Yakalama sınıfları

İşlevleri Match* kullanmak, eşleştirmek istediğiniz türleri belirtmenizi gerektirir. Bu türler, yakalama sınıfları listesinden seçilir. Yakalama sınıfları aşağıda açıklanan çeşitli kategorilerde yer alır.

Kategori Tanım
Exact Bu yakalama sınıfları belirli bir olay türüyle eşleştirmek için kullanılır ve başka bir olay türüyle eşleşmez. Derleyici olayıyla eşleşen Derleyici sınıfı örnek olarak verilmiştir.
Joker Bu yakalama sınıfları, destekledikleri olaylar listesinden herhangi bir olayı eşleştirmek için kullanılabilir. Örneğin, Etkinlik joker karakteri herhangi bir etkinlik olayıyla eşleşir. Başka bir örnek, FRONT_END_PASS veya BACK_END_PASS olayıyla eşleşebilen CompilerPass joker karakteridir.
Gruplandırma Grup yakalama sınıflarının adları Grup ile biter. Bunlar, bir satırda aynı türdeki birden çok olayı eşleştirmek için kullanılır ve boşlukları yok sayar. Olay yığınında kaç tane olduğunu bilmediğiniz için yalnızca özyinelemeli olayları eşleştirirken anlamlı olur. Örneğin, FRONT_END_FILE etkinliği derleyici bir dosyayı her ayrıştırışında gerçekleşir. Derleyici dosyayı ayrıştırırken bir include yönergesi bulabileceğinden bu etkinlik özyinelemeli olur. FrontEndFile sınıfı yığındaki yalnızca bir FRONT_END_FILE olayıyla eşleşir. Tüm ekleme hiyerarşisini eşleştirmek için FrontEndFileGroup sınıfını kullanın.
Joker karakter grubu Joker karakter grubu, joker karakterlerin ve grupların özelliklerini birleştirir. Bu kategorinin tek sınıfı, tek bir olay yığınındaki tüm LINKER ve DERLEYICI olaylarını eşleştiren ve yakalayan InvocationGroup sınıfıdır.

Her olayla eşleştirmek için hangi yakalama sınıflarının kullanılabileceğini öğrenmek için olay tablosuna bakın.

Eşleştirmeden sonra: yakalanan olayları kullanma

Eşleşme başarıyla tamamlandıktan sonra, Match* işlevler yakalama sınıfı nesnelerini oluşturur ve bunları belirtilen işleve iletir. Olayların özelliklerine erişmek için bu yakalama sınıfı nesnelerini kullanın.

Örnek

AnalysisControl MyAnalyzer::OnStartActivity(const EventStack& eventStack)
{
    // The event types to match are specified in the PrintIncludes function
    // signature.  
    MatchEventStackInMemberFunction(eventStack, this, &MyAnalyzer::PrintIncludes);
}

// We want to capture event stacks where:
// 1. The current event is a FrontEndFile activity.
// 2. The current FrontEndFile activity has at least one parent FrontEndFile activity
//    and possibly many.
void PrintIncludes(FrontEndFileGroup parentIncludes, FrontEndFile currentFile)
{
    // Once we reach this point, the event stack we are interested in has been matched.
    // The current FrontEndFile activity has been captured into 'currentFile', and
    // its entire inclusion hierarchy has been captured in 'parentIncludes'.

    cout << "The current file being parsed is: " << currentFile.Path() << endl;
    cout << "This file was reached through the following inclusions:" << endl;

    for (auto& f : parentIncludes)
    {
        cout << f.Path() << endl;
    }
}