LINUX.ORG.RU

[пришла весна] gcc выдает разные результаты при вызове из шелла и субпроцесса


0

0

Есть сгенерированный исходник на плюсах, содержащий два статически инициализированных массива структур и код между ними, примерно такого вида:

struct global_sym {
  char* name;
  void* target;
};

struct global_sym imported_syms[]={
  { 0, 0 }
};

//тут код, где объявляются нижеупомянутые ops_fed и reset_ops

struct global_sym exported_syms[]={
  { "ops_fed" , &ops_fed },
  { "reset_ops" , (void*) reset_ops },
  { 0, 0 }
};
В программе вызывается gcc для компиляции этого исходника:
 command = "gcc" + filename + " -c  -g -fPIC -o " + obj_name + " 2>&1";
 output = popen(command.c_str(),"r");
В скомпилированном таким способом коде отсутствует второй массив структур, nm такого символа не видит! Но первый массив присутствует:

0000000000000000 B imported_syms.

Во время выполнения программа выводит команду, которой выполняется компиляция. Так вот, если выполнить эту команду в шелле, то, как и должно быть, в объектнике появятся оба массива:

0000000000000000 D exported_syms

0000000000000000 B imported_syms

Собственно вопрос: почему gcc (3.4.6) считает себя в праве удалить массив и почему он этого не делает при вызове ручками (код, опции и компилятор тот же)?

хм… а …

command = "env -i gcc" + filename + " -c  -g -fPIC -o " + obj_name + " 2>&1";
… и …
bash$ env -i gcc $filename -c  -g -fPIC -o $obj_name 2>&1
… тоже выдают одинаковый результат?

arsi ★★★★★
()
Ответ на: комментарий от arsi

Нет, результаты все равно различаются. Попробовал в опции добавить -O0 (мало ли чего оптимизатору в голову придет), ничего не изменилось.

j-a-t-a
() автор топика
Ответ на: комментарий от j-a-t-a

хм… а если указать полностью «/usr/bin/gcc»? в обоих случаях эксперимент проводился под одним и тем же пользователем?

arsi ★★★★★
()
Ответ на: комментарий от arsi

Полный путь указывал, не помогает. Вызывается точно один и тот же компилятор.

Да, под одним пользователем. Сравнивал env'ы, отличий в PATH нет. Да и в остальном нет.

j-a-t-a
() автор топика
Ответ на: комментарий от j-a-t-a

Значит надо упростить программу, выделить минимальный проблемный кусок и дать его на анализ общественности лора.

anonymous
()
Ответ на: комментарий от anonymous

Возникла новая сложность. Попытаюсь разъяснить: программа транслирует скриптовый язык в плюсы, компилирует и подключает как библиотеку. На данный момент подключения еще нет, так как компиляция срабатывает странно. Соответственно, есть высокоуровневый метод Load, который состоит из вызовов методов Parse, Generate и Compile. Последние два никак не связаны, в Compile подается просто имя файла для компиляции.

Так вот, если в Load отключить все кроме Compile и подавать уже сгенерированный код (тот же самый), то все компилится правильно. Что слабо возможно, так как метод компиляции не изменился, компилируемый код тот же, а методы Parse и Generate вообще никак не связаны с Compile.

j-a-t-a
() автор топика
Ответ на: комментарий от j-a-t-a

Вместо этих глубоких размышлений, лучше сделать как сказал капитан в 03.03.2010 16:38:04

Chumka ★★★
()
Ответ на: комментарий от j-a-t-a

2 потенциальных глюка:
1. код сгенерирован, но еще не выдан в файл, как следствие компилируется
только часть
2. В процессе компиляции генерируется какой-то вывод, однако он
не читается и закрываемый файл грохает отдельную фазу
gcc (сомнительно, т.к. файл был бы более дерьмовым).

====
Защита ЛОР-а удолбала.

io ★★
()
Ответ на: комментарий от io

По первому пункту — компиляция начинается только после парсинга. Так что компиляция идет для всего файла или не идет вообще (в случае ошибок генерации).

По второму — при выполнении тех же команд ручками никакого вывода нет.

Буду искать скрытые связи между методами, иначе придется поверить в магию и летающих коров.

И да, всем спасибо.

j-a-t-a
() автор топика
Ответ на: комментарий от rymis

Уважаемые rymis и io, огромное вам спасибо! Все дело было в недостаточном знании потоков и их буферизации. generated_cpp.close() решило все проблемы. Два дня потрачены впустую.

Зато вера в летающих коров-вредителей и gcc, удаляющий секции по принципу русской рулетки, отменяется.

j-a-t-a
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.