Мой начальник хочет, чтобы я посмотрел, могу ли я написать «проверку на утечку памяти в одну кнопку» в нашем Java-клиенте для наших тестировщиков (поскольку тогда мне пришлось бы тратить меньше времени на самому запуску нашего полного набора ручных тестов под профилировщиком; мы не иметь автоматизированный набор тестов).
Я нашел то, что довольно близко к тому, что мне нужно: Куча ходок Мне пришлось немного изменить его, чтобы скомпилировать в VS в Windows (я думаю, что это было сделано для GCC под Mac). Но когда я запускаю его, JVM падает.
Я хотел бы получить собственный трассировку стека, чтобы увидеть, по крайней мере, где он падает, и если я могу узнать, что происходит, но не знаю, как. Я построил «отладочную» DLL, но я все еще не получаю трассировку стека. Ни в консоли, ни в файле «hs_err_pidXXXX.log», созданном JVM.
Я не делал никаких C / C ++ около 15 лет; Я все еще могу «угадать», что делает код, но я забыл, как идет отладка (за исключением «printf везде» …), и мне никогда не приходилось отлаживать нативный код в JVM. До сих пор Google не помогал; Я, вероятно, использую неправильные термины для поиска.
JVM обычно сообщает о трассировке собственного стека в аварийном дампе. Если в стеке нет трассировки hs_err_pid.log
это означает, что JVM не может получить последний кадр из регистра ПК, как правило, потому что он указывает на нечитаемый адрес.
Например, это может произойти, если собственный код разыменовывает нулевой указатель на функцию:
void (*func)() = 0;
func();
В этом случае ПК будет равен нулю, а JVM не будет печатать трассу. Но вы все равно можете найти вызывающий ПК из стека, потому что адрес возврата обычно помещается в стек перед вызовом. Вот как это найти в hs_err_pid.log
:
Top of Stack: (sp=0x0000000002e2f438)
0x0000000002e2f438: 00007ffcf03f1030 00007ffcf041d000
^^^^^^^^^^^^^^^^
the return address (the address after the last valid instruction)
Тогда вы можете найти этот адрес в Dynamic libraries
раздел и рассчитать смещение от начала dll.
Dynamic libraries:
...
0x00007ffcf03f0000 - 0x00007ffcf0426000 C:\Java\Test\crash.dll
^^^^^^^^^^^^^^^^^^
offset = 0x00007ffcf03f1030 - 0x00007ffcf03f0000 = 0x1030
Используйте дизассемблер (например, Visual Studio DUMPBIN) декодировать предложение в конкретную функцию / инструкцию в коде.
Вы также можете присоединить отладчик Visual Studio к JVM, когда он выходит из строя. Для этого вы должны запустить Java с -XX:+ShowMessageBoxOnError
, Следующее окно предложит вам подключить отладчик:
Других решений пока нет …