Получите HashCode вызывающего объекта? - PullRequest
3 голосов
/ 24 мая 2011

Это может быть дубликат, но я не видел этот точный вопрос или похожий вопрос, на который задавали / отвечали с датой, более новой, чем выпуск .Net 4.

Я ищу временный хак, который позволяет мне просматривать стек вызовов и получать все вызывающие объекты (не методы, а экземпляры, которые содержат методы) в стеке. В конечном итоге мне нужны их хэш-коды.

Возможно ли это?

EDIT:

Было ли это в моем вопросе или нет, я действительно спрашивал, есть ли простой / встроенный способ сделать это. На самом деле, просто временное исправление, пока я не смогу внести серьезные изменения в другие части системы. Спасибо за отличные ответы. Увидев их, я подожду. , , :)

Ответы [ 4 ]

5 голосов
/ 24 мая 2011

Чего ты здесь пытаешься достичь?

Посмотрите на аналогичный вопрос, на который я ответил около месяца назад: Как получить текущее значение EIP в управляемом коде? . Вы можете получить вдохновение от этого. Или вы можете решить, что это слишком некрасиво (+1 для последнего).

Если все, что вы хотите сделать, - это собрать «уникальные» пути вызовов в рамках сеанса программы, продолжайте: я был бы очень уверен использовать ткач AOP и нить локальное хранилище. Это было бы не так уж сложно.

Предупреждение 1: Хеши не очень полезны для общих объектов .NET

Хеш-код случайного объекта может изменяться в зависимости от его местоположения в куче. Для справки: в MONO, с отключенным распределителем движущейся кучи, Object :: GetHash - это симпатичный кусочек кода ( mono / metadata / monitor.c )

#else
/*
 * Wang's address-based hash function:
 *   http://www.concentric.net/~Ttwang/tech/addrhash.htm
 */
    return (GPOINTER_TO_UINT (obj) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
#endif

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

Предостережение 2: Ваш стек будет содержать инопланетные фреймы

Даже если вы исправили эту часть, предоставив надлежащие детерминированные хеш-функции, вам потребуется, чтобы каждый стековый фрейм имел тип 'recgonizable'. Это, вероятно, не будет иметь место. Конечно, нет, если вы используете что-то похожее на LINQ, анонимные типы, статические конструкторы, делегаты; все виды вещей могут быть чередованием стековых кадров с (анонимными) вспомогательными типами или даже батутами производительности, изобретенными JIT-компилятором для оптимизации хвостовой рекурсии, большой таблицей переходов переключения или совместным использованием кода между несколькими перегрузками.

Вывод: анализ стека сложен: вы обязательно должны использовать надлежащий API, если вы собираетесь его проводить.

Вывод:

Обязательно есть мяч. Но прислушайтесь к совету

  1. ваши требования нестандартны (подчеркнуто библиотекой времени выполнения, не поддерживающей ее); Обычно это признак того, что: вы решаете уникальную проблему (но пересматриваете выбранный инструмент?) Или решаете ее неправильно
  2. Возможно, вы могли бы получить гораздо больше информации, генерируя потоковый граф с некоторым рукописным кодом моделирования вместо того, чтобы пытаться подключиться к CLR VM
  3. если вы собираетесь это сделать, используйте соответствующий API (вероятно, API-интерфейс профилировщика, поскольку профилировщик выборки сохранит именно это: складывает «отпечатки пальцев» каждые так много инструкций)
  4. Если вы действительно должны сделать это, используя свой код, подумайте об использовании AOP
1 голос
/ 24 мая 2011

Вы можете получить стек вызовов, создав экземпляр класса StackTrace и проверив внутри него StackFrame объекты.Глядя на список членов, кажется, что это не показывает экземпляры, только классы и методы.

1 голос
/ 24 мая 2011

Это возможно только с неуправляемыми API, особенно с API профилирования CLR.Я точно знаю об этом, кроме того, что он используется для реализации инструментов профилирования и отладки.Вы должны гуглить это и быть комфортным с горящей 1 неделей, приводящей это к производству.Если это вообще возможно, откажитесь от своего плана и найдите альтернативу.Скажите нам, что вы хотите сделать, и мы можем помочь!

0 голосов
/ 24 мая 2011

Попробуйте Environment.StackTrace .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...