Wytter Report post Posted April 6, 2005 (edited) Hey all, This note on debugging methods is primarially targetted at GNU/Linux and *BSD users but should also work for Windows users who use a Cygwin environment (if you don't know what it is, this doesn't apply to you at all). The pre-requirements for helping debugging the EL client is: *) The latest CVS client - If you run into an error, try doing a new checkout and see if the problem persists. If it's still there, it will most likely be a bug and if you are not able to see a bug report describing the error you're experiencing on these forums, you should report it. *) The GCC compiler or similiar capable of compiling with debugging flags. - For GCC you only need to add the -ggdb keyword to the compiler flags. The default target in the Makefile.linux and Makefile.bsd already use these keywords. *) The GDB (The GNU Project Debugger) or similiar - http://www.gnu.org/software/gdb/gdb.html If you run into an error and you're willing to help us more than just reporting the bug, you can help us fix it by using a debugger and learning some simple commands. This small crashcourse should be able to give you the info you need to debug the EL client and give us sufficient information to find the source of the error. Keywords: Debugging: Debugging is the concept of finding and resolving bugs/crashes etc. Backtrace: Through a backtrace we can obtain information of what happened before the crash. Through this, we can see what happened prior to the crash and where the crash happened. Step 1: Compile the client with the default flags: make clean make -f Makefile.linux Step 2: Open the client in the GDB debugger: gdb el.x86.linux.bin Here's how the console should be looking: bjorn@darkhelmet elc $ gdb el.x86.linux.bin GNU gdb 6.2.1 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) Step 3: Let's run the beast. To run the client, you just need to write "run". If you wish to run the game with some command line arguments, you should put these after "run". (gdb) run <arguments> You should see the following window: Starting program: /home/bjorn/elsrc/dev/elc/el.x86.linux.bin warning: Unable to find dynamic linker breakpoint function. GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. [Thread debugging using libthread_db enabled] [New Thread 182915818272 (LWP 2867)] [New Thread 1082128736 (LWP 2870)] [New Thread 1090517344 (LWP 2871)] [Thread 1090517344 (zombie) exited] Step 4: Shit! The client crashed. But where and how? If the client crashes the window will not close, however you will get info that an error has occured. In this case I made a mistake on purpose (tried accessing a NULL-pointer) and caused the client to crash. You'll see something similiar to the following: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 182915818272 (LWP 2867)] 0x000000000043a436 in HandleEvent (event=0x7fbffff2d0) at events.c:46 46 actors_list[200]->x_pos=0; (gdb) Of course the location of the error will not be the same - the main idea is just that you remember to copy the lines "Program recieved signal ..." to (gdb) (the debugger console). Step 5 (Optional): Getting variables values Now, the first thing you'd do to check what could cause this to happen would be trying to get the value of the variable that caused the crash. (gdb) print actors_list[200] $1 = (actor *) 0x0 (gdb) Oh, so we tried accessing a NULL-pointer - that'll explain the error If you do not know how to do this or if this step confuses you due to lack of programming experience, you can jump to the backtrace. Step 6: The backtrace Now, in most cases the error will not be that obvious, and we'd need a backtrace to figure out what happened. To get a backtrace do the following: (gdb) backtrace #0 0x000000000043a436 in HandleEvent (event=0x7fbffff2d0) at events.c:46 #1 0x000000000044de05 in start_rendering () at main.c:48 #2 0x000000000044e106 in main (argc=1, argv=0x7fbffff3f8) at main.c:149 (gdb) It'll simply show the latest function calls, and that can be used to locate the error. ---- There's a more thorough guide here: http://www.delorie.com/gnu/docs/gdb/gdb_toc.html If you want a debugging GUI, I will recommend the DDD debugger: http://www.gnu.org/software/ddd ---- Now, this was a short introduction to debugging. If you have any questions or additions, feel free to post below. Edited April 6, 2005 by Wytter Share this post Link to post Share on other sites
crusadingknight Report post Posted April 6, 2005 As well, gdb comes with Dev-Cpp, and of course, MinGW. Chances are, if you're capable of compiling a client, you have the debugging tools. Share this post Link to post Share on other sites
Wytter Report post Posted April 6, 2005 Could you write a small guide for debugging using DevC++? Share this post Link to post Share on other sites
crusadingknight Report post Posted April 6, 2005 (edited) Could you write a small guide for debugging using DevC++? I'll have a look... see if I can work around it executing everything from $DEV-CPP/bin, instead of the app. dir. EDIT: Nope, not possible, because it won't execute in the right directory... I guess it's with gdb command line you'll have to work. <_< Edited April 6, 2005 by crusadingknight Share this post Link to post Share on other sites
emajekral Report post Posted August 29, 2006 If you follow my Dev-C++ guide then you will be able to debug from the directory you are coding in with just a couple extra steps... I do it. All you have to do is copy the contents of your EL app. directory to wherever your project directory is. Then specify that you execute and develop from the same directory. Does that make sense? (Am I doing something wrong, or have I left out too many details?) From there using the debugger is a relatively discoverable process, assuming you have previous debugger experience. This makes creating patches a little harder, but not too bad if you just copy source files around a bit. Now... how does one view console output in Dev-C++? Share this post Link to post Share on other sites
LabRat Report post Posted August 29, 2006 Now... how does one view console output in Dev-C++? Project->Project Options->Type->Win32 Console Share this post Link to post Share on other sites
emajekral Report post Posted August 30, 2006 Nope. That hasn't worked for me yet. No console window. You'll note my Dev-C++ guide recommended that as the project type. I double checked that that was what the project type I'm using now and it is. Share this post Link to post Share on other sites
alvieboy Report post Posted November 24, 2007 May I suggest an addition to the linux debugging ? Sometimes when a binary crashes due to a detected error (for example, a pointer double free or something detected by the C library), you are not able to use "gdb" directly on the binary - it will reply "Program no longer exists". This is often caused by a direct call to abort() inside libc. On this scenario, it's better to have your executable output a core dump and analyse that dump after with gdb. In most linux distros, the core generation is disabled - there's is a limit of 0 bytes for your core dumps. You can check your current limit with: $ ulimit -c To enable core dumps in your current shell session, issue this command: $ ulimit -c unlimited . You can now run el and when it crashes, it will generate a core dump. This file can be named just "core", or "core.<pid>", where pid was the process ID of the failing process. Example: $ ulimit -c unlimited $ ./el.x86.linux.bin Segmentation fault (core dumped) $ ls core* core.5597 $ gdb ./el.x86.linux.bin core.5597 (...library stuff here...) Core was generated by `./el.x86.linux.bin'. Program terminated with signal 11, Segmentation fault. #0 0x08090a6d in keypress_root_common () You can then use the backtrace commands in gdb to get a clearer view of what happened. Share this post Link to post Share on other sites