Debugging 在Qt中设置断点后,gdb说:“在;访问内存地址时出错“;

Debugging 在Qt中设置断点后,gdb说:“在;访问内存地址时出错“;,debugging,qt,qt4,gdb,breakpoints,Debugging,Qt,Qt4,Gdb,Breakpoints,我在这里编写了一个非常简单的Qt程序: int main(int argc, char* argv[]) { QApplication app(argc, argv); QTableView table(&frame); table.resize(100, 100); table.show(); return app.exec(); } (gdb) symbol-file /usr/lib/libQtGui.so.4.4.3.debug L

我在这里编写了一个非常简单的Qt程序:

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    QTableView table(&frame);
    table.resize(100, 100);
    table.show();

    return app.exec();
}
(gdb) symbol-file /usr/lib/libQtGui.so.4.4.3.debug 
Load new symbol table from "/usr/lib/libQtGui.so.4.4.3.debug"? (y or n) y
Reading symbols from /usr/lib/libQtGui.so.4.4.3.debug...done.
(gdb) br 'QAbstractItemView::clicked(QModelIndex const&)'
Breakpoint 1 at 0x5fc660: file .moc/release-shared/moc_qabstractitemview.cpp, line 313.
(gdb) run
Starting program: ./qt-test
Warning:
Cannot insert breakpoint 1.
Error accessing memory address 0x5fc660: Input/output error.
当我试图在单击表的位置设置断点时,我从gdb得到了这个错误:

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    QTableView table(&frame);
    table.resize(100, 100);
    table.show();

    return app.exec();
}
(gdb) symbol-file /usr/lib/libQtGui.so.4.4.3.debug 
Load new symbol table from "/usr/lib/libQtGui.so.4.4.3.debug"? (y or n) y
Reading symbols from /usr/lib/libQtGui.so.4.4.3.debug...done.
(gdb) br 'QAbstractItemView::clicked(QModelIndex const&)'
Breakpoint 1 at 0x5fc660: file .moc/release-shared/moc_qabstractitemview.cpp, line 313.
(gdb) run
Starting program: ./qt-test
Warning:
Cannot insert breakpoint 1.
Error accessing memory address 0x5fc660: Input/output error.

有人知道为什么无法插入断点吗?

不要使用gdb命令
符号文件
加载外部符号。断点地址将是错误的,因为它们没有重新定位

相反,在
main
中设置断点,运行程序,然后设置断点:

gdb ./program
GNU gdb 6.8-debian blah blah blah
(gdb) br main
Breakpoint 1 at 0x80489c1
(gdb) run
Starting program: ./program
Breakpoint 1, 0x080489c1 in main ()
(gdb) br 'QAbstractItemView::clicked(QModelIndex const&)'
Breakpoint 2 at 0xb7d24664
(gdb) continue
Continuing.
然后使断点发生


确保在要设置断点的函数中指定参数列表,而不指定这些参数的名称,只指定它们的类型。

如果要在不设置断点的情况下自动插入main,也可以使用
start
命令。
如果需要为程序提供任何参数,可以使用:
开始参数1参数2

实际错误:

访问内存地址0x5fc660时出错:输入/输出错误


可能由32/64位混淆引起。例如,请检查您是否未附加到具有64位进程ID的32位二进制文件,反之亦然。

好的,我是在使用mingw-w64(本机或交叉编译器)构建时得到的。 我不确定确切的问题是什么,但如果我使用gcc mingw-w64 i686-5.1.0-posix-sjlj-rt_v4-rev0构建它,那么它将创建(最终)可调试的构建。否则

(gdb) break main
...
(gdb) r
...
Cannot insert breakpoint 1.
Cannot access memory at address 0x42445c
<process basically hangs>
(gdb)断开主电源
...
(gdb)r
...
无法插入断点1。
无法访问地址为0x42445c的内存
消息20次中有19次,尽管有时确实有效(很少)

GDB7.8.1和7.9.1似乎能够调试创建的exe。因此,可能不是gdb的版本起了作用

我目前的理论/怀疑是它要么是gcc版本,要么可能是sljl vs.dwarf2编译器的“方面”[?](i686-492-posix-dwarf-rt_v3-rev1不起作用,与某种形式的gcc 4.9.2交叉编译也不起作用)。没有尝试其他版本的gcc


更新:更新的gcc(5.1.0),但交叉编译仍然失败。本例中的原因原来是我的构建(FFmpeg)通过链接(本例中为libgme)使用的依赖项库,它导出了一些错误的“共享”符号(当我构建静态可执行文件时)。正因为如此,“共享”构建了brake(),并且以某种方式也破坏了gdb。例如,可能针对SDL的链接也可以对您执行此操作。我的想法可能是一个
ld
bug[?]

我正在使用Ubuntu Intrepid,我已经安装了libqt4 dbg,如果这有帮助的话。多亏了irc.freenode.net中的#gdb中的pholklore提供了这个答案。你也可以只在任何你喜欢的地方设置断点,而不必先中断main(),gdb将询问您是否要设置挂起的断点。然而,通过这种方式,您永远无法确定该函数是否确实存在,或者您是否输入了错误。所以答案中说明的方法更安全。我有这个问题,但我不知道如何让它正确使用gdb:(比特率不匹配不是问题吗?看来我不得不在生成文件中添加
-g
选项,这就解决了问题。在stackoverflow上的某个地方找到了它,但我不知道它是做什么的。@froginvasion,
-g
使用调试符号编译,这样就可以让调试器查看源代码并提供有用的反馈。我调试VLC 3时也会遇到这种情况(4时不会出现这种情况)。您不能使用
start
,因为这样会自动在main上设置断点。解决方法是,当它停在“无法访问内存”时,告诉它
delete 1
,然后
continue