繁体   English   中英

使用glut和std :: string时main()之前的分段错误?

[英]Segmentation Fault before main() when using glut, and std::string?

在64位Ubuntu 14.04 LTS上,我正在尝试编译一个使用过剩的简单OpenGL程序。 我在main中执行任何代码行之前得到了一个Segmentation Fault(SIGSEV); 即使是在一个非常简单的测试计划上。 什么可能导致这个?

我的命令行:

g ++ -Wall -g main.cpp -lglut -lGL -lGLU -o main

我的简单测试案例:

#include <GL/gl.h>                                                                                                                                         
#include <GL/glu.h>
#include <GL/glut.h>

#include <string>
#include <cstdio>

int main(int argc, char** argv){
    printf("Started\n");                                                                                                   
    std::string dummy = "hello";
    glutInit(&argc, argv);
    return 0;
}

当我运行程序时,main开头的printf无法在segfault之前执行。 在GDB下,我在segfault之后得到了这个回溯

#0  0x0000000000000000 in ?? ()
#1  0x00007ffff3488291 in init () at dlerror.c:177
#2  0x00007ffff34886d7 in _dlerror_run (operate=operate@entry=0x7ffff3488130 <dlsym_doit>, args=args@entry=0x7fffffffddf0) at dlerror.c:129
#3  0x00007ffff3488198 in __dlsym (handle=<optimized out>, name=<optimized out>) at dlsym.c:70
#4  0x00007ffff702628e in ?? () from /usr/lib/nvidia-352/libGL.so.1
#5  0x00007ffff6fd1aa7 in ?? () from /usr/lib/nvidia-352/libGL.so.1
#6  0x00007ffff7dea0fd in call_init (l=0x7ffff7fd39c8, argc=argc@entry=1, argv=argv@entry=0x7fffffffdf48, env=env@entry=0x7fffffffdf58) at dl-init.c:64
#7  0x00007ffff7dea223 in call_init (env=<optimized out>, argv=<optimized out>, argc=<optimized out>, l=<optimized out>) at dl-init.c:36
#8  _dl_init (main_map=0x7ffff7ffe1c8, argc=1, argv=0x7fffffffdf48, env=0x7fffffffdf58) at dl-init.c:126
#9  0x00007ffff7ddb30a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#10 0x0000000000000001 in ?? ()
#11 0x00007fffffffe2ba in ?? ()
#12 0x0000000000000000 in ?? ()

这是踢球者。 如果我注释掉无论是gluInit线或的std :: string虚拟线,程序编译和运行就好了。 直到我注意到这一点,我认为我的GLUT有问题(虽然我已经尝试了我正在调试的原始程序(我已经剥离了这个例子))几个系统没有成功。 我在这里有点不知所措。

编辑:我尝试过gmbeard的建议。 关闭优化(-O0)并没有改变gdb生成的callstack的任何内容。

在程序上运行ldd给了我:

linux-vdso.so.1 =>  (0x00007ffe3b7f1000)
libglut.so.3 => /usr/lib/x86_64-linux-gnu/libglut.so.3 (0x00007f04978fa000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f04975f6000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f04973e0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f049701b000)
libGL.so.1 => /usr/lib/nvidia-352/libGL.so.1 (0x00007f0496cec000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f04969b7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f04966b1000)
libXi.so.6 => /usr/lib/x86_64-linux-gnu/libXi.so.6 (0x00007f04964a1000)
libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f049629b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0497b44000)
libnvidia-tls.so.352.21 => /usr/lib/nvidia-352/tls/libnvidia-tls.so.352.21 (0x00007f0496098000)
libnvidia-glcore.so.352.21 => /usr/lib/nvidia-352/libnvidia-glcore.so.352.21 (0x00007f0493607000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f04933f5000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f04931f1000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f0492fd2000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f0492dce000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f0492bc8000)

然后,在确定了我正在使用的libGL之后,我在其上运行了ldd

linux-vdso.so.1 =>  (0x00007ffc55df8000)
libnvidia-tls.so.352.21 => /usr/lib/nvidia-352/tls/libnvidia-tls.so.352.21 (0x00007faa60d83000)
libnvidia-glcore.so.352.21 => /usr/lib/nvidia-352/libnvidia-glcore.so.352.21 (0x00007faa5e2f2000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007faa5dfbd000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007faa5ddab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007faa5d9e6000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007faa5d7e2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007faa5d4dc000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007faa5d2bd000)
/lib64/ld-linux-x86-64.so.2 (0x00007faa612b5000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007faa5d0b9000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007faa5ceb3000)

但是快速浏览并没有发现任何不妥之处。

所以你在LD_DEBUG输出中看到:

它输出的最后一件事是:“20863:symbol = __ pthread_key_create;在文件中查找= / usr / lib / x86_64-linux-gnu / libXdmcp.so.6 [0]

这意味着ld.so id正在寻找__pthread_key_create因为你的某个库需要它[并且你最好找到这个符号所需的库,它可能会回答库需要libpthread.so]。

所以__pthread_key_create必须在libpthread.so中,但你的ldd输出中没有libpthread.so 正如您在下面看到的,程序可能在init()中使用__pthread_key_create时崩溃。 顺便你也可以试试

LD_PRELOAD=/lib64/libpthread.so.0 ./main

为了确保在其他符号之前加载pthread_key_create

所以lgut不太可能是个问题。 它只是在初始化时调用dlsym,这是绝对正确的行为。 但程序崩溃了:

#0  0x0000000000000000 in ?? ()
#1  0x00007ffff3488291 in init () at dlerror.c:177
#2  0x00007ffff34886d7 in _dlerror_run (operate=operate@entry=0x7ffff3488130 <dlsym_doit>, args=args@entry=0x7fffffffddf0) at dlerror.c:129

此回溯显示具有0x00000000地址的函数(我的猜测它是尚未解析的__pthread_key_create的地址)被调用,这是一个错误。 叫什么功能? 看看消息来源:

这是dlerror.c:129(第2帧):

int
internal_function
_dlerror_run (void (*operate) (void *), void *args)
{
  struct dl_action_result *result;

  /* If we have not yet initialized the buffer do it now.  */
  __libc_once (once, init);

(第1帧):

/* Initialize buffers for results.  */
static void
init (void)
{
  if (__libc_key_create (&key, free_key_mem))
    /* Creating the key failed.  This means something really went
       wrong.  In any case use a static buffer which is better than
       nothing.  */
    static_buf = &last_result;
}

它必须是__libc_key_create ,它是一个宏,并且在glibc中有不同的定义。 如果你为POSIX构建它是定义的

/* Create thread-specific key.  */
#define __libc_key_create(KEY, DESTRUCTOR) \
  __libc_ptf_call (__pthread_key_create, (KEY, DESTRUCTOR), 1)

我请你建立:

g++ -pthread -Wall -g main.cpp -lpthread -lglut -lGL -lGLU -o main

为了确保__libc_key_create实际上调用__pthread_key_create和lpthread是-lglut之前进行初始化。 但是如果你不想使用-pthread那么你可能需要分析第1帧

#1  0x00007ffff3488291 in init () at dlerror.c:177

例如,您可以为第1帧添加disasemble到您的问题

您的程序和libGL可能与第三个库(可能是libc?)的两个冲突版本链接或使用。 使用您提供的详细信息进行诊断很困难。 您可以禁用优化( -O0 )并查看GDB是否放弃了任何进一步的线索。 您可以通过运行ldd来查看程序和libGL所具有的依赖关系 - 这显示了编译时依赖关系。 对不起,我只能提出建议 - 出于多种原因,可能会出现这些类型的运行时问题。

我遇到了类似的问题,但是LD_PRELOAD=/lib/x86_64-linux-gnu/libpthread.so.0 ./main并不是全部工作。 这个问题发生在NVIDIA GPU上,OpenGL链接到/usr/lib/nvidia-352/libGL.so.1 ,在不同的计算机上测试后,我发现将g ++版本更改为g ++ - 5工作,或链接到'mesa / libGL .so',另一个OpenGL实现,由g++ main.cpp -o main -Wl, --rpath /usr/lib/x86_64-linux-gnu/mesa -lGLU -lGL -lglut

暂无
暂无

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

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