2015-05-07 4 views
7

Я пытаюсь отслеживать распределения всех объектов в JVM.Добавление invokestatic в java/lang/Object. <init> с помощью агента JVM TI вызывает сбой JVM с segfault

В нескольких документах о профайлерах распределения было отмечено, что самый простой способ сделать это заключается в следующем: добавить invokestatic Tracker.trackAllocation()V инструкции java/lang/Object.<init> (как правило, он состоит из одной return инструкции, мы добавим invokestatic перед ним, так что 2 инструкции).

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

Файл класса снабжен агентом JVM TI в крюке onClassLoaded.

Однако после добавления команды invokestatic JVM сбой с segfault. Объект Tracker добавлен в загрузчик классов bootstrap, поэтому он должен быть видимым на любом этапе. Я попытался добавить nop вместо invokestatic, а JVM отлично работает с измененным классом Object. Поэтому проблема связана с вызовом какого-либо статического метода.

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

Есть ли что-нибудь, что мне не хватает в инструментах java.lang.Object?

Код для агента находится здесь: https://gist.github.com/Korobochka/3bf2f906f6ab85b22dec (контроль ошибок раздели, код для изменения классов также не входит, но она работает достаточно хорошо для других классов)

+0

Показать код – apangin

+0

@apangin Я добавил суть с кодом агента в нижнюю часть вопроса. Это версия, в которой объект изменен после vmInit. – Korobochka

+1

Я думаю, что проблема заключается в том, что класс 'Tracker' является самим объектом, который должен быть создан до создания объекта, но для этого потребуется сначала загрузить класс ... и так далее. Вам нужно как-то разбить этот цикл. – biziclop

ответ

5

Похоже, проблема заключается в вызове System.out.println от LeakAgentInterface. Прежде всего, System.out еще не может быть инициализирован. Во-вторых, println может выделять объекты самостоятельно.

+1

И это включает в себя 'String', который будет напечатан, который также является объектом; даже константа времени компиляции 'String' должны быть выделены во время выполнения, когда они используются в первый раз ... – Holger

+0

Просто проверено, это действительно так. Большое спасибо!Я потратил пару часов на это, и ошибка была очень простой и глупой = (Но я искал ошибку только на C++-коде. – Korobochka

 Смежные вопросы

  • Нет связанных вопросов^_^