Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Simple code, crazy behavior

This thread is locked; no one can reply to it. rss feed Print
Simple code, crazy behavior
Edgar Reynaldo
Major Reynaldo
May 2007
avatar

EDIT
I found the bug. It was in line 26. The call to string::substr takes a start index and a count, not a stop index, which is what I was doing.
As soon as I changed line 26 to :

    string sub = string_to_split.substr(start_index, stop_index - start_index);

Then it (the function) worked again. GDB is still doing the same crazy thing, going from line 28 to line 26. I can't explain that. EDIT - The MSVC2015 Debugger doesn't do that. :/

--------------------------------------------------------

I am attempting to debug my GUI library, specifically, the SplitByDelimiterString function. It is doing some really crazy things that I can't explain.

Can you guys look at my code and see if there is anything wrong with it? This simple program just does not do what it is supposed to.

#SelectExpand
1#include <vector> 2#include <string> 3#include <iostream> 4 5using namespace std; 6 7 8 9vector<string> SplitByDelimiterString(string string_to_split , const string token) { 10 11 vector<string> tokens; 12 size_t start_index = 0; 13 size_t stop_index = 0; 14 15 if (string_to_split.size() == 0) { 16 return tokens; 17 } 18 19 const size_t split_string_size = string_to_split.size(); 20 21 while (stop_index <= split_string_size && start_index < split_string_size) { 22 stop_index = string_to_split.find_first_of(token , start_index); 23 if (stop_index == string::npos) { 24 stop_index = string_to_split.size(); 25 } 26 string sub = string_to_split.substr(start_index , stop_index); 27 tokens.push_back(sub); 28 start_index = stop_index + token.size(); 29 } 30 return tokens; 31} 32 33 34 35int main(int argc , char** argv) { 36 37 vector<string> strs = SplitByDelimiterString("DIM:200,50 ; FONT:Verdana20 ; TEXT:Quit" , ";"); 38 cout << strs.size() << endl; 39 for (int i = 0 ; i < (int)strs.size() ; ++i) { 40 cout << strs[i] << endl; 41 } 42 43 return 0; 44 45}

Take a look at this debugging session from gdb. It does crazy things, like jumping lines in source code :

#SelectExpand
1 2c:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\test>mingw32-g++ -Wall -g -o st.exe SplitTest.cpp 3 4c:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\test>gdb st.exe 5GNU gdb (GDB) 7.6.1 6Copyright (C) 2013 Free Software Foundation, Inc. 7License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 8This is free software: you are free to change and redistribute it. 9There is NO WARRANTY, to the extent permitted by law. Type "show copying" 10and "show warranty" for details. 11This GDB was configured as "mingw32". 12For bug reporting instructions, please see: 13<http://www.gnu.org/software/gdb/bugs/>... 14Reading symbols from c:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\test\st.exe...done. 15(gdb) break SplitTest.cpp:22 16Breakpoint 1 at 0x401499: file SplitTest.cpp, line 22. 17(gdb) run 18Starting program: c:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\test/st.exe 19[New Thread 15428.0x407c] 20[New Thread 15428.0x403c] 21[New Thread 15428.0x2b5c] 22[New Thread 15428.0x2968] 23 24Breakpoint 1, SplitByDelimiterString (string_to_split=..., token=...) at SplitTest.cpp:22 2522 stop_index = string_to_split.find_first_of(token , start_index); 26(gdb) continue 27Continuing. 28 29Breakpoint 1, SplitByDelimiterString (string_to_split=..., token=...) at SplitTest.cpp:22 3022 stop_index = string_to_split.find_first_of(token , start_index); 31(gdb) 32Continuing. 33 34Breakpoint 1, SplitByDelimiterString (string_to_split=..., token=...) at SplitTest.cpp:22 3522 stop_index = string_to_split.find_first_of(token , start_index); 36(gdb) 37Continuing. 383 39DIM:200,50 40 FONT:Verdana20 ; TEXT:Quit 41 TEXT:Quit 42[Inferior 1 (process 15428) exited normally] 43(gdb) run 44Starting program: c:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\test/st.exe 45[New Thread 2584.0x3518] 46[New Thread 2584.0xca4] 47[New Thread 2584.0x2a54] 48[New Thread 2584.0x225c] 49 50Breakpoint 1, SplitByDelimiterString (string_to_split=..., token=...) at SplitTest.cpp:22 5122 stop_index = string_to_split.find_first_of(token , start_index); 52(gdb) n 5323 if (stop_index == string::npos) { 54(gdb) n 5526 string sub = string_to_split.substr(start_index , stop_index); 56(gdb) n 5727 tokens.push_back(sub); 58(gdb) n 5928 start_index = stop_index + token.size(); 60(gdb) n 6126 string sub = string_to_split.substr(start_index , stop_index); 62(gdb) quit 63A debugging session is active. 64 65 Inferior 1 [process 2584] will be killed. 66 67Quit anyway? (y or n) y 68error return ../../gdb-7.6.1/gdb/windows-nat.c:1275 was 5 69 70c:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\test>

For some unknown reason, when typing 'next' gdb jumps from line 28 to line 26, skipping lines 22-25.

Is this a bug in MinGW? GDB? My code?

I'm about to tear my hair out.

Halp!

Edgar

EDIT
FWIW, mingw-w64-x86_64 g++ 6.2.0 and gdb 7.12 does exactly the same thing. I originally compiled it with MinGW 5.3.0 and ran it with gdb 7.6.1.

Mark Oates
Member #1,146
March 2001
avatar

I'm just curious. What does your st.exe source look like?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

st.exe was compiled from StringTest.cpp which was given above exactly as written.

Edit
Gdb goes from line 28 to the next line (an empty brace) and calls it line 26. Definitely a bug in gdb.

Mark Oates
Member #1,146
March 2001
avatar

The naming convention of "test" throws me a bit. To me, that would indicate that this is a test file, as in, a file that contains code that performs a list of tests outputting "pass" or "fail" for each test.

Test files look a bit different, and usually consist of several test cases, where each test case checks that a single piece of expected behavior works by using assertions.

GullRaDriel
Member #3,861
September 2003
avatar

That's why I never use the STL.
Never.

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

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

The naming convention of "test" throws me a bit. To me, that would indicate that this is a test file, as in, a file that contains code that performs a list of tests outputting "pass" or "fail" for each test.

Test files look a bit different, and usually consist of several test cases, where each test case checks that a single piece of expected behavior works by using assertions.

Pedantic much? It's not named UnitTest, it's named SplitTest, and all it does is test whether a given string splits properly or not. What are you so worried about my naming conventions for? It's a simple throw away test file, who cares what I name it? Maybe later I'll expand it to actually do unit tests, I don't know, who cares so what? I only used it to isolate code that wasn't performing as expected. Sorry I didn't name it properly for you. :/

Also, please do note that assertions are not normally catchable by a debugger. Good luck debugging with assertions if they don't throw a catchable signal.

Mark Oates
Member #1,146
March 2001
avatar

;D I'm just tellin you how it is man

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

So you know how it is then? Congratulations on knowing everything.

You didn't find the bug, you didn't offer alternatives to gdb or explanations as to why it does crazy things. Seems like there are a few things you don't know yet. :/

Go to: