Вопрос или проблема
У меня есть программа на C для построения простой гауссовой распределения. Однако каждый раз, когда я запускаю программу, я получаю эту ошибку:
gnuplot: ошибка поиска символа: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: неопределенный символ: __libc_pthread_init, версия GLIBC_PRIVATE
Пожалуйста, помогите
Я нашел возможное решение здесь: https://github.com/ros2/ros2/issues/1406
$ unset GTK_PATH
(Я не знаю, почему это работает или почему эта переменная задана в первую очередь).
Цитируя определение GTK_PATH
в Запуск GTK-приложений, из документации GTK (выделение моё):
Указывает список каталогов для поиска, когда GTK ищет динамически загружаемые объекты, такие как модули, указанные в
GTK_MODULES
, движки тем, модули ввода, бэкенды файловой системы и бэкенды печати.
Если путь к динамически загружаемому объекту задан как абсолютное имя пути, то GTK загружает его напрямую. В противном случае GTK поочередно проходит через каталоги в
GTK_PATH
, за которыми следует каталог.gtk-3.0
в домашнем каталоге пользователя, а затем системный каталог по умолчанию, который являетсяlibdir/gtk-3.0/modules
.
Когда GTK_PATH
задан, любой динамически загружаемый объект, содержащийся в каталоге, указанном в GTK_PATH
, будет иметь приоритет над тем же динамически загружаемым объектом, содержащимся в ~/.gtk-3.0
и /lib/x86_64-linux-gnu/gtk-3.0
.
Что, в свою очередь, означает: если версия библиотеки, найденной при обходе GTK_PATH
, проблемная, эта проблема проявится; если GTK_PATH
не задан, и первая найденная версия библиотеки в ~/.gtk-3.0
или /lib/x86_64-linux-gnu/gtk-3.0
не является проблемной, ошибка не проявится.
Что объясняет, почему unset GTK_PATH
работает; по сути, это заставляет приложение избежать проблемной версии библиотеки.
В вашем случае проблемная версия библиотеки находится в /snap/core20/current/lib/x86_64-linux-gnu
.
Многие люди, похоже, сталкиваются с такой проблемой, особенно в VSCode.
Если вы используете VSCode (но в принципе это применимо к любому приложению), у вас есть следующие альтернативные решения:
- Обновление приложения; в случае VSCode:
sudo snap refresh code
- Если вы находитесь в канале, отличном от
stable
(edge
/beta
/candidate
), переключение на каналstable
; в случае VSCodesudo snap refresh code --channel=stable
Если это не сработает, другой способ – убрать GTK_PATH
только для выполнения gnuplot
:
GTK_PATH= gnuplot [...]
Или, если вы действительно не хотите трогать GTK_PATH
, задать LD_PRELOAD
:
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libpthread.so.0 gnuplot [...]
В случае конкретно VSCode вы также можете убрать GTK_PATH
только для встроенного терминала; в settings.json
:
"terminal.integrated.env.linux": {
"GTK_PATH": null,
},
Ответ или решение
Проблема с ошибкой "undefined symbol" в gnuplot на языке C
Если вы столкнулись с ошибкой при запуске gnuplot, такой как:
gnuplot: symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE
это может свидетельствовать о конфликте между версиями библиотек, используемых вашим приложением и установленными системными библиотеками. В данном случае проблема, скорее всего, связана с переменной окружения GTK_PATH
, которая указывает пути к динамически загружаемым объектам GTK.
Причины возникновения проблемы
-
Конфликт версий библиотек: Если
GTK_PATH
настроен, gnuplot может пытаться загрузить библиотеки, которые могут содержать ошибки или быть несовместимыми с вашей версией системы. -
Использование Snap: Пакет Snap управляет зависимостями отдельно от остальной системы, что иногда может привести к конфликтам.
Решение проблемы
Ваше решение, связанное с использованием команды unset GTK_PATH
, является правильным и подтверждает, что сброс переменной окружения позволяет избежать загрузки нестабильной версии библиотеки.
Подробности решения:
-
Сброс переменной окружения
GTK_PATH
:- Откройте терминал и выполните команду:
unset GTK_PATH
Это позволит gnuplot загрузить версии библиотек из стандартного местоположения, избегая проблемы с конфликтующими версиями.
- Откройте терминал и выполните команду:
-
Однократное выполнение без изменения
GTK_PATH
:- Если вы не хотите изменять глобальную переменную, выполните команду для gnuplot так:
GTK_PATH= gnuplot
- Если вы не хотите изменять глобальную переменную, выполните команду для gnuplot так:
-
Использование
LD_PRELOAD
:- Альтернативный способ — использовать переменную
LD_PRELOAD
, чтобы явно указать linux библиотеке использовать конкретную версию:LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libpthread.so.0 gnuplot
- Альтернативный способ — использовать переменную
Варианты для Visual Studio Code (VSCode)
Если вы используете VSCode, проблемы могут возникать чаще. Предлагаемые решения:
-
Обновление приложения:
- Убедитесь, что у вас установлена последняя версия VSCode командой:
sudo snap refresh code
- Убедитесь, что у вас установлена последняя версия VSCode командой:
-
Переключение на стабильный канал:
- Если ваше приложение установлено из канала "edge", переключитесь на стабильный канал:
sudo snap refresh code --channel=stable
- Если ваше приложение установлено из канала "edge", переключитесь на стабильный канал:
-
Настройка интегрированного терминала:
- Чтобы изменить переменные окружения только для интегрированного терминала, добавьте следующую строку в
settings.json
:"terminal.integrated.env.linux": { "GTK_PATH": null, },
- Чтобы изменить переменные окружения только для интегрированного терминала, добавьте следующую строку в
Заключение
Ошибки с "undefined symbol" в контексте использования библиотек часто вызваны конфликтами версий или неправильными настройками переменных окружения. Сброс переменной GTK_PATH
или использование локальных настроек LD_PRELOAD
могут помочь разрешить проблему и обеспечить правильную работу gnuplot. Если ситуация сохраняется, рассмотрите возможность обновления или переустановки библиотек и ваших приложений для лучшей совместимости.