c - 带有 valgrind 的 G-WAN?备择方案?

标签 c valgrind g-wan

G-WAN 是一种开箱即用的在 Web 上运行 C 代码的便捷方式,但对我而言,它不适用于 valgrind。 (运行 valgrind ./gwan 出现错误消息 Inconsistency detected by ld.so: rtld.c: 1292: dl_main: Assertion `_rtld_local._dl_rtld_map.l_libname' failed!然后退出;系统是 Debian Jessie 64 位)。

问题是:
1) G-WAN 是否应该与 valgrind 一起工作?
2) 是否有任何其他可行的选项来检测在 G-WAN 下运行的 C 代码中的内存错误?

最佳答案

Is G-WAN supposed to work with valgrind?

我们已经测试了 Valgrind,虽然它可以做很多事情,但它不适合高并发作业(即使是低并发也是 Valgrind 的问题)。

viable options to detect memory bugs in C code running under G-WAN?

使用 malloc() 包装器、预分配池,或者更好的是,使用 alloca() 从一开始就避免内存问题。

请注意,G-WAN 可在不导致服务器崩溃的情况下处理 C 脚本中的错误指针,请参阅:http://gwan.ch/developers#crash

这个错误代码:

int main(int argc, char *argv[])
{
   strcpy(0xBADC0DE, 0xBADC0DE);
   return 200;
}

...将生成类似于以下“优雅”崩溃报告的内容:

Script: crash_libc.c
 Client: 127.0.0.1
 Query : ?crash_libc

 Signal        : 11:Address not mapped to object
 Signal src    : 1:SEGV_MAPERR
 errno         : 0
 Thread        : 0
 Code   Pointer: 0000f5200b33 (module:/lib/libc.so.6, function:strcpy, line:0)
 Access Address: 00000badc0de

 Registers     : EAX=00000badc0de CS=00000033 EIP=0000f5200b33 EFLGS=000000010202
                 EBX=000000000001 SS=ec2d8ed4 ESP=0000f5ded828 EBP=0000f5dee020
                 ECX=000033323130 DS=ec2d8ed4 ESI=0000ec2d8f86 FS=00000033
                 EDX=000003b03c00 ES=ec2d8ed4 EDI=00000badc0de CS=00000033

 Module        :Function        :Line # PgrmCntr(EIP)  RetAddress  FramePtr(EBP)
      libc.so.6:          strcpy:     - 0000f5200b33 0000ec2d8f00   0000f5dee020
        servlet:            main:    37 0000ec2d8f00 00000042e10c   0000f5dee020        

G-WAN 甚至会告诉您源代码中错误发生的位置(请参阅 G-WAN crash_xxx.c 示例),而不是终止服务器进程。

如果您不想调试 C 代码,则使用 Java 或 Scala(G-WAN 均支持)——您将需要更多内存,因为您的数据将保持加载状态,直到 GC 减慢所有内容以释放内存它认为可以被释放——但至少你会享受到更少的与内存相关的错误,如果有的话。


应提问者的要求,这里有更多的细节。

在 2012 年底,我们测试了十几种免费和商业工具,如 Valgrind,它们应该有助于调试并发性。我们还使用静态工具研究源代码,而不仅仅是用于运行(编译)程序的动态工具。

可悲的事实是,他们都有共同的问题,他们:

  • 通常太慢而无法支持并发(核心问题)
  • 产生大量的琐碎警报(甚至更多错误警报)
  • 非常昂贵(当然是商业产品)并且不能总是在购买前进行测试(!)

因此,经过数周的检查和过滤所有这些结果后,我们花了很多时间“纠正”G-WAN 代码库以删除琐碎的错误警报(由无法区分有效代码和错误代码的工具引起的警报代码)...但是,当时令我们沮丧的是,我们没有在 G-WAN 中发现任何真正的错误(明确表示那几周是浪费时间)。

因此得出以上结论:尽可能编写简单的代码,并在需要更复杂的策略时尝试预分配 block 。

当然,Linux LIBC 坚持使用(不可捕获的)abort 信号杀死应用程序这一事实无济于事(这会阻止程序恢复或转储相关跟踪),尤其是对于草率的 double-free Linux LIBC 检测(它错误地假设所有代码都在使用它的 malloc(),而当一个程序使用过 malloc() 一次——这通常是由 LIBC 调用完成的!)。我什至不是在谈论 mmap() 失败,也不是在谈论 OOM 终止开关。

到目前为止,我们发现唯一有效的解决方案是避免使用 Linux LIBC,并使用我们自己的 C 运行时编译我们需要的一切。这有点难以向所有用户推荐“要做的事情”,但它对我们有用。

我们很高兴看到我们的部分代码(或者至少是 G-WAN 中实现的一些概念)被 Linux 使用,因为这将使我们(以及许多其他开发人员之一)的生活变得更加轻松,但我们过去与“负责人”的接触并不令人鼓舞。

总而言之,操作系统、像我们这样的 ISV 以及开发人员都有改进的空间 - 毕竟,自 2004 年以来,并发“只是”主流......差不多十年前。

关于c - 带有 valgrind 的 G-WAN?备择方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17659619/

相关文章:

从 valgrind 的 callgrind 输出过滤对 libc 的调用

c++ - 矩阵类的 4 写入大小无效(使用 valgrind)

c - Axis2C内存泄漏?

c - G-WAN 在处理程序中持久化请求数据

c - 我如何在 C 中将 int 转换为 char

c - 在 while 循环中使用函数(在 Atom 中有效,但在 VIM 中无效)

mysql - Windows 下最基本的 MySQL UDF 代码

c - G-WAN 类似物

c - G-wan xbuf_xcat(),难道是内存泄露?

c - 相当于cuda中的memalign