0

我的程序绘制了一个小动画,使用了 glut 和 cuda,并且是用 C++ 编写的,它在一段时间后挂起,当我在它挂起几秒钟后中断它时,我在调试器中看到以下跟踪:

Program received signal SIGINT, Interrupt.
0x000000011302a84c in cuGraphicsGLRegisterBuffer ()
(gdb) bt
#0  0x000000011302a84c in cuGraphicsGLRegisterBuffer ()
#1  0x000000011306bc36 in cuGraphicsGLRegisterBuffer ()
#2  0x0000000113039455 in cuGraphicsGLRegisterBuffer ()
#3  0x0000000113006864 in cuGraphicsGLRegisterBuffer ()
#4  0x000000011303cbe6 in cuGraphicsGLRegisterBuffer ()
#5  0x000000011303d972 in cuGraphicsGLRegisterBuffer ()
#6  0x0000000113028bc6 in cuGraphicsGLRegisterBuffer ()
#7  0x000000011302a090 in cuGraphicsGLRegisterBuffer ()
#8  0x000000011301fcb2 in cuGraphicsGLRegisterBuffer ()
#9  0x0000000112ffcead in cuGraphicsGLRegisterBuffer ()
#10 0x0000000113001718 in cuGraphicsGLRegisterBuffer ()
#11 0x0000000112ff27cf in cuMemcpyDtoH_v2 ()
#12 0x00000001001d70c4 in cudaGetExportTable ()
#13 0x00000001002098a5 in cudaMemcpy ()

(这是堆栈跟踪的顶部;其余的是我自己的函数,其中一个调用 cudaMemcpy。)

如果我在挂起后立即尝试中断,则跟踪如下所示:

#0  0x00007fffffe0026d in __spin_lock ()
#1  0x00007fff880f855b in pthread_mutex_unlock ()
#2  0x000000011303ad89 in cuGraphicsGLRegisterBuffer ()
#3  0x000000011303b972 in cuGraphicsGLRegisterBuffer ()
#4  0x0000000113026bc6 in cuGraphicsGLRegisterBuffer ()
#5  0x0000000113028090 in cuGraphicsGLRegisterBuffer ()
#6  0x000000011301dcb2 in cuGraphicsGLRegisterBuffer ()
#7  0x0000000112ffaead in cuGraphicsGLRegisterBuffer ()
#8  0x0000000112fff718 in cuGraphicsGLRegisterBuffer ()
#9  0x0000000112ff07cf in cuMemcpyDtoH_v2 ()
#10 0x00000001001d70c4 in cudaGetExportTable ()
#11 0x00000001002098a5 in cudaMemcpy ()

我不知道如何处理这个问题。cudaPeekAtLastError在调用cudaMemcpy. 我也知道我可以运行包含在 nvidia 的 SDK 中的程序。此外,程序在挂起之前运行了几秒钟,这意味着挂起之前的所有调用都会执行而不会产生错误,因此我的调用方式或指针分配不正确cudaMemcpy似乎没有任何问题(如果它们cudaMemcpy是,我希望 cuda 只会产生错误,而不是挂起)。

该卡是 GeForce 9400M,Cuda 驱动程序/运行时 4.2,Cuda 功能 1.1。

有什么建议吗?

4

1 回答 1

1

我猜您遇到了指针问题,例如尝试复制超出缓冲区的末尾(源或目标),或者完全引用了错误的指针。一旦你开始踩到无效内存,不要指望任何理智的错误报告或有用的回溯。

查看您的回溯,可能会调用 GLRegister 调用,因为您无意中尝试从映射到 OpenGL 的设备内存空间进行复制。

尝试 cuda-memcheck 和/或 valgrind。或者,因为很容易重现,所以首先验证(通过调试器或通过 printf)您传递给 memcpy 的值。或者,通过禁用部分代码来手动开始二进制搜索,直到一切恢复正常。

于 2012-05-22T19:41:16.653 回答