使用glut和std :: string时,main()之前的细分错误? [英] Segmentation Fault before main() when using glut, and std::string?

查看:121
本文介绍了使用glut和std :: string时,main()之前的细分错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在64位Ubuntu 14.04 LTS上,我试图编译一个使用glut的简单OpenGL程序.在main中执行任何代码行之前,我都遇到了Segmentation Fault(SIGSEV);即使是非常精简的测试程序.是什么原因造成的?

On 64-bit Ubuntu 14.04 LTS, I am trying to compile a simple OpenGL program that uses glut. I am getting a Segmentation Fault (SIGSEV) before any line of code is executed in main; even on a very stripped down test program. What could cause this?

我的命令行:

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

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在段错误之前无法执行. 在GDB下,segfault是

When I run the program, the printf at the beginning of main doesn't get to execute before the segfault. Under GDB, I get this back trace after the segfault is

#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出现了问题(尽管我尝试了要调试的原始程序(在本示例中我将其简化)),但几个系统都没有成功.我在这里有点茫然.

And here's the kicker. If I comment out either the gluInit line or the std::string dummy line, the program compiles and runs just fine. Up until I noticed this I assumed there was something wrong with my GLUT (though I've tried the original program I'm debugging on (that I stripped down to this example)) several systems with no success. I am at a bit of a loss here.

我已经尝试过gmbeard的建议.取消优化(-O0)不会更改gdb生成的调用栈的任何内容.

I have tried gmbeard's suggestions. Turining off optimizations (-O0) didn't change anything about the callstack produced by gdb.

在程序上运行ldd会给我:

Running ldd on the program gives me:

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之后,我对其进行了运行

And then, having identified which libGL I am using, I ran ldd on it

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)

但是快速浏览并不会发现任何不对劲.

But a quick glance doesn't reveal anything amiss.

推荐答案

所以您在LD_DEBUG输出中看到:

So you see in the LD_DEBUG output:

它最后打印出的内容是:"20863:symbol = __ pthread_key_create; 在file =/usr/lib/x86_64-linux-gnu/libXdmcp.so.6中查找[0]

The last thing it prints out is: " 20863: symbol=__pthread_key_create; lookup in file=/usr/lib/x86_64-linux-gnu/libXdmcp.so.6 [0]

这意味着ld.so id正在寻找__pthread_key_create,因为您的一个librarie需要它[您最好找到该符号需要的库,它可能会回答需要libpthread.so的库].

It means that ld.so id looking for __pthread_key_create since it is needed by one of your librarie [and you'd better find what library is needed this symbol, it possibly will answer what library need libpthread.so].

因此,__pthread_key_create必须位于libpthread.so中,但ldd输出中没有libpthread.so.如您在下面看到的,在init()中使用__pthread_key_create时,程序可能崩溃.顺便说一句,您也可以尝试

So __pthread_key_create must be in libpthread.so but you have no libpthread.so in your ldd output. As you can see below your program crashes possibly in using __pthread_key_create in init(). By the way you can try also

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

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

in order to make sure that pthread_key_create is loaded before other symbols.

因此,lgut不太可能成为问题.它只是在初始化中调用dlsym,这绝对是正确的行为.但是程序崩溃了:

So lgut is unlikely to be a problem. It just calls dlsym in initialization and it is absolutely correct behaviour. But the program crashes:

#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的未解析地址),这是一个错误.调用了什么功能?查看来源:

This backtrace shows that a function with 0x00000000 address (my guess it is yet unresolved address of __pthread_key_create) was called and that is an error. What function was called? Look at sources:

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

This is dlerror.c:129 (frame #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构建的,则定义为

It must be __libc_key_create that is a macro and it has in glibc different definitions. If you build for POSIX it is defined

/* 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

In order to make sure that __libc_key_create in fact calls __pthread_key_create and lpthread is initialized before -lglut. But if you do not want use -pthread then possibly you need to analyze frame #1

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

例如,您可以将第1帧的Disasemble添加到您的问题中

For example you can add disasemble for frame #1 to your question

这篇关于使用glut和std :: string时,main()之前的细分错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆