2010-08-06 3 views
3

Я пишу короткий и простой профайлер (на C), который предназначен для периодического вывода трассировки стека для потоков на разных Java-клиентах. Я должен использовать недокументированную функцию AsyncGetCallTrace вместо GetStackTrace, чтобы свести к минимуму вторжение и разрешить трассировку стека независимо от состояния потока. Исходный код функции можно найти здесь: http://download.java.net/openjdk/jdk6/promoted/b20/openjdk-6-src-b20-21_jun_2010.tar.gz в hotspot/src/share/vm/prims/forte.cpp. Я нашел несколько справочных страниц, которые документируют JVMTI, обработку сигналов и время, а также блог с подробными сведениями о том, как настроить вызов AsyncGetCallTrace: http: // jeremymanson.blogspot.com/2007/05/profiling-with-jvmtijvmpi- SIGPROF-and.html.Как правильно написать обработчик SIGPROF, который вызывает AsyncGetCallTrace?

Отсутствие этого блога - это код для фактического вызова функции внутри обработчика сигнала (автор предполагает, что читатель может это сделать самостоятельно). Я прошу о помощи в этом. Я не уверен, как и где создать структуру ASGCT_CallTrace (и внутреннюю структуру ASGCT_CallFrame), как определено в вышеупомянутом файле forte.cpp. Структура ASGCT_CallTrace является одним из параметров, переданных AsyncGetCallTrace, поэтому мне нужно ее создать, но я не знаю, как получить правильные значения для своих полей: JNIEnv * env_id, jint num_frames и JVMPI_CallFrame кадров. Кроме того, я не знаю, каким должен быть третий параметр, переданный AsyncGetCallTrace (void ucontext)?

Вышеупомянутая проблема является основной, которую я имею. Тем не менее, другие проблемы, с которыми я столкнулся, включают в себя: [1] SIGPROF, кажется, не поднимается таймером точно через определенные промежутки времени, а немного реже. То есть, если я установил таймер для отправки SIGPROF каждую секунду (1 с, 0 мкс), то в 5-секундном запуске я получаю менее 5 выходных сигналов SIGPROF (обычно 1-3) [2] Обработчик SIGPROF выходы вообще не появляются во время Thread.sleep в коде Java. Таким образом, если SIGPROF отправляется каждую секунду, и у меня есть Thread.sleep (5000) ;, я не буду получать выходные данные обработчика во время выполнения этого кода.

Любая помощь будет оценена по достоинству. Дополнительная информация (а также части кода и выходные данные) будет отправлена ​​по запросу.

Спасибо!

+0

Я не могу помочь, но браво за то, что вы пытаетесь сделать! Кроме того, вы хотите, чтобы это было минимально навязчивым, но я думаю, что это действительно не нужно, потому что не нужно много образцов. Вы должны убедиться, что он может принимать образцы во время ожидания ввода-вывода. Вот общее пламя по этому вопросу: http://stackoverflow.com/questions/1777556/alternatives-to-gprof/1779343#1779343 –

+0

На самом деле так, как я это делал лет назад, на C было использовать SIGALRM. Вам нужно что-то, что инициирует, заблокирован ли поток (-ы). И, если это не особенно точно, это вообще не имеет значения. Важно то, что программа не влияет на выборку. –

+0

@Mike Dunlavey: Спасибо за информацию, но может быть несколько проблем с предлагаемым подходом: 1. Я хотел бы автоматизировать и обобщить этот процесс профилирования. То есть, мой JVMTI-код можно запускать с любым Java-клиентом и просто потребовать упоминания одного jvmarg (файла .so). Выполнение ручных перерывов каждый раз будет трудоемким и менее систематическим. – user400348

ответ

0

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

Структура ASGCT_CallTrace (и базовый массив ASGCT_CallFrame) может быть просто объявлена ​​в обработчике сигнала, таким образом, существующий только стек: ASGCT_CallTrace trace; JNIEnv * env; global_VM_pointer-> AttachCurrentThread ((void **) & env, NULL); trace.env_id = env; trace.num_frames = 0; ASGCT_CallFrame storage [25]; trace.frames = storage;

Следующие получают uContext: ucontext_t uContext; getcontext (& uContext);

И тогда вызов просто: AsyncGetCallTrace (& след, 25, & uContext);

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

Другие вопросы: [1] Если поток спал и генерируется SIGPROF, поток обрабатывает этот сигнал только после пробуждения. Это нормально, так как это задача потока для обработки сигнала. [2] Недостатки таймера больше не появляются. Возможно, я неправильно измерил.

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

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