08 December, 2010

Восстановление списка активных тредов во время attach

Список ThreadID для работающих managed тредов нельзя получить через CLR v4 profiling API в чистом виде. Для sampling профайлера это очень серьезная неприятность, так как профайлер не сможет узнать о уже существующих тредах. Он их попросту не увидит.

Но есть не плохой выход - установить флажок COR_PRF_MONITOR_JIT_COMPILATION. Таким образом профайлер сможет получать events о JIT компиляции. Компиляция же происходит достаточно часто и профайлер легко сможет получить ThreadID при помощи вызова GetCurrentThreadID.

P.S. В следующей версии dotTrace, ну той что после 4.0.1, наконец-то будет attach.

26 November, 2010

Определение разрядности работающего процесса

Периодически тредуется код который сможет определить разрядность процесса по его id. Вот пример такого кода:

[DllImport("kernel32.dll", PreserveSig = true, SetLastError = true, ExactSpelling = true)]
private static extern unsafe bool _IsWow64Process(void* hProcess, out bool wow64Process);

private static bool IsWow64Process(Process process)
{
  if (process == null)
    throw new ArgumentNullException("process");
  if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6)
    unsafe
    {
      bool retVal;
      if (_IsWow64Process(process.Handle.ToPointer(), out retVal))
        return retVal;
    }
  return false;
}

public static string GetPointerSize(int processId)
{
  using (Process p = Process.GetProcessById(processId))
    if (IsWow64Process(p))
      return 4;
  switch (IntPtr.Size)
  {
  case 4:
    return IsWow64Process(Process.GetCurrentProcess()) ? 8 : 4;
  case 8:
    return 8;
  default:
    throw new ApplicationException("Unknown pointer size");
  }
}

Attach особенности реализации

Неприятной особенностью интерфейса ICLRMetaHost является то, что поодерживаются только процессы с той же разрядностью, что и у вашего приложения. Другими словами если ваше приложение 64 бита, то и работать вы сможете только с 64-х битными процессами, а если 32 бита, то - только с 32-я битными.

12 November, 2010

О важности default значений

Забавная ситуация происходит, пользователи нам пишут что dotTrace Performance 4.0 работает медленно. С другой стороны многие ли позователь имеют ясное и четкое представление о том чем отличается sampling профиляция от tracing? Понимают ли пользователи, что один вид профиляции принципиально сильно быстрее или медленнее другого и почему это так?

10 November, 2010

Смена семантики COR_PRF_ENABLE_STACK_SNAPSHOT

В .NET Framework v2.0 флаг COR_PRF_ENABLE_STACK_SNAPSHOT входил в группу COR_PRF_MONITOR_IMMUTABLE (флаг можно устанавливать один раз и только во время вызова ICorProfilerCallback::Initialize), а в .NET Framework v4.0 уже входит в группу COR_PRF_ALLOWABLE_AFTER_ATTACH (этом флагом можно манипулировать в любое время). Собственно напоролся на это.

06 November, 2010

Несколько слов о пищеварении профайлеров

Получилось так, что главным заказчиком dotTrace стал ReSharper. А все потому что ReSharper очень серьезное и тяжелое приложение и не каждый профайлер способен проглотить в tracing/line-by-line режимах такой кусок мяса кода и в добавок выжить после такого издевательства.

На сегодня нашим классическим тестом на выносливость является: профиляция процесса загрузки солюшена ReSharper 5.1/6.0 под Visual Studio 2008/2010 с установленным релизным ReSharper 5.1. Перед началом теста все кэши стираются. Расширенный тест предполагает, что после загрузки солюшена запускается анализ солюшена на всю ночь (желателен пустой 500Gb HDD для нашего снапшота).

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

К моему глубокому сожалению поддержка профайлера в .NET Compact Framework v3.5.7283 содержит серьезную ошибку, которая увы делает невозможным корректную профиляцию в tracing режиме, если в коде кидаются exception которые не ловятся в той же функции где возникают. Как выяснилось причина в том, что необходимые нам нотификации из ICorProfilerCallback::ExceptionXXX просто не приходят. Получается, что наш продукт не виноват, но пользователю-то все равно кто виноват, программа же не работает. Обидно...

03 November, 2010

О культуре работы с реестром

Хотел озвучить одну вещь, которая меня крайне раздражает в некоторых программах, а именно нежелание за собой чистить реестр после деинсталляции и после окончания работы. На днях очень тесно столкнулся с этим. У пользователей наш dotTrace переставал нормально работать сразу после использования сторонних профайлеров (однозначно это было замечено за YourKit и ANTS от RedGate).

23 April, 2010

Выплыл однако

Ух, 2 недели тяжелой, глубокой и безостановочной отладки и ... инструментация для Silverlight 4.0 практически готова. С другой стороны в этом есть и свои плюсы - получил гору бесценного опыта.

30 March, 2010

Своя личная NTLM authentication в remoting (Часть №1)

Задача поставлена, теперь как бы ее так реализовать с использованием того-же NegotiateStream но уже поверх remoting. Сперва наперво должно прийти понимание, что наш NegotiateStream будет работать только с некоторыми стримами: NetworkStream или PipeStream. FileStream, MemoryStream не годятся категорически. Можно еще нагородить что-то свое, но это довольно долго. Сперва напишем интерфейс общения клиента и сервера.

Вольности в метаданных

Ну как всегда, напишешь что-нибудь хорошее, а на каких-то исходных данных оно не работает. Вот и с метаданными произошла такая засада: некоторые .NET компиляторы именуют главный metadata stream не #~ как все белые люди, а так сказать упрощенно, для бедных: #-

08 March, 2010

NTLM Authentication просто и со вкусом

Я довольно долго искал простой и стандартный путь для того чтобы произвести аутентификацию пользователя (текущий пользователь - вы не знаете его пароля и пользователь заданный при помощи NetworkCredential) на удаленном компьютере. Хотел уже было все написать ручками через AcquireCredentialsHandle/InitializeSecurityContext/AcceptSecurityContext/CompleteAuthToken, но совсем неожиданно нашел NegotiateStream - который и занимается данным непростым процессом. По сему поводу написал маленький примерчик (пример работает только в пределах одного компьютера, если хотите большего, то замените NamedPipeXxxStream на Socket).

03 March, 2010

Object synchronization method was called from an unsynchronized block of code

Симптомы: Посредством remoting вы создаете Mutex на удаленной машине все работает хорошо, но в один прекрасный момент при попытке вызвать ReleaseMutex вы получаете exception "Object synchronization method was called from an unsynchronized block of code". Ошибка плавающая, возникает время от времени и не на всех компьютерах.

Диагноз: ReleaseMutex вызывается не из того же thread что и вызов WaitOne так как никто не гарантирует, что отдельные remoting вызовы будут работать в том же thread.

Лечение: Можно нагородить на удаленной машине объект, который будет обеспечивать тот же тред для вызывов WaitOne и ReleaseMutex. А можно просто заменить Mutex на Semaphore...

15 February, 2010

Выравнивание в CLR и в C/C++

Столкнулся вот с проблемой: нужно было установить однозначное соответствие структуры в C/C++ и в CLR, структурка небольшая вот такого вида:
#pragma pack(push, PPP)
struct XXX
{
    LPVOID m_AAA;
    ULONG m_BBB;
    ULONG m_CCC;
    ULONG m_DDD;
};
#pragma pack(pop)

31 January, 2010

Бережливой хозяйке на заметку

Все знают функцию QueryPerformanceCounter, но как давеча выяснилось не все знают, что ее реализация под Windows Vista x64 портит регистр xmm0 после своего вызова. Windows7 x64 такой пакости не делает.

27 January, 2010

Нестыковочки

Неожиданно на одном компьютере dotTrace 4.0 начал валиться при профиляции безобидного приложения. Выяснилось, что виноват во всем класс System.Reflection.Emit.DynamicMethod. Оказывается при обработке исключений он сильно влияет на парность ExceptionSearchFunctionLeave и ExceptionUnwindFunctionLeave - вызовы ExceptionSearchFunctionEnter и ExceptionUnwindFunctionEnter напрочь отсутствуют. Профайлер не ожидавший такой подставы валится (в релизной сборке убрано большинство проверок для увеличения производительности). Сейчас все починено и работает...

P.S. Подробности по этой проблеме тут в разделе DynamicMethods.

Новое в dotTrace 4.0

Появилась поддержка Silverlight 4.0, пока не сделан отдельный тип аргумента, но я уже думаю об этом. Технически вся поддержка свелась к правильной установке CORECLR_ENABLE_PROFILING и CORECLR_PROFILER, прошу не путать с COR_ENABLE_PROFILING и COR_PROFILER.