Анализ последовательности вызовов Java - PullRequest
2 голосов
/ 24 мая 2011

Я хотел бы иметь возможность визуализировать последовательность вызовов для данного процесса JVM (какие методы были вызваны, какие объекты и какие параметры были переданы).Например, инструмент, который будет выводить эту информацию в файл.Существует ли существующий инструмент для этого?Если нет, не могли бы вы дать несколько советов о том, как это можно сделать?Какие решения вы могли бы посоветовать (помимо изменения байт-кодов методов)?

Ответы [ 3 ]

1 голос
/ 01 июля 2011

ОП говорит: «Журналирование Java» не годится.«Да, но вы должны вручную вставлять все вызовы журнала. Не очень приемлемый вариант для большого проекта, не так ли?».

Хорошо, вам нужен способ автоматической вставки пользовательских инструментов в ваше приложение.

Для этого можно использовать наш набор инструментов для реинжиниринга программного обеспечения DMS с интерфейсом Java .DMS предоставляет универсальный механизм для анализа исходного кода, построения AST и таблиц символов, анализа кода (деревьев) для особых случаев и выполнения преобразований в коде (деревьях), в конечном итоге воссоздавая модифицированный код (из модифицированных деревьев).Интерфейс Java позволяет DMS сделать это для Java;В DMS есть много других языковых модулей внешнего интерфейса.

Вам нужно написать преобразование источника в источник DMS, чтобы снабдить запись функции логикой для вывода значений из списка параметров (например, serialize).их эквиваленты "toString"):

tag RecordArguments(a:arguments):statements;

instrument_function_entry rule(r:type,m:identifier,a:arguments,s:stmts):method->method
   "\r \m(\a) { \s } "
   ->
   "\r \m(\a) { Call.FunctionEntry(\stringify\(\m\));\RecordArguments\(\a\); { \s } }"

empty_arguments rule () arguments -> statements
   "\RecordArguments\(\) " -> ";"

 more_arguments rule (args:arguments,a:argument) arguments -> statements
   "\RecordArguments\(\args,\a)" 
   -> "\RecordArguments\(\args\);Call.Argument(\a.toString()))"

То, что делает правило "instrument_function_entry", - это вызывает вызов для записи записи функции и генерирует серию вызовов для записи значений аргумента.Правило empty_arguments обрабатывает базовый случай обработки аргументов no-more-arguments (включая «вообще никаких аргументов»).Правило «more_arguments» обрабатывает список аргументов, выбирая последний, генерируя код для выгрузки этого аргумента и создавая более короткий список оставшихся аргументов, которые будут обработаны тем же правилом или, в конечном итоге, правилом «empty_arguments».

Что это должно произвести для метода:

 int  X3(char J, array[] X)
 { <code> }

будет

 int X3(char J, array[] X)
 {  Call.FunctionEntry("X3");
    Call.Argument(J.toString());
    Call.Argument(X.toString());
    { <code> } 
  }

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

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

Я думаю, что проще всего использовать JPDA (Java Platform Debugger Architecture). Вам придется приостановить все потоки, проанализировать, сбросить информацию и возобновить потоки. Это не будет тривиально, но с первого взгляда это будет возможно.

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

Лучший способ, которым я смотрел на стек вызовов для Java, был через отладчик Eclipse. Если вы просто разместите точки останова в своем коде, вы сможете пройтись по коду и посмотреть на стек вызовов.

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