To create new wiki account, please join us on #znc at freenode and ask admins to create a wiki account for you. You can say thanks to spambots for this inconvenience.

Difference between revisions of "Debugging"

From ZNC
Jump to: navigation, search
(Tracing crash bugs)
(Restore Debugging from archive.org - 2016/11/07)
 
(12 intermediate revisions by 5 users not shown)
Line 3: Line 3:
 
Steps to do when you think you found a bug:
 
Steps to do when you think you found a bug:
  
* verify the bug exists in the latest version [https://github.com/znc/znc (Git)]
+
* verify the bug exists in the [[Git|latest version]]
 
* report it at [https://github.com/znc/znc/issues Github]
 
* report it at [https://github.com/znc/znc/issues Github]
 
  
 
== Tracing crash bugs ==
 
== Tracing crash bugs ==
Line 14: Line 13:
 
./configure --enable-debug --enable-other-things-you-may-want
 
./configure --enable-debug --enable-other-things-you-may-want
 
make
 
make
 +
make install
 
</pre>
 
</pre>
  
Line 19: Line 19:
  
 
<pre>
 
<pre>
gdb ./znc
+
$ gdb znc
handle SIGPIPE nostop
+
(gdb) set logging file /tmp/znc.gdb.log
run -D
+
(gdb) set logging on
 +
(gdb) handle SIGPIPE nostop noprint pass
 +
(gdb) run -D
 +
</pre>
 +
 
 +
If znc is already running, you can attach gdb to the already-running instance (where pid is znc's process id):
 +
 
 +
<pre>
 +
$ gdb
 +
(gdb) set logging file /tmp/znc.gdb.log
 +
(gdb) set logging on
 +
(gdb) gdb ./znc
 +
(gdb) attach pid
 +
(gdb) handle SIGPIPE nostop noprint pass
 +
(gdb) cont
 
</pre>
 
</pre>
  
Line 33: Line 47:
  
 
<pre>
 
<pre>
bt full
+
(gdb) bt full
 
</pre>
 
</pre>
  
=== Why use --enable-debug? ===
+
If you had logging file set and logging enabled, you can find the bt full and everything else in /tmp/znc.gdb.log. You might want to copy it somewhere safe (that doesn't get cleared every boot unlike /tmp).
  
With this flag [[ZNC]] is compiled with some special flag: <code>-ggdb</code>
+
=== core files ===
So where's the difference?
 
  
Lets assume the code has a bug and does segfault.
+
You can also get the full backtrace from core file if you have core files enabled.
First we compile it without -ggdb and run it in [http://www.gnu.org/software/gdb/ GDB]
 
  
 +
First run <pre>ulimit -c unlimited</pre> and preferrably add it to your ~/.bashrc or rc of whatever shell you use.
  
Starting program: /znc/znc
+
When your ZNC crashes, you should find a file with name "core" in the directory where you ran znc. If you used cron, it is probably located at $HOME. Now run <pre>gdb znc core</pre> and there
+
<pre>
Program received signal SIGSEGV, Segmentation fault.
+
(gdb) set logging /tmp/znc.gdb.log
0x0812d9a6 in CZNC::ParseConfig ()
+
(gdb) set logging on
(gdb) bt full
+
(gdb) bt full
#0  0x0812d9a6 in CZNC::ParseConfig ()
+
(gdb) quit
__ioinit = {static _S_refcount = <optimized out>, static _S_synced_with_stdio = <optimized out>}
+
</pre>
std::string::_Rep::_S_terminal = 0 '\0'
 
std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::id = {_M_index = 5,
 
  static _S_refcount = <optimized out>}
 
std::string::_Rep::_S_empty_rep_storage = {0, 0, 0, 0}
 
std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::id = {_M_index = 4,
 
  static _S_refcount = <optimized out>}
 
std::numpunct<char>::id = {_M_index = 3, static _S_refcount = <optimized out>}
 
#1  0x0811ba35 in main ()
 
__ioinit = {static _S_refcount = <optimized out>, static _S_synced_with_stdio = <optimized out>}
 
std::string::_Rep::_S_empty_rep_storage = {0, 0, 0, 0}
 
std::string::_Rep::_S_terminal = 0 '\0'
 
std::numpunct<char>::id = {_M_index = 3, static _S_refcount = <optimized out>}
 
  
And now again with <code>-ggdb</code>
+
Now your full backtrace should be in /tmp/znc.gdb.log and you can send it to the developers. It's also adviced to copy znc.gdb.log to somewhere outside /tmp as /tmp is cleared every boot.
 +
 
 +
=== Why use --enable-debug? ===
  
Starting program: /znc/znc
+
With this flag <code>bt full</code> shows much more info, which is needed to understand why the crash had happened.
+
If you're interested in details, search the Web for "debug symbols" or just try with and without.
Program received signal SIGSEGV, Segmentation fault.
 
0x0813cbae in CZNC::ParseConfig (this=0x8256930, sConfig=@0xbf88f710) at znc.cpp:846
 
846 *i = 42;
 
(gdb) bt full
 
#0  0x0813cbae in CZNC::ParseConfig (this=0x8256930, sConfig=@0xbf88f710) at znc.cpp:846
 
s = {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295,
 
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
 
      _M_p = 0x824c94c ""}}, _vptr.CString = 0x8249a78}
 
i = (int *) 0x0
 
#1  0x08125945 in main (argc=1, argv=0xbf88f884) at main.cpp:190
 
sConfig = {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295,
 
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
 
      _M_p = 0x825691c "znc.conf"}}, _vptr.CString = 0x8249a78}
 
sDataDir = {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295,
 
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},  
 
      _M_p = 0x824c94c ""}}, _vptr.CString = 0x8249a78}
 
iArg = -1
 
iOptIndex = -1
 
bMakeConf = false
 
bMakePass = false
 
bMakePem = false
 
bEncPem = false
 
pZNC = (class CZNC *) 0x8256930
 
iPid = 136338569
 
sa = {__sigaction_handler = {sa_handler = 0x1, sa_sigaction = 0x1}, sa_mask = {__val = {815, 3083576408, 3083575368, 134723832,
 
      3082340416, 134607268, 1, 3086254020, 3086256136, 3213424396, 3213424424, 3086182628, 134607268, 3213424396, 3086256044, 7,
 
      3083576408, 1, 0, 1, 1300, 3083576840, 3083575368, 3084744097, 3213424408, 3086181320, 3082362303, 3213424464, 3086255696,
 
      134723832, 725871085, 0}}, sa_flags = -1208713276, sa_restorer = 0xb7b83c60}
 
iRet = -1209189020
 
  
As you notice the second attempt shows the source of the problem better than the first one. The first one only mentions <code>0</code> and <code>&lt;optimized out&gt;</code>.
+
[[Category:ZNC]]
In this example you can even see exactly why the crash happened, without looking at the source code!
 

Latest revision as of 22:31, 21 May 2017

Reporting bugs[edit]

Steps to do when you think you found a bug:

Tracing crash bugs[edit]

Configure your ZNC version with --enable-debug.

./configure --enable-debug --enable-other-things-you-may-want
make
make install

Then you can run ZNC under gdb:

$ gdb znc
(gdb) set logging file /tmp/znc.gdb.log
(gdb) set logging on
(gdb) handle SIGPIPE nostop noprint pass
(gdb) run -D

If znc is already running, you can attach gdb to the already-running instance (where pid is znc's process id):

$ gdb
(gdb) set logging file /tmp/znc.gdb.log
(gdb) set logging on
(gdb) gdb ./znc
(gdb) attach pid
(gdb) handle SIGPIPE nostop noprint pass
(gdb) cont

Now you use ZNC as you would always do and try to make it crash. Once it crashed, gdb will show you something like this:

Program received signal SIGSEGV, Segmentation fault.

Now we can get the useful info. This info, together with an explanation how the bug happened are then very useful to the developers.

(gdb) bt full

If you had logging file set and logging enabled, you can find the bt full and everything else in /tmp/znc.gdb.log. You might want to copy it somewhere safe (that doesn't get cleared every boot unlike /tmp).

core files[edit]

You can also get the full backtrace from core file if you have core files enabled.

First run
ulimit -c unlimited
and preferrably add it to your ~/.bashrc or rc of whatever shell you use. When your ZNC crashes, you should find a file with name "core" in the directory where you ran znc. If you used cron, it is probably located at $HOME. Now run
gdb znc core
and there
(gdb) set logging /tmp/znc.gdb.log
(gdb) set logging on
(gdb) bt full
(gdb) quit

Now your full backtrace should be in /tmp/znc.gdb.log and you can send it to the developers. It's also adviced to copy znc.gdb.log to somewhere outside /tmp as /tmp is cleared every boot.

Why use --enable-debug?[edit]

With this flag bt full shows much more info, which is needed to understand why the crash had happened. If you're interested in details, search the Web for "debug symbols" or just try with and without.