Почему IntelliJ говорит & ldquo; переменная debug info недоступна & rdquo; [Дубликат]

Это одно из самых запутанных сообщений об ошибках, которые каждый программист VC ++ видел снова и снова. Давайте сначала сделаем чёткость.

A. Что такое символ? Короче говоря, символ - это имя. Это может быть имя переменной, имя функции, имя класса, имя typedef или что-либо кроме тех имен и знаков, которые принадлежат языку C ++. Он определяется пользователем или вводится библиотекой зависимостей (другой пользовательский).

B. Что является внешним? В VC ++ каждый исходный файл (.cpp, .c и т. Д.) Рассматривается как единица перевода, компилятор компилирует по одному модулю за раз и генерирует один объектный файл (.obj) для текущей единицы перевода. (Обратите внимание, что каждый заголовочный файл, включенный в этот исходный файл, будет предварительно обработан и будет рассматриваться как часть этой единицы перевода). Все внутри единицы перевода считается внутренним, все остальное считается внешним. В C ++ вы можете ссылаться на внешний символ, используя ключевые слова, такие как extern, __declspec (dllimport) и т. Д.

C. Что такое «решимость»? Resolve - термин времени связывания. Во время компоновки линкер пытается найти внешнее определение для каждого символа в объектных файлах, которые не могут найти свое определение внутри. Объем этого процесса поиска, включая:

  • Все объектные файлы, сгенерированные во время компиляции
  • Все библиотеки (.lib), которые явно или неявно указаны как дополнительные зависимости это строительное приложение.

Этот процесс поиска называется разрешением.

D. Наконец, почему Unresolved External Symbol? Если компоновщик не может найти внешнее определение для символа, который не имеет определения внутри, он сообщает об ошибке неразрешенного внешнего символа.

E. Возможные причины LNK2019: ошибка неразрешенного внешнего символа. Мы уже знаем, что эта ошибка связана с тем, что компоновщик не смог найти определение внешних символов, возможные причины могут быть отсортированы как:

  1. Определение существует

Например, если у нас есть функция foo, определенная в a.cpp:

int foo()
{
    return 0;
}

В b.cpp мы хотим вызвать функцию foo, поэтому добавим

void foo();

, чтобы объявить функцию foo () и вызвать ее в другом теле функции, скажем bar():

void bar()
{
    foo();
}

Теперь, когда вы создаете этот код, вы получите ошибку LNK2019, жалуясь, что foo является неразрешенным символом , В этом случае мы знаем, что foo () имеет свое определение в a.cpp, но отличается от того, которое мы вызываем (другое возвращаемое значение). Это означает, что определение существует.

  1. Определение не существует

Если мы хотим вызвать некоторые функции в библиотеке, но библиотека импорта не добавлен в дополнительный список зависимостей (установленный из: Project | Properties | Configuration Properties | Linker | Input | Additional Dependency) вашего проекта. Теперь компоновщик сообщит LNK2019, поскольку определение не существует в текущей области поиска.

38
задан Amitābha 15 August 2013 в 16:01
поделиться

5 ответов

Вообще говоря, чтобы иметь возможность наблюдать за переменными при переходе через исходный код JDK, вам нужны файлы классов, которые должны быть скомпилированы с помощью отладочной информации, т. е. скомпилировать с помощью javac -g.

Итак, ваш лучший выбор либо найти уже скомпилированную версию с отладочной информацией (я ничего не мог найти для JDK 7), или вы можете попробовать скомпилировать источник для себя.

Согласно этот пост ( обратите внимание, что я не пробовал) вам не нужно собирать все источники, только те, которые вам нужны. Поместите ваши вновь скомпилированные классы в каталог $jdk/jre/lib/ ext / endorsed, вместо этого будут использоваться новые классы в оригинале rt.jar.

Я считаю, что вам нужно начать.

Обновление: На самом деле я только что пробовал этот процесс, и это совсем не сложно. Протестировано в Windows, JDK 1.7.0_11. Все команды вызываются из командной строки:

  1. Создайте свою рабочую папку. Я выбрал d:\ корневую папку
  2. . Внутри рабочей папки создайте исходную папку, то есть jdk7_src и папку вывода jdk_debug
  3. Из папки JDK_HOME получите src.zip файл и разархивируйте его внутри jdk7_src
  4. Выберите то, что вы будете компилировать и удалить остальные. Для всех вас могут потребоваться дополнительные шаги. Я выбрал папки: java javax org
  5. Из вашего JDK_HOME\jre\lib получить файл rt.jar и поместить в рабочую папку (это только для удобства не указывать слишком большие имена файлов в командной строке).
  6. Выполните команду: dir /B /S /X jdk7_src\*.java > filelist.txt, чтобы создать файл с именем filelist.txt со списком всех java-файлов, которые будут скомпилированы. Это будет указано в качестве входных данных для javac
  7. Выполнить javac с помощью команды: javac -J-Xms16m -J-Xmx1024m -sourcepath d:\jdk7_src -cp d:\rt.jar -d d:\jdk_debug -g @filelist.txt >> log.txt 2>&1 Это скомпилирует все файлы в папке jdk_debug и сгенерирует файл log.txt в вашем рабочей папки. Проверьте содержимое журнала. Вы должны получить кучу предупреждений, но без ошибок.
  8. Зайдите в папку jdk_debug и запустите команду: jar cf0 rt_debug.jar *. Это создаст вашу новую библиотеку времени исполнения с информацией о деградации.
  9. Скопируйте эту новую банку в папку JDK_HOME\jre\lib\endorsed. Если папка endorsed не существует, создайте ее.

Отлаживайте свою программу в Eclipse. Обратите внимание, как переменные называются нормально (не более arg0, arg1 и т. Д.). Счастливая отладка:)

JDK debug [/g1]

70
ответ дан c.s. 28 August 2018 в 19:40
поделиться

Как вы знаете, одобренный механизм переопределения устарел и будет удален в будущей версии ( http://docs.oracle.com/javase/8/docs/technotes /guides/standards/).

Используйте этот pom.xml для получения источников JDK 1.8.0_111 с информацией об отладке:

<project>

  <modelVersion>4.0.0</modelVersion>
  <name>JDK sources with debug information</name>

  <groupId>ex.jdk.debug</groupId>
  <artifactId>jdk-debug-sources</artifactId>
  <version>1.8.0_111</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>com.oracle</groupId>
      <artifactId>jdk-rt</artifactId>
      <version>1.8.0_111</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.6.0</version>
        <configuration>
          <debug>true</debug>
          <debuglevel>lines,vars,source</debuglevel>
          <source>1.8</source>
          <target>1.8</target>
          <excludes>
            <exclude>com/sun/java/swing/**</exclude>
            <exclude>com/sun/source/util/**</exclude>
          </excludes>
        </configuration>
      </plugin>

    </plugins>
  </build>

 </project>

Вам нужно будет сделать mvn clean install

mvn install:install-file -Dfile=rt.jar -DgroupId=com.oracle -DartifactId=jdk-rt -Dversion=1.8.0_111 -Dpackaging=jar

. rt.jar Я скопировал в каталог endorsed исходный rt.jar, но с исходными классами заменены моими новыми классами.

0
ответ дан aliopi 28 August 2018 в 19:40
поделиться

Эта статья http://www.thejavageek.com/2016/04/03/debug-jdk-source-code/ описывает то же самое, но простым и приятным способом. Вы делаете материал (компилируете, делаете банку), используя только eclipse.

0
ответ дан Andrew 28 August 2018 в 19:40
поделиться

Если кому-то это нужно с tomcat. Вам нужно настроить аргумент VM Djava.endorsed.dirs и поместить в него собранный jdk jar. Вы можете сделать это решение cs или экспортировать с помощью eclipse (все Java Compiler ClassFile Generation, используемое отладчиком, должно быть активным)

Перейти к Run Configurations> Arguments> Аргументы VM

Djava.endorsed.dirs = "/ ваша / папка / апач-кот-ххх / одобрил"

0
ответ дан PbxMan 28 August 2018 в 19:40
поделиться

Решение s-s's jre \ lib \ одобрено отлично. Проще построить с помощью Eclipse: создать проект Java, поместить javax *, java * в src и разрешить компиляцию Eclipse. Затем экспортируйте банку.

13
ответ дан weberjn 28 August 2018 в 19:40
поделиться
Другие вопросы по тегам:

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