Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Роббинс Д. - Отладка приложений для Microsoft .NET и Microsoft Windows - 2004

.pdf
Скачиваний:
353
Добавлен:
13.08.2013
Размер:
3.3 Mб
Скачать

412 ЧАСТЬ III Мощные средства и методы отладки приложений .NET

и свойств. Я включил в код массу комментариев, так что вы легко поймете, как все работает.

Наибольшая проблема при создании SettingsMaster была связана с созданием значения перечислимого типа. Так как .NET строго типизирована, если бы я не смог создать специфическое значение Enum, мне было бы сложно задать множе ственные параметры через объекты Project и VCProject. После ряда безуспешных проб я обратился за помощью. Франческо Балена (Francesco Balena) напомнил мне, что с этим успешно справляется метод System.Enum.Parse. Все остальное оказалось простой нудной работой с XML файлами.

Будущие усовершенствования SettingsMaster

SettingsMaster — очень полезная надстройка, но если вы ищете проект, то можете внести в SettingsMaster ряд усовершенствований, чтобы сделать ее еще лучше.

В SettingsMaster отсутствует редактор конфигурационных XML файлов. С ре шетками свойств (property grid) работать довольно легко, поэтому вы могли бы создать такой редактор, чтобы избавиться от редактирования конфигура ционных файлов вручную. Этот редактор конфигураций следует сделать до ступным с командной панели SettingsMaster, а также из страницы свойств окна Options.

Есть одна функция, добавить которую будет относительно легко: это обработ чик событий, отслеживающий загрузку проектов и автоматически обновляю щий их параметры.

Некоторые глобальные параметры проектов на неуправляемом C++ устанав ливаются при помощи объекта VCPlatform. Было бы неплохо реализовать под держку этого объекта, чтобы пользователи могли задавать каталоги включае мых файлов и другие свойства, полезные при работе в группе.

Отличной функцией была бы команда записи текущих параметров проекта в конфигурационный файл SettingsMaster, чтобы вы могли применить их к дру гим проектам.

Чтобы предоставить пользователям дополнительной обратной связи, вы мог ли бы выводить изменения, сделанные SettingsMaster, в окно Output.

Резюме

Новые возможности создания макросов и надстроек, реализованные в IDE Visual Studio .NET, дали разработчикам могучую силу, позволяющую сделать среду именно такой, какая нужна для быстрого решения проблем. В этой главе я рассмотрел ряд вопросов, связанных с созданием реальных, жизнеспособных макросов и надстроек. Хотя в IDE все еще есть недостатки, общая картина более чем привлекательна.

Программисты давно желали получить мощь Visual Studio .NET. Теперь мы ее получили, и мне хотелось бы побудить вас реализовать средства, о которых вы всегда мечтали. Ими могли бы пользоваться все мы!

Г Л А В А

10

Мониторинг управляемых исключений

Наверное, вы уже поняли, что в разработке под Microsoft Visual Studio .NET го раздо больше исключений, чем в традиционной разработке под Microsoft Win32. Прелесть .NET в том, что обработка исключений была встроена изначально. Она не заимствовала прикрученные и привитые исключения, с которыми мы бились долгие годы, работая с приложениями Microsoft Windows и C++. Теперь исключе ния поддерживаются естественно и полноценно.

Но, как и всегда, исключения — для исключительных условий. Не стоит при менять исключения вместо таких конструкций, как операторы switch и case, если не хотите получить истинно медленный код. В этой главе я представлю утилиту ExceptionMon, которая служит для наблюдения за исключениями, возникающи ми в приложении. Хотя через диалоговое окно исключений в отладчике можно установить все исключения CLR на остановку при инициации, вам потребовалась бы вечность, потому что пришлось бы постоянно нажимать кнопку Continue. ExceptionMon позволяет наблюдать за исключениями почти без хлопот.

ExceptionMon использует одно из великолепнейших средств .NET — Profiling API. Я писал средства профилирования (profilers) и инструменты обнаружения ошибок (error detection tools) без поддержки ОС и, когда в .NET увидел Profiling API, сразу возблагодарил богов разработки. Profiling API прекрасно продуман и работает точно, как заявлено. Его сила позволяет видеть то, что практически не увидеть иными способами. Интересно, что название Profiling API несколько об манчиво, так как Profiling API позволяет гораздо больше простого хронометри рования операций. К концу главы в вашей голове будут роиться идеи других «про двинутых» инструментов, которые можно создать, используя Profiling API. Вооб ще я буду применять Profiling API в следующих главах как основу для других пре красных инструментов.

414 ЧАСТЬ III Мощные средства и методы отладки приложений .NET

Наш путь к ExceptionMon начнется с обсуждения средств и целей Profiling API. Разобравшись с этим, я объясню как работать с ExceptionMon и как она реализо вана. И в заключение я расскажу о своем видении применения исключений в мире

.NET.

Введение в Profiling API

Документация и примеры для Profiling API из .NET отсутствуют в MSDN, но они есть у вас на компьютере, если вы установили Visual Studio .NET. Волшебное мес то — <Каталог Visual Studio .NET>\SDK\v1.1\Tools Developers Guide. Там вы найде те каталог Docs с Word документами, описывающими все: от Profiling API до Debug ging API и Metadata API, а также полными спецификациями ECMA для общеязыко вой инфраструктуры (Common Language Infrastructure, CLI). Каталог Samples со держит примеры .NET компиляторов, примеры Profile API и средство обхода за висимостей сборок (assembly dependency walker). В документах и примерах мас са полезного, и, если вам любопытно, как в .NET все работает, каталог Samples — прекрасное место для начала исследований. Документ, описывающий Profiling API, — вполне очевидно — Profiling.DOC.

Есть два способа профилирования. В первом применяется процесс выборки (sampling). В нем средство профилирования через определенные интервалы в миллисекундах «заглядывает» в профилируемое приложение (profilee) и проверяет, что выполняется в данный момент, — это средство профилирования с выборкой имен (name sampling profiler). Второй метод — безвыборочный (nonsampling), где средство профилирования синхронно контролирует каждый вызов и возврат, отслеживая все, что происходит в профилируемом приложении. .NET Profiling API легко работает с обоими типами профилирования. Как я уже говорил, Profiling API позволяет делать гораздо больше, чем просто профилировать. Вот полный спи сок элементов, о которых вы можете получать уведомления, создавая программу с помощью Profiling API (табл. 10 1). Получение этих уведомлений относительно тривиально, так что в будущем вы наверняка увидите массу изящных инструментов.

Табл. 10-1. Обеспечение Profiling API

Элемент

Типы уведомлений

Исполняющая среда

Приостановка (suspend) и возобновление (resume) управляе

 

мого выполнения (всех потоков), приостановка и возобнов

 

ление отдельного управляемого потока

AppDomain

Старт (startup), завершение (shutdown)

Сборка

Загрузка (load), выгрузка (unload)

Модуль

Загрузка, выгрузка, присоединение (attach)

Класс

Загрузка, выгрузка

Функция

JIT компиляция, поиск в кэше, изъятие (удаление из памя

 

ти), подстановка (inlined), выгрузка

Поток

Создание (create), уничтожение (destroy), присвоение пото

 

ку ОС

Remoting

Активизация клиента, отправка клиентом сообщения, полу

 

чение клиентом ответа, получение сервером сообщения, ак

 

тивизация, отправка сервером ответа

 

ГЛАВА 10

Мониторинг управляемых исключений

415

 

 

 

Табл. 10-1. Обеспечение Profiling API

(продолжение)

 

 

 

 

Элемент

Типы уведомлений

 

Переключения

Управляемое в неуправляемое, неуправляемое в управляе

 

мое, создание COM VTable, уничтожение COM Vtable

 

Приостановка

Приостановка, отмена приостановки, возобновление,

 

исполняющей среды

приостановка потока, возобновление потока

 

Сбор мусора

Выделение объекта, выделения по классам, перемещение

 

 

ссылки, объектные ссылки, корневые ссылки

 

Исключение

Инициация, поиск, фильтрация, вход в перехватчик

 

 

(catcher), перехватчик обнаружен, вызов ОС обработчика,

раскрутка функции, раскрутка finally, обнаружен перехват чик CLR, запущен перехватчик CLR

Для написании средства профилирования реализуется интерфейс ICorProfiler Callback. Хотя было бы прекрасно писать средство профилирования в управляе мом коде, из за архитектуры, поддерживаемой Profiling API, этого делать нельзя. Средство профилирования выполняется в адресном пространстве профилируе мого управляемого приложения. Возможность использования управляемого кода вызывала бы чрезвычайно опасные ситуации разного рода. Так, если бы вы полу чили уведомление о проводимой операции сбора мусора и вам потребовалось бы выделить управляемую память для хранения собираемых элементов, это иници ировало бы рекурсивный сбор мусора. Не нужно говорить, что архитекторы Micro soft выбрали более разумный подход, минимизирующий взаимное влияние. Для поддержки управляемых средств профилирования все уведомления должны быть межпроцессовыми (cross process), что серьезно замедлило бы профилируемое приложение.

Поскольку средства профилирования — это всего лишь COM DLL, концепции должны быть знакомы всем, кто занимался разработкой под Windows с 2000 года. Всю нудную работу я инкапсулировал в библиотеке, что позволит вам сосредото читься на важных моментах, не увязая в COM. Ниже я расскажу о ProfilerLib под робнее. Хочу отметить ключевой COM аспект: ваш COM код средства профили рования будет вызываться в модели со свободными потоками (free threaded model), так что вам придется защищать структуры данных от повреждения в многопоточной среде (multithreaded corruption).

В интерфейсе ICorProfilerCallback лишь два метода нужны всегда: Initialize и Shutdown. Initialize вызывается самым первым. Вам передается интерфейс IUnknown, через который надо будет сразу запросить интерфейс ICorProfilerInfo и сохра нить возвращенный интерфейс, чтобы запрашивать информацию о профилиру емом приложении.

Многие методы ICorProfilerCallback получают идентификаторы. С помощью сохраненного интерфейса ICorProfilerInfo идентификатор преобразуется в удобное значение. Так, метод ICorProfilerCallback::ModuleLoadFinished получает значение

ModuleID, представляющее идентификатор загруженного метода. Чтобы определить имя модуля и другую полезную информацию, такую как адрес загрузки (load address) и идентификатор сборки, вызовите метод ICorProfilerInfo::GetModuleInfo. Допол нительные задачи, выполняемые с помощью методов интерфейса, включают по лучение интерфейсов метаданных, инициацию сбора мусора и запуск отладки

416 ЧАСТЬ III Мощные средства и методы отладки приложений .NET

процесса. Не буду описывать интерфейс ICorProfilerInfo полностью — подробную информацию см. в файле Profiling.DOC.

Сохранив интерфейс ICorProfilerInfo в методе ICorProfilerCallback::Initialize, следует сообщить CLR, какие уведомления вы хотели бы видеть. Красота системы ICorProfilerCallback в том, что вы будете получать уведомления только для нуж ных вам элементов, так что CLR сможет минимизировать использование ресур сов и выполнять профилируемое приложение как можно быстрее. Элементы, для которых требуются уведомления, позволяет указать метод ICorProfilerInfo::Set EventMask, принимающий битовое поле, которое указывает нужные элементы.

Устанавливаемые битовые флаги описаны в табл. 10 2. Большинство не требу ет объяснений. Некоторые значения — для которых в колонке Неизменяемый указано «Да» — могут быть установлены только во время вызова метода ICorProfiler Callback::Initialize. Если флаг уведомления не неизменяемый, его можно пере ключать в любой момент работы профилирующего средства. Чтобы увидеть вклю ченные флаги уведомлений, вызовите метод ICorProfilerInfo::GetEventMask. Флаг

COR_PRF_ENABLE_OBJECT_ALLOCATED устанавливается в методе ICorProfilerCallback::Ini tialize, указывая на необходимость установки CLR на отслеживание выделения объектов, а COR_PRF_MONITOR_OBJECT_ALLOCATED включает и выключает уведомления.

Табл. 10-2. Флаги уведомлений SetMethod

Флаг1

Неизменяемый

Описание

ALL

Да

Включает все флаги уведомлений.

APPDOMAIN_LOADS

Нет

Уведомление о каждой загрузке или выгруз

 

 

ке AppDomain.

ASSEMBLY_LOADS

Нет

Уведомление о каждой загрузке или выгруз

 

 

ке сборки.

CACHE_SEARCHES

Нет

Уведомление, когда код периода инсталля

 

 

ции находит функции, запущенные через

 

 

Native Image Generator (NGEN).

CCW

Нет

Уведомление о каждой COM оболочке.

CLASS_LOADS

Нет

Уведомление о каждой загрузке или выгруз

 

 

ке класса.

CLR_EXCEPTIONS

Нет

Уведомление о каждой внутренней обработ

 

 

ке исключений в CLR.

CODE_TRANSITIONS

Да

Уведомление о каждом переключении меж

 

 

ду управляемым и неуправляемым кодом.

DISABLE_INLINING

Да

Отключает подстановку методов во всем

 

 

процессе. Если не установлен, уведомления

 

 

о подстановках проходят через уведомле

 

 

ние ICorProfilerCallback.JITInlining.

DISABLE_OPTIMIZATIONS

Да

Предписывает JIT компилятору отключить

 

 

оптимизации.

ENABLE_IN_PROC_DEBUGGING

Да

Разрешает использование внутрипроцесс

 

 

ной отладки (in process debugging) вместе

 

 

с Profiling API.

ENABLE_JIT_MAPS

Да

Разрешает отслеживание JIT сопоставлений.

1 Для ясности из имен флагов удалены префиксы COR_PRF_ и COR_PRF_MONITOR_.

 

ГЛАВА 10

Мониторинг управляемых исключений

417

 

 

Табл. 10-2. Флаги уведомлений SetMethod (продолжение)

 

 

 

 

 

Флаг

Неизменяемый

Описание

 

ENABLE_OBJECT_ALLOCATED

Да

Уведомление о каждом объекте, выделенном

 

 

из кучи собранного мусора.

 

ENABLE_REJIT

Да

Вызывает повторную JIT компиляцию кода

 

 

периода инсталляции (NGEN), чтобы вклю

 

 

чить для этих функций JIT уведомления.

 

ENTERLEAVE

Нет

Ловушки (hooks) на входе и выходе функ

 

 

ции вызова (call function).

 

EXCEPTIONS

Нет

Уведомление о каждом не CLR исключении

 

 

(т. е. обо всех общих исключениях).

 

FUNCTION_UNLOADS

Нет

Уведомление о выгрузке функций.

 

GC

Да

Уведомление о готовящемся сборе мусора.

JIT_COMPILATION

Нет

Уведомление о каждой функции непосред

 

 

ственно до и сразу после ее JIT компиляции.

MODULE_LOADS

Нет

Уведомление о каждой загрузке и выгрузке

 

 

модуля.

 

NONE

Нет

Не посылать уведомления.

 

OBJECT_ALLOCATED

Нет

Уведомление о каждом объекте, выделяемом

 

 

в кучу собранного мусора.

 

REMOTING

Да

Уведомление о пересечении каждого кон

 

 

текста удаленного взаимодействия

 

 

 

(remoting).

 

REMOTING_ASYNC

Да

Уведомление о каждом асинхронном собы

 

 

тии удаленного взаимодействия.

 

REMOTING_COOKIE

Да

Создание файлов «cookie», чтобы средство

 

 

профилирования могло спаривать обратные

 

 

вызовы удаленного взаимодействия.

 

SUSPENDS

Нет

Уведомление о приостановке CLR.

 

THREADS

Нет

Уведомление о каждом создании и уничто

 

 

жении потока.

 

 

 

 

 

После возврата S_OK из метода ICorProfilerCallback::Initialize вы будете полу чать запрошенные уведомления через соответствующий метод ICorProfilerCallback. Я расскажу, что с этим делать чуть позже, так как сначала хочу упомянуть после дний необходимый метод — ICorProfilerCallback::Shutdown.

Если профилируемый процесс начинает выполнение в виде управляемого приложения, метод Shutdown будет обязательно вызван. Однако, если приложение начинает выполнение как неуправляемое приложение, загружающее CLR, как Visual Studio .NET, то ваш метод Shutdown вызван не будет. Чтобы обеспечить остановку средства профилирования, в DllMain средства профилирования надо обрабатывать флаг DLL_PROCESS_DETACH и проверять, вызван ли метод Shutdown. Если нет, следует провести очистку вручную, помня, что, поскольку приложение завершается, надо быть осведомленным о выполняемых операциях. Пример действий в такой ситу ации см. в коде ExceptionMon.

Кроме специальных алгоритмов, необходимых для реализации вашего кон кретного профиля, основная работа будет заключаться в том, чтобы следить за

418 ЧАСТЬ III Мощные средства и методы отладки приложений .NET

значениями, получаемыми методами уведомления ICorProfilerCallback. Многие методы уведомления получают значения идентификаторов, которые можно при менять для получения определенной информации об объекте. Эти уникальные для Profiling API идентификаторы являются просто адресами элементов в памяти, благо интерфейс ICorProfilerInfo предлагает методы, помогающие преобразовать эти идентификаторы в реальные значения. Обычно для этого нужно вызвать соответ ствующий метод ICorProfilerInfo, получить интерфейс метаданных, напрямую свя занный с идентификатором, и задействовать этот интерфейс в работе.

Метаданные ссылаются на данные, описывающие каждый объект в .NET. Само описание объектов с помощью метаданных — загвоздка .NET. При разработке управляемых приложений метаданные доступны через механизм отражения. При разработке неуправляемых приложений, которым нужен доступ к метаданным, используется интерфейс чтения (reader interface) IMetaDataImport и интерфейс за писи (writer interface) IMetaDataEmit. В основном работа, выполняемая в средствах профилирования, сопряжена с чтением данных через IMetaDataImport. IMetaDataEmit используется компиляторами для создания метаданных в скомпилированных в .NET двоичных файлах. Интерфейсы метаданных подробно описываются в файле Meta data Unmanaged API.DOC, так что я отправлю вас туда, так как по большей части работа с метаданными — чистая морока.

Наверное, лучший способ продемонстрировать работу с идентификаторами и метаданными — показать, как получить имя класса и метода из идентификатора функции (function ID). Значения идентификаторов функций получаются многи ми методами ICorProfilerCallback, такими как ExceptionUnwindFunctionEnter (чтобы показать, какая функция раскручена), JITCompilationFinished (чтобы показать, ка кая функция прошла JIT компиляцию) и ManagedToUnmanagedTransition (чтобы по казать, какая функция переключается на неуправляемый код). В листинге 10 1 показан метод GetClassAndMethodFromFunctionId из ProfilerLib, который получает имя класса и метода из идентификатора функции. Как видите, для этого надо лишь прорваться через интерфейс метаданных.

Листинг 10-1. GetClassAndMethodFromFunctionId

 

BOOL CBaseProfilerCallback ::

 

 

 

 

 

GetClassAndMethodFromFunctionId (

FunctionID

uiFunctionId

,

 

 

 

LPWSTR

szClass

,

 

 

 

UINT

uiClassLen

,

 

 

 

LPWSTR

szMethod

,

 

 

 

UINT

uiMethodLen

)

 

 

{

 

 

 

 

 

// Магия метаданных в том, как найти эту информацию.

 

 

 

 

// Возвращаемое значение.

 

 

 

 

 

BOOL bRet = FALSE ;

 

 

 

 

 

// Маркер для идентификатора функции.

 

 

 

 

 

mdToken MethodMetaToken = 0 ;

 

 

 

 

 

// Интерфейс метаданных.

 

 

 

 

 

IMetaDataImport * pIMetaDataImport = NULL

;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ГЛАВА 10 Мониторинг управляемых исключений

419

 

 

//Запрашиваем через ICorProfilerInfo интерфейс

//метаданных для этого идентификатора функции. HRESULT hr = m_pICorProfilerInfo >

GetTokenAndMetaDataFromFunction (

uiFunctionId

,

 

IID_IMetaDataImport

,

(IUnknown**)

&pIMetaDataImport

,

 

&MethodMetaToken

);

ASSERT ( SUCCEEDED ( hr ) ) ;

 

 

if ( SUCCEEDED ( hr ) )

 

 

{

 

 

//Маркер для класса. mdTypeDef ClassMetaToken ;

//Суммарные копии символов. ULONG ulCopiedChars ;

//Получаем из метаданных информацию о методе.

hr = pIMetaDataImport >GetMethodProps ( MethodMetaToken ,

&ClassMetaToken

,

szMethod

,

uiMethodLen

,

&ulCopiedChars

,

NULL

,

NULL

,

NULL

,

NULL

,

NULL

) ;

ASSERT

(

SUCCEEDED

(

hr ) ) ;

 

ASSERT

(

ulCopiedChars

< uiMethodLen ) ;

if ( (

SUCCEEDED (

hr )

 

) &&

(

ulCopiedChars

<

uiMethodLen )

)

{

// Имея маркер метаданных для класса, я могу найти класс.

hr = pIMetaDataImport >GetTypeDefProps ( ClassMetaToken

,

szClass

,

uiClassLen

,

&ulCopiedChars

,

NULL

,

NULL

) ;

ASSERT ( SUCCEEDED ( hr ) ) ;

ASSERT ( ulCopiedChars < uiClassLen ) ;

if ( (

SUCCEEDED ( hr )

)

&&

(

ulCopiedChars < uiClassLen )

)

{

bRet = TRUE ;

}

else

{

bRet = FALSE ;

}

}

см. след. стр.

420 ЧАСТЬ III Мощные средства и методы отладки приложений .NET

else

{

bRet = FALSE ;

}

pIMetaDataImport >Release ( ) ;

}

else

{

bRet = FALSE ;

}

return ( bRet ) ;

}

Запуск средства профилирования

До сих пор я рассказывал, как работают средства профилирования, но так и не упомянул, как их запускать. Увы, это слабое звено системы профилирования.

Загружаемое средство профилирования определяется двумя переменными окружения. Первая, которой следует установить ненулевое значение, — Cor_Enable_Pro filing; она сообщает CLR, что следует включить профилирование. Второй — Cor_Pro filer — следует задать CLSID или ProgID средства профилирования. Вот как уста новить средство профилирования ExceptionMon из командной строки.

set Cor_Enable_Profiling=0x1

set COR_PROFILER={F6F3B5B7 4EEC 48f6 82F3 A9CA97311A1D}

Установка переменных окружения прекрасно работает для Windows Forms и консольных приложений .NET, но как профилировать приложения Microsoft ASP.NET? Ох, это непросто. Поскольку надо устанавливать переменные окружения, придется установить две переменные в системном окружении (рис. 10 1), так как отсюда Microsoft Internet Information Services (IIS) и ASPNET_WP.EXE/W3WP.EXE будут считывать переменные окружения.

С помощью Visual Studio .NET 2003 и .NET Framework 1.1 можно перезапустить IIS, чтобы новый экземпляр ASPNET_WP.EXE принял новые глобальные перемен ные окружения. Чтобы перезапустить IIS, вызовите консоль Internet Information Services, щелкните правой кнопкой имя машины, укажите на All Tasks и выберите из контекстного меню команду Restart IIS. В диалоговом окне Start/Stop/Reboot выберите Restart Internet Services On <имя компьютера> из раскрывающегося списка и щелкните OK. ASPNET_WP.EXE/W3WP.EXE не запустится, пока вы не запросите IIS об ASP.NET приложении. Проверить, установлены ли переменные окружения, позволяет Process Explorer (см. главу 3): дважды щелкните ASPNET_WP.EXE/W3WP.EXE в верхнем окне и в диалоговом окне Properties перейдите на вкладку Environment.

Устанавливая переменные системного окружения, вы сталкиваетесь с еще од ной проблемой. Будучи общесистемным (system wide), любой процесс, загружа ющий CLR, автоматически профилируется. Это может соответствовать вашим на мерениям, но с ростом количества процессов, загружающих CLR, могут быстро

ГЛАВА 10 Мониторинг управляемых исключений

421

 

 

возникнуть проблемы. Так, если в вашем средстве профилирования есть ошибка (я знаю, что этого не может быть, но просто в порядке шутки) и вы собираетесь отладить его с помощью Visual Studio .NET, ваше средство профилирования так же будет загружено и в Visual Studio .NET, что может сорвать всю отладку. Можно использовать удаленную отладку, но я предпочитаю устанавливать еще одну пе ременную окружения, указывающую, в каком процессе или процессах запускать средство профилирования. Тогда при старте вы сможете проверить определенную переменную окружения и указать, запускаться ли в данном процессе. Если запус каться в процессе не нужно, просто вызовите ICorProfilerInfo::SetEventMask, пе редав COR_PRF_MONITOR_NONE как маску в методе ICorProfilerCallback::Initialize.

Рис. 10 1. Установка переменных системного окружения

Поскольку проверка того, запускать ли средство профилирования в определен ном процессе, — операция стандартная, я реализовал в ProfilerLib метод CBasePro filerCallback::SupposedToProfileThisProcess, выполняющий для вас эту проверку. Пе редайте как параметр проверяемую переменную окружения, и функция вернет TRUE в следующих случаях.

1.Переменная окружения не установлена, что предполагает желание профили ровать все процессы.

2.Значение переменной окружения полностью соответствует диску, пути и име ни текущего процесса.

3.Значение переменной окружения совпадает только с именем файла текущего процесса.

Здесь я хочу закончить введение в Profiling API. Он позволяет делать гораздо больше того, что было рассказано. Но, вместо того чтобы затягивать ваши глаза поволокой все новых подробностей и оставить вас в раздумьях о том, как приме нить Profiling API, думаю, лучше всего объяснить это, показав вам применение некоторых из самых «продвинутых» его функций. К концу этих двух глав, касаю

Соседние файлы в предмете Программирование на C++