Jump to content
Eternal Lands Official Forums
Sign in to follow this  
Wytter

Crashcourse in debugging

Recommended Posts

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 :P

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 by Wytter

Share this post


Link to post
Share on other sites

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

Could you write a small guide for debugging using DevC++?

Share this post


Link to post
Share on other sites
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 by crusadingknight

Share this post


Link to post
Share on other sites

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
Now... how does one view console output in Dev-C++?
Project->Project Options->Type->Win32 Console :icon13:

Share this post


Link to post
Share on other sites

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. :confused:

Share this post


Link to post
Share on other sites

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×