Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » gdb fails hard (yet again)

This thread is locked; no one can reply to it. rss feed Print
gdb fails hard (yet again)
Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Yet again, gdb has failed me in so many ways. It still doesn't have any clue how to properly output the STL, yet it has been an integral component of C++ for who knows how long now. It fails to recognize #defines, it fails to recognize inline functions even though I have optimized with -O0 and -ggdb3 (mostly STL functions again). It fails so hard it just boggles my mind. Below is a transcript of a debugging session I had with GDB just now.

#SelectExpand
1Breakpoint 1, ParseAttributeSet (widget_parameters=...) 2 at C:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\src\Gui\Scripting\Parsing.cpp:24 324 vector<string> attributes = SplitByDelimiterString(widget_parameters , ";"); 4(gdb) s 5SplitByDelimiterString (string_to_split=..., token=...) 6 at C:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\src\StringWork.cpp:96 796 std::vector<std::string> tokens; 8(gdb) continue 9Continuing. 10 11Breakpoint 2, SplitByDelimiterString (string_to_split=..., token=...) 12 at C:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\src\StringWork.cpp:112 13112 tokens.push_back(sub); 14(gdb) p sub 15$5 = {static npos = <optimized out>, 16 _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 17 _M_p = 0x93ebc4 "DIM:200,50 "}, _M_string_length = 11, {_M_local_buf = "DIM:200,50 \000(\000\000", 18 _M_allocated_capacity = 978143556}} 19(gdb) l 20107 stop_index = string_to_split.find_first_of(token , start_index); 21108 if (stop_index == string::npos) { 22109 stop_index = string_to_split.size(); 23110 } 24111 string sub = string_to_split.substr(start_index , stop_index); 25112 tokens.push_back(sub); 26113 start_index = stop_index + token.size(); 27114 } 28115 return tokens; 29116 } 30(gdb) p stop_index 31$6 = 11 32(gdb) p string_to_split 33$7 = {static npos = <optimized out>, 34 _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 35 _M_p = 0x34805e8 "DIM:200,50 ; FONT:Verdana20 ; TEXT:Quit"}, _M_string_length = 39, { 36 _M_local_buf = "'\000\000\000hì"\000-Uo|"", _M_allocated_capacity = 39}} 37(gdb) n 38[New Thread 15372.0x1848] 39113 start_index = stop_index + token.size(); 40(gdb) p token.size() 41$8 = 55004280 42(gdb) n 43111 string sub = string_to_split.substr(start_index , stop_index); 44(gdb) p start_index 45$9 = 12 46(gdb) p stop_index 47$10 = 11 48(gdb) bt 1 49#0 SplitByDelimiterString (string_to_split=..., token=...) 50 at C:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\src\StringWork.cpp:111 51(More stack frames follow...) 52(gdb)

Note that when printing out a std::string, it gives me "_M_allocated_capacity = 978143556". Why would a std::string be reserving 978 MB of space? It's obviously wrong.

What I'm trying to do is debug a simple function that splits a string by delimiters. No I don't want to use strtok, don't ask. The function is here :

StringWork.cpp#SelectExpand
94std::vector<std::string> SplitByDelimiterString(std::string string_to_split , const std::string token) { 95 96 std::vector<std::string> tokens; 97 size_t start_index = 0; 98 size_t stop_index = 0; 99 100 if (string_to_split.size() == 0) { 101 return tokens; 102 } 103 104 const size_t split_string_size = string_to_split.size(); 105 106 while (stop_index <= split_string_size && start_index < split_string_size) { 107 stop_index = string_to_split.find_first_of(token , start_index); 108 if (stop_index == string::npos) { 109 stop_index = string_to_split.size(); 110 } 111 string sub = string_to_split.substr(start_index , stop_index); 112 tokens.push_back(sub); 113 start_index = stop_index + token.size(); 114 } 115 return tokens; 116}

For some reason I have been getting an exception later on because this function seemingly fails to split this string by semi-colons :

"DIM:200,50 ; FONT:Verdana20 ; TEXT:Quit"

It is returning two strings, "DIM:200,50 " and " FONT:Verdana20 ; TEXT:Quit". I'm trying to debug this thing, and it's giving me all weird kind of results when I debug it.

For one, when I call "token.size()" it returns 55004280, which is obviously wrong for a const std:string with the contents ";". For two, once when I was on line 113 of the code above, when I hit 'n' for next it returned me to line 111, skipping lines 107-110 in a while loop FFS.

My only conclusion is that gdb is trash and that its never going to be fixed. I tried to print out an object that contained an unordered_set, and I got back this shit :

(gdb) p EagleLog()
[New Thread 13920.0x300c]
$11 = (EagleLogger &) @0x6f1550a0: {global_log_level = EAGLE_LOG_INFO, old_global_log_level = EAGLE_LOG_INFO,
  local_log_level = EAGLE_LOG_INFO, outputs = {
    _M_h = {<std::__detail::_Hashtable_base<std::basic_ostream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*, std::__detail::_Identity, std::equal_to<std::basic_ostream<char, std::char_traits<char> >*>, std::hash<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<false, true, true> >> = {<std::__detail::_Hash_code_base<std::basic_ostream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*, std::__detail::_Identity, std::hash<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>> = {<std::__detail::_Hashtable_ebo_helper<0, std::__detail::_Identity, true>> = {<std::__detail::_Identity> = {<No data fields>}, <No data fields>}, <std::__detail::_Hashtable_ebo_helper<1, std::hash<std::basic_ostream<char, std::char_traits<char> >*>, true>> = {<std::hash<std::basic_ostream<char, std::char_traits<char> >*>> = {<std::__hash_base<unsigned int, std::basic_ostream<char, std::char_traits<char> >*>> = {<No data fields>}, <No data fields>}, <No data fields>}, <std::__detail::_Hashtable_ebo_helper<2, std::__detail::_Mod_range_hashing, true>> = {<std::__detail::_Mod_range_hashing> = {<No data fields>}, <No data fields>}, <No data fields>}, <std::__detail::_Hashtable_ebo_helper<0, std::equal_to<std::basic_ostream<char, std::char_traits<char> >*>, true>> = {<std::equal_to<std::basic_ostream<char, std::char_traits<char> >*>> = {<std::binary_function<std::basic_ostream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*, bool>> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <std::__detail::_Map_base<std::basic_ostream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*, std::allocator<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Identity, std::equal_to<std::basic_ostream<char, std::char_traits<char> >*>, std::hash<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true>, true>> = {<No data fields>}, <std::__detail::_Insert<std::basic_ostream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*, std::allocator<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Identity, std::equal_to<std::basic_ostream<char, std::char_traits<char> >*>, std::hash<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true>, true, true>> = {<std::__detail::_Insert_base<std::basic_ostream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*, std::allocator<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Identity, std::equal_to<std::basic_ostream<char, std::char_traits<char> >*>, std::hash<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> >> = {<No data fields>}, <No data fields>}, <std::__detail::_Rehash_base<std::basic_ostream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*, std::allocator<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Identity, std::equal_to<std::basic_ostream<char, std::char_traits<char> >*>, std::hash<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> >> = {<No data fields>}, <std::__detail::_Equality<std::basic_ostream<char, std::char_traits<char> >*, std::basic_ostream<char, std::char_traits<char> >*, std::allocator<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Identity, std::equal_to<std::basic_ostream<char, std::char_traits<char> >*>, std::hash<std::basic_ostream<char, std::char_traits<char> >*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true>, true>> = {<No data fields>}, <std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::basic_ostream<char, std::char_traits<char> >*, false> > >> = {<std::__detail::_Hashtable_ebo_helper<0, std::allocator<std::__detail::_Hash_node<std::basic_ostream<char, std::char_traits<char> >*, false> >, true>> = {<std::allocator<std::__detail::_Hash_node<std::basic_ostream<char, std::char_traits<char> >*, false> >> = {<__gnu_cxx::new_allocator<std::__detail::_Hash_node<std::basic_ostream<char, std::char_traits<char> >*, false> >> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>},
      _M_buckets = 0x125a088, _M_bucket_count = 5, _M_before_begin = {_M_nxt = 0x125a068}, _M_element_count = 2,
      _M_rehash_policy = {static _S_growth_factor = 2, _M_max_load_factor = 1, _M_next_resize = 5},
      _M_single_bucket = 0x0}}}
(gdb)

I tried to call my logging functions from within GDB to get an idea of what some of my objects contain, and all it gives me is this :

(gdb) p EagleInfo() << (*quit_button)
Internal error: incompatible overload candidates proposed

I know the template that enables EagleLog() << TextButton has been resolved and instantiated, but gdb fails me yet again.

I'm fed up.

I need an alternative to debugging with gdb. I'm almost at my wits end, and I'm thinking of converting my code to use MSVC (which makes me a little sick inside) and would probably take me over a month to get my dlls to build right.

What else can I use? Does Intel's ICC compiler come with a debugger? I desperately need an alternative that actually does what it is supposed to do.

Halp!

Edgar

GullRaDriel
Member #3,861
September 2003
avatar

Because the fucking SDL was compiled with fucking Microsoft Visual Studio or equal mean you have to stitch with VS/VC debugger if your problem lies in the STL.

ICC will have the same problem as gdb for VC/VS compiled programs. The debugging symbols wil lstill be all funky from VS/VC.

Go and check GDB STL support, for it to be full of good informations like "When you try to use GDB's "print" command to display the contents of a vector, a stack, or any other GDB abstract data structure, you will get useless results. Instead, download and install one of following tools to properly view the contents of STL containers from within GDB."

And also some tools to have better STL view with gdb.

https://sourceware.org/gdb/wiki/STLSupport

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Peter Hull
Member #1,136
March 2001

It still doesn't have any clue how to properly output the STL

I had a quick try, on GDB 7.12 (using Fedora 25) it just printed out std::strings as the string contents.

(gdb) print sub
$1 = "hello"

Quote:

Note that when printing out a std::string, it gives me "_M_allocated_capacity = 978143556". Why would a std::string be reserving 978 MB of space? It's obviously wrong.

It's because std::string holds its contents internally as part of the structure (for short strings) or as a separately allocated block (for long strings) so _M_allocated_capacity is in a union with _M_local_buf - in your case you've got a short string , so I suppose 978143556 is the numerical representation of the first 32 bits of your string, 0x3A4D4944 == ':' 'M' 'I' 'D'.

The cut-off between short and long is about 15 chars (in the STL on my computer)

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Thanks for the link GullRaDriel, it looks like it might be useful.

@Peter
Fedora comes with pretty print integrated into gdb. GDB 7.12 with MSYS does not. I'll have to try that out. It's a python extension that works with ~/.gdbinit.

Thank you for the information regarding std::string. I never would have expected they were using a union. To be honest, it doesn't make much sense, and reeks of minimalist paranoia, but you're right, it was holding the string and was part of a union.

Try printing out more complicated STL types like vector, list, map or unordered_set and see if you still get nice results.

Erin Maus
Member #7,537
July 2006
avatar

I've had decent luck with lldb. It generally pretty prints types.

Also, it's a lot more consistent than GDB, which makes it easier to memorize commands.

---
ItsyRealm, a quirky 2D/3D RPG where you fight, skill, and explore in a medieval world with horrors unimaginable.
they / she

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Are you fairly experienced with Clang and LLVM? It would be nice to have a short tutorial. I tried to compile the test file from above with a fresh install of Clang32 and got a bunch of errors related to including <vector> and it was searching Program Files and Visual Studio for headers.

Erin Maus
Member #7,537
July 2006
avatar

Sorry, but I've got no idea how to use Clang on Windows! I didn't have much luck a couple years ago before I switched to FreeBSD.

Does this help?

Clang (not GCC!) is the default compiler for FreeBSD. It literally ships with the OS as part of the base system.

---
ItsyRealm, a quirky 2D/3D RPG where you fight, skill, and explore in a medieval world with horrors unimaginable.
they / she

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I don't know if Clang really works on Windows....

They have a 32bit and 64bit installer, but it seems there are no headers for libc and c++ available that function on Windows... ???

What's the point of installing a C++ compiler that can't compile C++? :/

EDIT
I am getting the gist that it's supposed to integrate with either MinGW or MSVC's standard libraries, but I haven't the faintest clue how to do so.

Go to: