Как правильно написать обработчик SIGPROF, который вызывает AsyncGetCallTrace?

StackOverflow https://stackoverflow.com/questions/3426537

Вопрос

Я пишу короткий и простой профилировщик (на 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 .

Чего не хватает в этом блоге, так это кода для фактического вызова функции в обработчике сигналов (автор предполагает, что читатель может сделать это самостоятельно).Я прошу помощи именно в этом.Я не уверен, как и где создать структуру 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 usec), то за 5 секунд выполнения я получаю менее 5 выходных данных обработчика SIGPROF (обычно 1-3) [2] Выходные данные обработчика SIGPROF вообще не отображаются во время Thread.sleep в Java-коде.Итак, если SIGPROF должен отправляться каждую секунду, и у меня есть Thread.sleep(5000);, я не получу никаких выходных данных обработчика во время выполнения этого кода.

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

Спасибо!

Это было полезно?

Решение

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

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

Следующее возвращает uContext:ucontext_t uContext;getcontext(&uContext);

И тогда звонок просто:AsyncGetCallTrace(&trace, 25, &uContext);

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top