У меня есть сценарий CGI, написанный на C. Я знаю, что это неортодоксально в наше время, но у меня есть свои причины. Кроме того, он скомпилирован с помощью -static
, поэтому мне не нужно беспокоиться об общих библиотеках моего веб-провайдера. Скрипт работает нормально уже больше года, но недавно сломался. Также общеизвестно, что отладить проблему очень сложно, потому что скрипт дает сбой в службе моего веб-провайдера, и я не получаю много информации. Но я получаю дампы ядра.
Проблема, которую я вижу: На удаленном сервере происходит сбой сценария CGI, и ошибка, по-видимому, исходит из кода запуска, т. е. того, что выполняется до того, как моя функция main() когда-либо будет достигнута ( __libc_start_main()
).
Я создал SSCCE, иллюстрирующий проблему, с именем hey.c
:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("Content-type: text/plain\n\n");
printf("Hey, is this thing on?\n");
printf("query string: '%s'\n", getenv("REQUEST_URI"));
return 0;
}
Скомпилировано на 64-битном Linux с помощью gcc:
gcc -g -Wall hey.c -o hey.cgi -static
Работает нормально из подсказки:
$ REQUEST_URI="q=querystring" ./hey.cgi
Content-type: text/plain
Hey, is this thing on?
query string: 'q=querystring'
Когда я запускаю его локально на установке Apache (например, http://localserver/cgi-bin/hey.cgi?q=query
), веб-страница показывает:
Hey, is this thing on?
query string: '/cgi-bin/hey.cgi?q=query'
Однако, когда я помещаю этот двоичный файл в каталог Apache cgi-bin моего веб-провайдера, я получаю 500 Internal Server Error. После сбоя сервер оставляет пронумерованные дампы ядра, которые я затем загружаю и проверяю с помощью gdb:
Core was generated by `hey.cgi'.
Program terminated with signal 11, Segmentation fault.
#0 0x000000000041b763 in __syscall_error ()
(gdb) bt
#0 0x000000000041b763 in __syscall_error ()
#1 0x0000000000402569 in __libc_message ()
#2 0x000000000040283c in __libc_fatal ()
#3 0x0000000000401355 in __libc_start_main ()
#4 0x0000000000401081 in _start ()
Я знаю, что много низкоуровневых деталей, но, надеюсь, проблема очевидна для кого-то из Stack Overflow. Спасибо.
Более подробная информация в соответствии с комментариями: я проверил с помощью простого скрипта Python CGI (и os.environ[]
), что REQUEST_URI определен. Я думаю, что это основа протокола CGI, но я не эксперт.
file
сообщает о статически связанном двоичном файле x86-64; ldd
сообщает «не динамический исполняемый файл». Libtool никогда не вступает в игру — я использую один вызов команды gcc
для создания всего сценария.
Идеально было бы компилировать скрипт на сервере. Если бы у меня был такой доступ, у меня, вероятно, было бы достаточно гибкости, чтобы избежать этого подхода. Я не беспокоюсь о защите источника; это было просто лучшее решение, которое я мог найти для своей проблемы. Рассматриваемая программа представляет собой пользовательскую поисковую систему для моего сайта, состоящую примерно из 20 строк C для взаимодействия с библиотекой под названием SWISH-E. Мой веб-провайдер не предоставляет слишком много возможностей, но я смог это сделать.
Другие решения включают в себя: перенос на другой хостинг (много хлопот); найти чистое решение на основе PHP, которое будет поддерживаться на моем хосте (я исследую это через mnoGoSearch).
getenv
вернет значение null, и его чтение будет иметь неопределенное поведение. - person jcm   schedule 01.12.2013libtool
печально известен тем, что отказывается соблюдать-static
, и также может случиться так, что некоторые динамические библиотеки будут использоваться, если вам не хватает их статических версий в системе, где вы компилируете. Используйтеldd
,file
и т. д. для проверки. - person R.. GitHub STOP HELPING ICE   schedule 01.12.2013