#linux #bash
#linux #bash
Вопрос:
Я не новичок в bash, но я впервые вижу, как это происходит.
[OP@localhost linking]$ ls
helloworld-lib.o helloworld-lib.s helloworld_s
[OP@localhost linking]$ ./helloworld_s
bash: ./helloworld_s: No such file or directory
Эта ошибка произошла, когда я тестировал компоновщик, ld
. Содержимое helloworld-lib.s
является:
[OP@localhost linking]$ cat helloworld-lib.s
.section .data
helloworld:
.ascii "Hello, world!n"
.section .text
.globl _start
_start:
mov $helloworld, %rdi
call printf
mov $0, %rdi
call exit
Этот файл helloworld_s
был создан следующим образом.
[OP@localhost linking]$ as helloworld-lib.s -o helloworld-lib.o
[OP@localhost linking]$ ld -lc helloworld-lib.o -o helloworld_s
УТОЧНИТЕ, является ли какая-либо из этих сведений актуальной. К вашему сведению, если я попытаюсь запустить другие файлы, я просто получу отказ в разрешении (как и ожидалось). Есть идеи?
РЕДАКТИРОВАТЬ: как и предлагалось, вот вывод ls -l
:
[OP@localhost linking]$ ls -l
total 88
-rw-rw-r--. 1 OP OP 968 Mar 23 18:40 helloworld-lib.o
-rw-rw-r--. 1 OP OP 159 Mar 23 18:40 helloworld-lib.s
-rwxrwxr-x. 1 OP OP 14384 Mar 23 18:41 helloworld_s
вот вывод id
:
[OP@localhost linking]$ id
uid=1000(OP) gid=1000(OP) groups=1000(OP),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
РЕДАКТИРОВАТЬ: ответ см. в комментариях. Смотрите здесь
Комментарии:
1. @Kenster Я не верю, что это так. Например, я могу
cat
получить файл без проблем. Используяbasename
, я не нахожу ничего необычного в имени файла.2. Добавьте вывод
ls -l
иid
к вашему вопросу.3. Скорее всего,
ldd
скажет вам, что он ищет что-то подобное,/lib/ld64.so.1
чего не существует.4. @DavidSchwartz о, да, действительно.
readelf -l helloworld_s
сообщает мне, что программа запрашивает интерпретатор/lib/ld64.so.1
, который, как вы говорите, не существует. Итак, очевидно, что здесь что-то не так. Когда я явно указываю интерпретатор как/usr/lib64/ld-linux-x86-64.so.2
, все работает. Во-первых, не могли бы вы опубликовать это в качестве ответа? Но также, если это так, почему я получаю это как свою ошибку? И, кроме того, почему компоновщик GNU по умолчанию запрашивает программный интерпретатор, который не существует?5. Можем ли мы получить это в ответе и пометить это как ответ или закрыть?
Ответ №1:
Как объясняется в redhat ошибка # 868662 , рекомендуемый способ связать — разрешить gcc вызывать ld, как показано ниже;
> gcc -nostartfiles helloworld-lib.o -o helloworld_s -lc
Что приводит к правильному связыванию;
> ldd helloworld_s
linux-vdso.so.1 => (0x00007ffd283bf000)
libc.so.6 => /lib64/libc.so.6 (0x00007fd011b62000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd011f2f000)
И выполнение проходит нормально;
> ./helloworld_s
Hello, world!
Почему ld ссылается на /lib/ld64.so.1, который не существует?
Потому что это настройка по умолчанию для общей системы, а не только для Linux.
Ответ №2:
Существующие исполняемые файлы могут ошибочно сообщаться как отсутствующие при обстоятельствах, когда фактическая проблема заключается в том, что они не могут быть выполнены.
Фактические причины различны, но включают такие вещи, как
-
файл неисправен, возможно, в результате неправильной ссылки, как указано в другом ответе
-
файл предназначен для другой архитектуры или ABI, не поддерживаемой платформой
-
в файле отсутствует бит разрешения на выполнение для пользователя, пытающегося это сделать
-
файл находится на томе, смонтированном с флагами, запрещающими выполнение
Во многих из этих случаев ясно, что предпочтительнее было бы более конкретное и релевантное сообщение об ошибке, однако иногда то, что фактически реализовано (или вызвано менее очевидными путями сбоя), действительно может сбивать с толку в смысле обозначения чего-то «непригодного» как «отсутствующего». Точность ошибок может несколько различаться в разных средах.