Я пытаюсь разыскать очень нечетный катастрофический отказ. То, что так нечетно об этом, является обходным решением, что кто-то обнаружил и который я не могу объяснить.
Обходное решение является этой небольшой программой, которую я назову 'бегуном':
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
if (argc == 1)
{
fprintf(stderr, "Usage: %s prog [args ...]\n", argv[0]);
return 1;
}
execvp(argv[1], argv + 1);
fprintf(stderr, "execv failed: %s\n", strerror(errno));
// If exec returns because the program is not found or we
// don't have the appropriate permission
return 255;
}
Как Вы видите, вся эта программа делает использовать execvp
заменять себя другой программой.
Программа отказывает, когда она непосредственно вызывается из командной строки:
/path/to/prog args # this crashes
но хорошо работает, когда это косвенно вызывается через мой контейнер бегуна:
/path/to/runner /path/to/prog args # works successfully
Ни за что в жизни я могу выяснить, как наличие дополнительного должностного лица может изменить поведение запущенной программы (поскольку Вы видите, что программа не изменяет среду).
Некоторый фон на катастрофическом отказе. Сам катастрофический отказ происходит во времени выполнения C++. А именно, когда программа делает a throw
, отказывающая версия неправильно думает, что нет никакой выгоды соответствия (хотя существует), и вызовы terminate
. Когда я вызываю программу через бегуна, исключение правильно поймано.
Моим вопросом является какая-либо идея, почему дополнительное должностное лицо изменяет поведение exec'ed программы?
Возможно, файлы .so, загруженные бегуном, вызывают правильную работу руны. Попробуйте запустить каждый из двоичных файлов и посмотрите, загружают ли какие-либо библиотеки разные версии / места.
Как выстрел в темноте: двойной exec может изменить порядок переменных окружения в ОЗУ.
Среда - это структура памяти с указателями; ядро копирует эту структуру в адресное пространство нового процесса. Фактический порядок элементов в ОЗУ может измениться во время этого копирования (переменные среды семантически не упорядочены, но адреса в ОЗУ имеют порядок). С двумя exec () порядок может быть изменен дважды.
То, что изменение порядка строк в ОЗУ обнаруживает ошибку, несколько странно, но случаются и более странные вещи.
Интересно, передаете ли вы в argv [0] что-то другое, чем оболочка. Я не могу понять, что вы пишете выше, но возможно, что вы устанавливаете argv [0] как фактический первый аргумент программы, тогда как оболочка устанавливает его на свое названное имя (например, полный или короткий путь )
Возможно, в вызываемой программе произошла утечка памяти. Попробуйте запустить его с помощью valgrind или другого инструмента проверки памяти. После того, как у вас возникла ошибка памяти, все остальное будет неопределенным (так что все может случиться).
Думаю, две вещи, которые вы могли бы сравнить между «работающей» и «аварийной» версиями - дескрипторы открытых файлов и обработчики сигналов - поскольку они передаются exec .
Я не понимаю, в чем проблема / чем они отличаются, но, возможно, стоит их устранить.