繁体   English   中英

__libc_start_main()中基于C的远程CGI脚本崩溃

[英]Remote C-based CGI Script Crashing In __libc_start_main()

我有一个用C编写的CGI脚本。我知道这在当今时代是非正统的,但是我有我的理由。 而且,它是使用-static编译的,因此我不必担心Web提供程序上的共享库。 该脚本已经运行了一年多了,但是最近就坏了。 众所周知,调试问题也很困难,因为脚本在我的Web提供商的服务上崩溃了,并且我的可见度不高。 但是我确实得到了核心转储。

我看到的问题是:在远程服务器上,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;
}

使用gcc在64位Linux上编译:

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'

但是,当我将此二进制文件放到Web提供程序的Apache cgi-bin目录中时,出现500内部服务器错误。 崩溃后,服务器留下了编号的核心转储,然后我使用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进行调查)。

我找到了一个解决方案,并希望将其发布,因为这些Stack Overflow问题可以让自己在Google的最佳搜索结果中找到自己的位置。

最终,我计划通过将这一功能转移到我具有更好的调试可见性的其他服务器或平台上来解决此问题。 同时,我认为由于问题似乎是使用-static进行编译的一种表现,并且因为无法将必需的共享库安装到共享宿主系统上的标准lib目录中,所以我将采用动态方法。 我将必要的共享库上载到与编译脚本相同的目录中,并重新处理了基于C的CGI脚本,以使用dlopen / dlsym动态打开共享库,获取所需的函数指针,然后调用这些指针。

在研究其他解决方案时,这种方法行得通(尽管我一直保持手指交叉,不会再神秘地折断)。 如果其他人遇到这些奇怪的问题,也许这会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM