你如何处理调试无法重现的东西?

时间:2013-09-27 10:02:06

标签: c++ qt opengl

我制作了一个简单的OpenGL应用程序(link)。在那里,您可以看到它应该如何显示的图像 - 以及它在我的计算机上的外观(OSX):

correct

问题是:当我的客户端克隆并在他的计算机上编译它(Ubuntu)时,这就是他所看到的:

wrong http://dl.dropboxusercontent.com/u/62862049/Screenshots/wl.png

我对此感到很困惑。如果我可以重现这个错误就没问题了,但是不能这样做让我对如何开始修复它一无所知。我该如何处理这个问题?

4 个答案:

答案 0 :(得分:5)

  

我该如何处理这个问题?

我建议使用VirtualBox在您的计算机上创建虚拟Ubuntu环境,以便您自己编译和调试该问题。

如果它在您的虚拟机上按预期运行,则问题可能与客户端驱动程序相关。

答案 1 :(得分:1)

如果您不想关注this suggestion并使用virtualbox,则其他选项是获得与客户端相同的设置(至少类似的硬件,相同的操作系统和安装包)。这样可以更容易地重现和调试。

有时,由于驱动程序问题,应用程序对不同GPU的行为会有所不同。如果司机是最新的,这无关紧要。

答案 2 :(得分:1)

我所遇到的一些奇怪问题源于某些地方未初始化的数据。 Valgrind是发现这些问题的天赐之物。 Valkyrie是一个很好的应用程序来组织其输出。

在这个特定的情况下,我会抛出疯狂的猜测。我已经看到这种情况发生在窗口管理器发送延迟调整大小事件或没有初始调整大小事件之前。例如,如果您的代码期望在第一次绘制调用之前发送resize事件(或者每当您存储初始窗口大小以设置视口和宽高比时)并且事件不会立即发生,那么您就错了值。如果在进入主循环之前没有发生真正的resize事件,我的GL框架会在内部注入一个resize事件(非常繁琐,如果你想在最终出现时忽略真实事件)。

答案 3 :(得分:1)

我冒昧地纠正了我认为这个代码行为可预测的巨大障碍。 gluPerspective (...)应该用于设置投影矩阵,有时可以将everythng填充到单个矩阵中,但它没有多大意义。

void GLWidget::paintGL(){
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

  /* Original code that does really bad things ... 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluPerspective(60.0f,(GLfloat)width/(GLfloat)height,0.01f,650.0f);
  */

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(60.0f,(GLfloat)width/(GLfloat)height,0.01f,650.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(0.0, cam_radius, cam_radius,
            0.0, 0.0, 0.0,
            0.0, 0.0, 1.0);
  glViewport(0, 0, width, height);
  glRotatef( rotate_x, 1.0, 0.0, 0.0 );
  glRotatef( rotate_y, 0.0, 0.0, 1.0 );

  ...

}

至于调试无法重现的东西,第一步是考虑可能产生类似于你(或者更确切地说是其他人)所经历的效果的每个状态。当有人提供随机的代码和屏幕截图时,这就是我在StackOverflow上大部分时间所做的事情。通常他们最初提供的代码是无益的,但问题的屏幕截图和描述会导致正确的解决方案;值得庆幸的是,评论部分允许我们在提交答案之前询问更具体的代码。

当我听到你的问题时,我想到的第一件事是投影和视口映射,它引导我qglwidget.cpp我发现了一些顽皮的代码。它可能不一定是您的整个问题,但绝对符合所有标准的 问题