openSUSE:Bugreport application crashed

Jump to: navigation, search
You are working with a program and suddenly the worst happens--it crashes. One convenience of open source software is the open community with their programmers who really listen to their users and try to fix a reported bug as soon as possible. So you, as a normal user, can become part of the community just by reporting bugs and testing the fixed application.

But reporting a bug is not as easy as saying "it doesn't work." One of the factors that delays a bug's being fixed is the way it is reported. So this guide should help improve communication between developers and users in bug resolution.

Qualities of a Good Bug Report

So please remember the two qualities of a good bug report:

  • Reproducible: Try to reproduce the bug on your own workstation. Write down every step you take to reproduce the bug. Sometimes it could be helpful to disable background tasks in order to avoid interactions between the crashing application and another process running in the background. If the crashing application interacts with another process, this should also be reported as a bug. Every detail you can provide helps the engineer to reproduce the bug on his own workstation.
  • Specific: Don't report more than one bug with a single message. Provide as exact information as you can. Don't talk about other things that might force a programmer or tester to decipher before understanding your message.

For example: Let's say the buggy application is a Web browser. It crashes every time you visit example.org and you want to write up a bug report:

BAD:
My browser crashed.
I think I was on www.example.org.
I play golf with Mr. Big Boss, so you better
fix this problem, or I'll report you to him.
By the way, your Back icon looks UGGGLY!!!
Thx 4 UR help.
GOOD:
My browser "exact-name" crashed
each time I went to www.example.org
on an openSUSE-"exact-version" system.
EXCELLENT:
My browser "exact-name"-"exact-version"
crashed each time I went to www.example.org.
I use the browser build dated 2012-May-23
from the openSUSE "Browsers" repository
on an openSUSE-"exact-version" system.
It crashed each time upon drawing
the banner at the top of the page.
I broke apart the page, and discovered
that the following image link will crash it,
unless you remove the "BORDER=0" attribute:
<IMG SRC="banner.png" WIDTH="400" HEIGHT="60" BORDER="0" ALT="Banner">

Analyzing the Problem

Environment

First of all, check your environment. Write down the system version, the program version, plug-ins (adding their versions), and so on. After that, try to reproduce the problem and write down the steps you make to get the application to crash. Find out, if the problem is solved with a newer version of your software: look at the project home page to get more information.

Install -debuginfo Packages

Most GUI applications show you a backtrace on a crash. A backtrace tells the developer more exactly where the error occurred. Usually gdb is used to create this backtrace. However, gdb can create a more detailed backtrace when it has the debug info. Please install the -debuginfo package for your application to improve the output of gdb. The -debuginfo packages are not part of the CD set, but you can find them in the full network installation source, in the debug directory on our HTTP download server or any mirror (debug repositories for the offici. This directory can be defined as an installation source in YaST (as a replacement for your CD).

Please install the packages and try to reproduce the crash. Attach a description what you did to trigger the crash and the backtrace to the bug report. These packages also help debugging, when you use gdb directly, see below.

Debugging

There is no update and you can reproduce the problem smoothly. Now it's time to start debugging the application. Debugging could take a lot of time--but sometimes it's the only way to get a good bug report and to help the developers to solve the bug quickly.

There are different ways to debug an application, so you have to check each of these proposals on your own and choose the right form for your application.

strace

Programs often use files to fetch configuration information, access hardware, or write logs. Sometimes, a program attempts to reach such files incorrectly. strace is a useful diagnostic, instructional, and debugging tool and could help deal with this. strace traces system calls (hence the name), which include calls that use the memory and files.

In the simplest case, strace runs the specified command until it exits. It intercepts and records the system calls that are called by a process and the signals that are received by a process. The name of each system call, its arguments, and its return value are printed on standard error or to the file specified with the -o option.

An example for stracing the command cat /dev/null is:

  strace -f -ttt -o strace.log cat /dev/null

This creates a file called strace.log in the current directory. We check the file, the relevant parts of which are shown below:

  open("/dev/null", O_RDONLY) = 3

Errors (typically a return value of -1) have the errno symbol and error string appended.

  open("/foo/bar", O_RDONLY) = -1 ENOENT (No such file or directory)

So strace seems to be the best way to debug applications that crash on start-up or crash while opening or saving files.

Using GDB

GDB, the GNU Debugger, is a program used to find run time errors that normally involve memory corruption. You can also use it to obtain a so-called backtrace, a sequence of function calls leading to a crash. When you want to get a backtrace from /usr/bin/brokenprogram, which is throwing segmentation faults every time it runs, you use the following command:

  $ gdb /usr/bin/brokenprogram
  GNU gdb 6.5
  ...
  (gdb)

Now you are in GDB's own prompt. If you are still missing -debuginfo packages gdb will show you output similar to the following:

   Missing separate debuginfo for /lib64/libm.so.6
   Try: zypper install -C "debuginfo(build-id)=35d35d9ce781be3a140a34242d998498615b021f"
   Missing separate debuginfo for /lib64/libpthread.so.0
   Try: zypper install -C "debuginfo(build-id)=522229c2dde70aaa8e4295ecb7b6643c810f758f"
   Missing separate debuginfo for /lib64/libc.so.6
   Try: zypper install -C "debuginfo(build-id)=c3e668c7a2e7ae513e801d34a968a43510b29b52"

Simply copy and paste the given zypper commands into another terminal in order to install the missing packages, then quit gdb with quit and start over.

From gdb type run and wait until the program crashes:

  (gdb) run
  Starting program: /usr/bin/brokenprogram
  
  Program received signal SIGSEGV, Segmentation fault.
  0x08048394 in brokenfunc () at brokenprogram.c:4
  4	    *i = 2;
  (gdb)

Alternately if the program runs at login, is started by an init script or something similar, you can attach to the running process and then continue its execution with continue and wait until the program crashes:

  $ pidof brokenprogram
  12345
  $ gdb /usr/bin/brokenprogram 12345
  (gdb) continue
  Continuing.
  Program received signal SIGSEGV, Segmentation fault.
  0x08048394 in brokenfunc () at broken.c:4
  4	    *i = 2;
  (gdb)

Here you go, back at the GDB prompt enable logging and obtain the backtrace with thread apply all backtrace full.

  (gdb) set logging on
  Copying output to gdb.txt.
  (gdb) thread apply all backtrace full
  [New Thread 0x7ffff6d0b700 (LWP 4520)]
   
   Thread 2 (Thread 0x7ffff750c700 (LWP 4519)):
   #0  0x00007ffff7542849 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
           resultvar = 0
           pid = 4515
           selftid = 4519
   #1  0x00007ffff7543cd8 in __GI_abort () at abort.c:89
           save_stage = 2
           act = {__sigaction_handler = {sa_handler = 0x6466203030303030, sa_sigaction = 0x6466203030303030}, sa_mask = {__val = {3906931166148702266, 2314885530818459703, 2314885530818453536,
                 3395749441387372576, 7596498572764408172, 3330465998920576354, 7378697628689264499, 3256155514972955191, 7233967814408037943, 3255307721929404514, 3472891250476064880, 3616454703663034416,
                 2321666313920262688, 2314885530818453536, 2314885530818453536, 8096}}, sa_flags = 89, sa_restorer = 0x7ffff750bed0}
           sigs = {__val = {32, 0 <repeats 15 times>}}
   #2  0x00007ffff7581114 in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7ffff76770e0 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
           ap = Template:Gp offset = 40, fp offset = 0, overflow arg area = 0x7ffff750bee0, reg save area = 0x7ffff750be70
           fd = 3
           on_2 = <optimized out>
           list = <optimized out>
           nlist = <optimized out>
           cp = <optimized out>
           written = <optimized out>
   #3  0x00007ffff758696e in malloc_printerr (action=3, str=0x7ffff767317b "free(): invalid pointer", ptr=<optimized out>) at malloc.c:4916
           buf = '0' <repeats 11 times>, "12345"
           cp = <optimized out>
   #4  0x0000000000400a88 in work (t=0x0) at brokenprogram.c:18
           i = 10
           tid = 0
           result = -4.943676956758269
   #5  0x00007ffff78c40db in start_thread (arg=0x7ffff750c700) at pthread_create.c:309
           __res = <optimized out>
           pd = 0x7ffff750c700
           now = <optimized out>
           unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140737342654208, 3582659488515194238, 1, 140737354125312, 0, 140737342654208, -3582675678410998402, -3582676406767878786}, mask_was_saved = 0}}, priv = {
               pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
           not_first_call = <optimized out>
           pagesize_m1 = <optimized out>
           pd = 0x7ffff750c700
           now = <optimized out>
           unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140737342654208, 3582659488515194238, 1, 140737354125312, 0, 140737342654208, -3582675678410998402, -3582676406767878786}, mask_was_saved = 0}}, priv = {
               pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
           not_first_call = <optimized out>
           pagesize_m1 = <optimized out>
           sp = <optimized out>
           freesize = <optimized out>
           __PRETTY_FUNCTION__ = "start_thread"
   #6  0x00007ffff75f47cd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
   No locals.
   
   Thread 1 (Thread 0x7ffff7fe1700 (LWP 4515)):
   [...]
   (gdb) 

Quit GDB by typing quit, the backtrace will be saved to the file gdb.txt in the current directory.

If the program crashes only when you use a specific parameter, say --crash, you have to add that parameter to the run command:

  (gdb) run --crash
  Starting program: /usr/bin/brokenprogram --crash

dmesg

dmesg prints out or controls the kernel ring buffer. So if you have problems with the kernel itself or kernel-related applications (especially kernel modules or hotplug stuff), you should use this tool.