在MinGW中但不是Unix中,当程序使用(甚至是#include的)SDL2时,gdb没有行号信息。MCVE确实很简单。
#include "SDL.h" //<--comment this out and we get line numbers in gdb again
int main(int argc, char** argv)
{
return 0;
}
这就是Makefile
INCLUDE_FLAGS := -I../../external/SDL2-MinGW/SDL2/i686-w64-mingw32/include/SDL2
LIBRARIES := mingw32 SDL2main SDL2
LIB_FLAGS := $(foreach library,$(LIBRARIES), -l$(library))
LIB_DIR_FLAGS := -L../../external/SDL2-MinGW/SDL2/i686-w64-mingw32/lib
ALL_FLAGS := $(INCLUDE_FLAGS) $(LIB_FLAGS) $(LIB_DIR_FLAGS)
a.exe: main.cpp
g++ -Wall -g -o a.exe main.cpp $(ALL_FLAGS)
这是我调用gdb的方法
PATH="../../external/SDL2-MinGW/SDL2/i686-w64-mingw32/bin:$PATH"
gdb a.exe
我在MinGW上运行最新的版本 (mingw-gcc-bin, mingw-gcc-g++-bin是9.2.0-1; mingw-gdb-bin是7.6.1-1).
这里有什么解决方法?我想SDL2应该不是用-g编译的吧,不过这应该和main没关系。
编辑:输出在这里显示。
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\Users\briggs_w\Desktop\cpp-for-lazy-programmers-master\ch29\mcve\a.exe...done.
(gdb) break main
Breakpoint 1 at 0x404270
(gdb) run
Starting program: C:\Users\briggs_w\Desktop\cpp-for-lazy-programmers-master\ch29\mcve/a.exe
[New Thread 8652.0x700]
[New Thread 8652.0xab8]
[New Thread 8652.0x36f0]
[New Thread 8652.0x244c]
Breakpoint 1, 0x00404270 in main ()
(gdb) next
Single stepping until exit from function main,
which has no line number information.
0x00401
SDL2有 SDL2main
库来处理不同目标平台上的入口点。例如,在unix系统上,你可以使用 main
入口处,在窗户上--有时 main
,有时 WinMain
而在android或ios等平台上,情况就会大不相同。SDL可以让你假装入口点永远是 int main(int argc, char **argv)
但在此之前,它需要注入自己的实际进入点。为此,它使用 #define main SDL_main
,有效地重新命名了您的 main
到 SDL_main
然后在初始化阶段后调用它。所以,在你的例子中,在 main
调试器不能给你显示行数是因为 SDL2main
构建时没有调试符号;你的代码仍然有符号,所以在你的代码中任何地方中断都会有所有预期的事情。
补充一点,因为你用的是C++而不是C。main
所以绝对要 int main(int argc, char **argv)
. C++(或任何C)允许main声明有更大的自由度,但一旦它的名字不是 main
编译器不再知道它有任何特殊的意义,并会产生C++的混乱和通常的重载功能。它可能会导致意外的链接错误。
你可以放弃 SDL2main
如果您自己实现了切入点,并通知SDL您不需要该切入点--通过使用 #define SDL_MAIN_HANDLED
前包括 SDL.h
并称 SDL_SetMainReady
在任何其他 SDL 函数之前。在这种情况下,您不需要与 SDL2main
但你会失去它的额外功能,比如utf8命令行参数。