|
|
Line 39: |
Line 39: |
| === Why use --enable-debug? === | | === Why use --enable-debug? === |
|
| |
|
| With this flag [[ZNC]] is compiled with some special flag: <code>-ggdb</code> | | With this flag <pre>bt full</pre> shows much more info, which is needed to understand why the crash had happened. |
| So where's the difference?
| | If you're interested in details, search the Web for "debug symbols" or just try with and without. |
| | |
| Lets assume the code has a bug and does segfault.
| |
| First we compile it without -ggdb and run it in [http://www.gnu.org/software/gdb/ GDB]
| |
| | |
| | |
| Starting program: /znc/znc
| |
|
| |
| Program received signal SIGSEGV, Segmentation fault.
| |
| 0x0812d9a6 in CZNC::ParseConfig ()
| |
| (gdb) bt full
| |
| #0 0x0812d9a6 in CZNC::ParseConfig ()
| |
| __ioinit = {static _S_refcount = <optimized out>, static _S_synced_with_stdio = <optimized out>}
| |
| 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>
| |
| | |
| Starting program: /znc/znc
| |
|
| |
| 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><optimized out></code>.
| |
| In this example you can even see exactly why the crash happened, without looking at the source code!
| |
Reporting bugs
Steps to do when you think you found a bug:
- verify the bug exists in the latest version (Git)
- report it at Github
Tracing crash bugs
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
handle SIGPIPE nostop
run -D
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.
bt full
Why use --enable-debug?
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.