Получить адрес памяти загруженных сборок

После включения уровня журнала отладки для весны и прохождения обширных журналов я обнаружил, что сканирование для различных компонентов, таких как JPA-репозитории, JPA-объекты и т. д., зависит от имени пакета Application.java.

Если репозитории JPA или Entities не находятся в подпакетах пакета Application.java, тогда нам нужно явно указать их следующим образом:

@Configuration
@ComponentScan(basePackages="com.sivalabs.jcart")
@EnableAutoConfiguration
@EnableJpaRepositories(basePackages="com.sivalabs.jcart")
@EntityScan(basePackages="com.sivalabs.jcart")
public class Application{

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

С помощью вышеуказанных дополнительных @EnableJpaRepositories, @EntityScan я могу запускать он использует Run As -> Java Application.

Но все еще не уверен, как он работает нормально, когда Run As -> Spring Boot App !!

В любом случае, я думаю, что лучше двигаться мой пакет Application.java до com.myapp, а не борьба с SpringBoot!

2
задан ThisMeansWar 2 March 2019 в 14:11
поделиться

1 ответ

Я не уверен, ищете ли вы (1) виртуальный адрес сопоставленного файла сборки или (2) виртуальный адрес, на котором код JITed помещается после загрузки сборки.

Далее я рассмотрю простой случай, когда хост-процесс загружает несколько сборок. Код можно найти здесь . Давайте сосредоточимся на том, что происходит, когда загружается x64_Assembly.dll .

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

enter image description here

Для (2), это виртуальный адрес, где находится JIT-код сборки, вы можете увидеть соответствующий адрес, если вы войдите в свой код с помощью отладчика:

enter image description here

Когда указывает этот поток , сборка JITed помещается в куча, которую вы можете легко проверить с помощью VMMap снова. В моем случае адрес, показанный в отладчике, можно увидеть в блоке кучи с VMMap:

enter image description here

Так какой адрес вы на самом деле нацеливание?

Позднее обновление : Вы можете использовать CLR MD для получения очень интересных данных. Взгляните на простой код, приведенный ниже (взят из «Написание высокопроизводительного кода .NET» Бена Уотсона), который получает (1) и , возможно, (2). Вы можете видеть, что адрес образа загруженной сборки в VMMap совпадает со значением module.ImageBase, поэтому вы обязательно получите (1). Для (2), однако, значение module.Address НЕ совпадает с переменной m_assembly, замеченной в отладчике в моем исходном ответе - поэтому один из них показывает что-то еще. Однако, если вы подумаете об этом, не весь код JITed одновременно - вместо этого CLR будет JIT компилировать методы так, как (и если) они вызываются. Поэтому я считаю, что виртуальные адреса, содержащиеся в 2 переменных, указывают на некоторую общую структуру, представляющую сборку.

enter image description here

Поскольку вы упомянули, что у вас есть доступ для проверки содержимого памяти, вы можете довольно быстро выяснить, какая из двух переменных представляет интерес ( 2). [+1135] 1136 Как вы могли это сделать на практике? Я имею в виду создание проекта CLR MD, который просто выводит информацию, которую вы ищете ((1) и (2), в простой файл)), а затем запускает этот EXE-файл вашим основным кодом, чтобы он анализировал ваш процесс и сборка он загружает и записывает данные. Когда процесс CLR MD завершается, ваш реальный код может получить информацию, записанную в файле, и работать с теми виртуальными адресами, которые он получил. В моем примере выше PID был просто жестко закодирован (я использовал Process Explorer, чтобы увидеть назначенный PID), но вы, вероятно, могли бы передать его в качестве аргумента в свой проект CLR MD.

Вы можете использовать опцию Управление пакетами NuGet для решения в Visual Studio, чтобы установить CLR MD и настроить его для своего конкретного проекта, а затем просто добавить using Microsoft.Diagnostics.Runtime.

2 вещи, которые нужно иметь в виду:

  • «битность» используемого вами кода CLR MD должна соответствовать анализируемому вами процессу (например, не создавать его). для x86 и другой для x64; все подробности о сборках и загрузке между битами приведены в статье, на которую я ранее ссылался )
  • , которую вы должны будете использовать AttachFlag.Passive в метод AttachToProcess, иначе ваш исходный код будет приостановлен на неопределенный срок. Я также проверил эту опцию после того, как сделал снимок экрана выше и успешно получил значения module.ImageBase и module.Address, плюс исходный код продолжал работать просто отлично.
0
ответ дан Mihai Albert 2 March 2019 в 14:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: