|
|
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!
| |