Gdb empty string turns into gobbledygook when passed to function - c++

Take a look at the gdb output below. To recap: endString is an empty string, until it is passed as the argument to a constructor.
I'm stumped. Would this maybe indicate stack corruption?
367 string endString = fTable[i][endTimeIndex];
(gdb) p endString
$2 = ""
(gdb) n
369 TimeData endObj = TimeData(endString);
(gdb) step
TimeData::TimeData (this=0xbfb60550, fIsoTime=
"\000F;\267\370\063(\267\f\361%\267\027\364%\267\023\000\000\000\230\000\000\000\000\300\067\267\004\357\067\267\300\063(\267\300\000\000\000\360\063(\267\364\037(\267\300\063(\267h\326\n\bx\b\266\277,i\031\267\300\063(\267l\361l\267\224I\r\b\314\307k\267\224I\r\b\324\333\r\b\270\b\266\277\265\207\061\267\220\000\000\000l\361l\267\250\b\266\277b\307k\267\344\b\266\277T\n\266\277h\326\n\bl\361l\267l\361l\267\324\333\r\b\330\b\266\277J\304k\267\340\b\266\277\344\b\266\277\330\b\266\277.\275k\267h\326\n\b$\000\000\000\000\000\000\000\230I\r\bl\361l\267\bI\r\b\370\b\266\277\200\276k\267\330\333\r\b\330\333\r\b\bI\r\bp\266k\267<\t\266\277l\361l\267\030\t\266\277\363\266k\267H\333\r\b\330\333\r\b\bI\r\bH\333\r\bl\361l\267l\361l\267X\t\266\277\327\255k\267H\333\r\bF1\031\267\bI\r\bwYh\267\300\063(\267\001\000\000\000\330\333\r\bH\333\r\bX\t\266\277]h\031\267h\t\266\277t\326\n\b\344\361h\267\000\000\000\000x\t\266\277MOh\267\000\000\000\000\000\000\000\000\021\001\000\000 \000\000\000\300"... <Address 0xbfb63000 out of bounds>, __in_chrg=<optimized out>,
__vtt_parm=<optimized out>) at TimeData.cpp:164
As requested:
(gdb) p endString
$4 = ""
(gdb) p endString.size()
$5 = 0

Related

GDB help to analyse core

One of our code is generating a core file
While trying to analyse core using gdb with below commands
gdb programe_name core
I am unable to retrieve the tarce with backtrace command getting below
#4 0x20202020 in ?? ()
#5 0x20202020 in ?? ()
#6 0x20202020 in ?? ()
#7 0x20202020 in ?? ()
#8 0x20202020 in ?? ()
#9 0x20202020 in ?? ()
#10 0x20202020 in ?? ()
#11 0x20202020 in ?? ()
#12 0x20202020 in ?? ()
#13 0x20202020 in ?? ()
#14 0x20202020 in ?? ()
#15 0x20202020 in ?? ()
#16 0x20202020 in ?? ()
#17 0x20202020 in ?? ()
#18 0x20202020 in ?? ()
#19 0x20202020 in ?? ()
do we have a command which I can use to get trace with function name and arguments
It looks like your stack has been "crunched" -- that is, overwritten with some data that shouldn't be there.
0x20202020 is four spaces in ASCII, so the stack has been overwritten by a string of characters with a lot of spaces.
Look for an array (or variable) that you are reading into (or copying characters into); the chances are you are reading/copying more data than you expected into that array/variable.
To avoid this sort of thing in the future, use one of the forms that allows you to limit the amount read/copied to the size of the target area:
fread
fgets
strncpy
You might want to also take a look at the answers to
Reading in a variable length string user input in C
As relatively safe ways to protect yourself when reading data of unknown length into a buffer.

Load gdb sources marked as "read on demand"

I am debugging a C application (postgres) in GDB. When I hit a breakpoint, the top frame of the stack will always have source information, but lower frames often will not:
(gdb) bt
#0 findTargetlistEntrySQL99 (pstate=0x555555ef8f78, node=0x555555ef8c08, tlist=0x555555ef90d0, exprKind=EXPR_KIND_GROUP_BY) at /home/sergei/postgresql/src/backend/parser/parse_clause.c:1775
#1 0x00005555556c6e9d in findTargetlistEntrySQL92 (pstate=<optimized out>, node=<optimized out>, tlist=<optimized out>, exprKind=<optimized out>) at /home/sergei/postgresql/src/backend/parser/parse_clause.c:1744
#2 0x00005555556c72d5 in transformGroupClauseExpr (flatresult=flatresult#entry=0x7fffffffd0a0, seen_local=seen_local#entry=0x0, pstate=pstate#entry=0x555555ef8f78, gexpr=gexpr#entry=0x555555ef8c08, targetlist=targetlist#entry=0x555555ef90d0, sortClause=sortClause#entry=0x0, exprKind=EXPR_KIND_GROUP_BY, useSQL99=0 '\000', toplevel=1 '\001') at /home/sergei/postgresql/src/backend/parser/parse_clause.c:1970
#3 0x00005555556c9192 in transformGroupClause (pstate=0x555555ef8f78, grouplist=<optimized out>, groupingSets=0x555555ef90f0, targetlist=0x555555ef90d0, sortClause=0x0, exprKind=EXPR_KIND_GROUP_BY, useSQL99=0 '\000') at /home/sergei/postgresql/src/backend/parser/parse_clause.c:2287
#4 0x00005555556aa111 in transformStmt ()
#5 0x00005555556abe6d in parse_analyze ()
#6 0x000055555574c50e in DefineView ()
#7 0x0000555555867bda in ProcessUtilitySlow.isra.4 ()
#8 0x0000555555866a97 in standard_ProcessUtility ()
#9 0x0000555555864084 in PortalRunUtility ()
#10 0x0000555555864b95 in PortalRunMulti ()
#11 0x00005555558657a4 in PortalRun ()
#12 0x00005555558631f2 in exec_simple_query (query_string=0x555555ea6de0 "-- Statistics views\n\nCREATE VIEW pg_stat_all_tables AS\n SELECT\n", ' ' <repeats 12 times>, "C.oid AS relid,\n", ' ' <repeats 12 times>, "N.nspname AS schemaname,\n", ' ' <repeats 12 times>, "C.relname AS relname,\n", ' ' <repeats 12 times>, "pg_stat_get_numscans(C."...) at /home/sergei/postgresql/src/backend/tcop/postgres.c:1094
#13 PostgresMain (argc=<optimized out>, argv=<optimized out>, dbname=<optimized out>, username=<optimized out>) at /home/sergei/postgresql/src/backend/tcop/postgres.c:4069
#14 0x00005555555f719d in main ()
At first, I suspected GDB could not find the source files for the lower frames. However, this is not the case: info sources shows these source files, but they are marked as "read on demand". For example, the function DefineView in frame 6 is defined in view.c.
(gdb) info sources
Source files for which symbols have been read in:
...
Source files for which symbols will be read in on demand:
... , /home/sergei/postgresql/src/backend/commands/view.c , ...
All source file paths (including view.c) are correct. How can I get GDB to load these sources? I am using GDB from an IDE, so solutions involving a one-off configuration change are preferrable.
The command line option gdb --readnow, should cause gdb to read symbol files as they are discovered.

gdb - execute current line without moving on

This has probably been asked elsewhere, but was a bit of a tricky one to google.
I am debugging some code like the following in gdb (or cgdb more specifically):
if(something) {
string a = stringMaker();
string b = stringMaker();
}
As I step through using 'n', the cursor will reach the 'string b' line. At this point I can inspect the value of a, but b won't have been populated yet as that line hasn't been executed. Another press of 'n' will execute that line, but will then also move outside the if loop and b will now be out of scope. Is there a way to execute the current line without moving on so that its result can be inspected before it goes out of scope?
Another press of 'n' will execute that line, but will then also move
outside the if loop and b will now be out of scope
The problem is that next executes too much instructions and b variable becomes unavailable. You can substitute this single next with a number of step and finish commands to achieve more granularity in debugging and stop immediately after b was constructed. Here is sample gdb session for test program:
[ks#localhost ~]$ cat ttt.cpp
#include <string>
int main()
{
if (true)
{
std::string a = "aaa";
std::string b = "bbb";
}
return 0;
}
[ks#localhost ~]$ gdb -q a.out
Reading symbols from a.out...done.
(gdb) start
Temporary breakpoint 1 at 0x40081f: file ttt.cpp, line 7.
Starting program: /home/ks/a.out
Temporary breakpoint 1, main () at ttt.cpp:7
7 std::string a = "aaa";
(gdb) n
8 std::string b = "bbb";
(gdb) p b
$1 = ""
(gdb) s
std::allocator<char>::allocator (this=0x7fffffffde8f) at /usr/src/debug/gcc-5.1.1-20150618/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/allocator.h:113
113 allocator() throw() { }
(gdb) fin
Run till exit from #0 std::allocator<char>::allocator (this=0x7fffffffde8f) at /usr/src/debug/gcc-5.1.1-20150618/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/allocator.h:113
0x0000000000400858 in main () at ttt.cpp:8
8 std::string b = "bbb";
(gdb) s
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (this=0x7fffffffde70, __s=0x400984 "bbb", __a=...) at /usr/src/debug/gcc-5.1.1-20150618/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/basic_string.tcc:656
656 basic_string<_CharT, _Traits, _Alloc>::
(gdb) fin
Run till exit from #0 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (this=0x7fffffffde70, __s=0x400984 "bbb", __a=...) at /usr/src/debug/gcc-5.1.1-20150618/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/basic_string.tcc:656
0x000000000040086d in main () at ttt.cpp:8
8 std::string b = "bbb";
(gdb) p b
$2 = "bbb"
Just add to the code b; the line afterwards. i.e.
if(something) {
string a = stringMaker();
string b = stringMaker();
b; // Break point here
}
Well you can always to a
(gdb) p stringMaker();
regardless of the line you're in given that stringMaker() is accessible. You can execute any kind statements , even involving variables if those variables are in current scope. For more advanced usage, you can use gdb's internal variables($1,$2 etc) to store certain result to use it later when the variables involved in that previous computation went out of scope.
Finally God(whatever that may be) send us gdb Python API. just type py and demolish your code to such extent that you will forget what you were doing at the first place.

Source line number in GDB backtrace corresponds to basically nothing

I compiled all source files using GCC with options -O0 -g3, and then I ran the corresponding binary in GDB. After receiving a SIGABRT, I performed a backtrace.
Here is the "crash" output from the run in GDB:
terminate called recursively
terminate called recursively
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
terminate called recursively
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff5baf700 (LWP 6434)]
0x00007ffff6be9037 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
Here is the GDB backtrace (which immediately followed the output shown above):
(gdb) bt
#0 0x00007ffff6be9037 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff6bec698 in __GI_abort () at abort.c:90
#2 0x00007ffff7921e8d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff791ff76 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff791f089 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff791fbc1 in __gxx_personality_v0 () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff71a615b in ?? () from /lib/x86_64-linux-gnu/libgcc_s.so.1
#7 0x00007ffff71a65b8 in _Unwind_Resume () from /lib/x86_64-linux-gnu/libgcc_s.so.1
#8 0x0000000000445b5d in simulate4_NEJMdisutilities (P=..., NNSmode=true, NNScontrol=false) at ../simulation4.cpp:1846
#9 0x0000000000420f97 in Policy::evaluate (this=0x8ad368) at ../globals.cpp:686
#10 0x000000000041201b in OCBA_SC(std::vector<Policy, std::allocator<Policy> >&, double, int, int, int, double) [clone ._omp_fn.1] () at ../OCBA.cpp:616
#11 0x00007ffff73b586a in ?? () from /usr/lib/x86_64-linux-gnu/libgomp.so.1
#12 0x00007ffff6f81f8e in start_thread (arg=0x7ffff5baf700) at pthread_create.c:311
#13 0x00007ffff6cabe1d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113
(gdb)
From frame #8, GDB seems to be claiming that the problem ensued from line 1846 in source file simulation4.cpp.
However, here is line 1846 (and surrounding lines):
1835 if(NORMAL && VALIDATION) {
1836 P.hist_PSAtest.print();
1837 P.hist_biopsy.print();
1838 P.hist_treatment.print();
1839 P.hist_getCancer.print();
1840 P.hist_getMetastasis.print();
1841 P.hist_death.print();
1842 P.hist_deathOther.print();
1843 P.hist_deathPCa.print();
1844
1845 prevalence.print();
1846 }
1847
1848 /* ------------ TESTING ------------ */
1849 #if SIMULATION4_DEBUG > 1
1850 cout << "After single execution of simulate4_NEJMdisutilities(Policy&,bool,bool):\n";
1851 cout << " Policy::QALY::sum() = " << P.QALYs.sum() << "\n";
1852 cout << " Policy::Year::sum() = " << P.Years.sum() << "\n";
1853 cout << "\n";
1854 #endif
1855 /* --------------------------------- */
1856
1857
1858 } //simulate4_NEJMdisutilities()
What could explain the discrepancy between the line numbers?
As background, I should note that I am using std::vector::at() calls in simulation4.cpp instead of the [] operator, specifically because I'm suspicious that there may be a memory corruption somewhere. Prior to switching to the at() method, I was receiving a seg fault.
I should also note that VALIDATION=false in my run, so none of the code on lines 1836--1845 is executed.
Do you have many macros in the code? If you have a lot of multi-line pre-compiler expansions (multi-line macros for example) then your "code" is modified to include that by the pre-processor before linking happens. These count as lines of code and so can throw off your debugger.

std::string::find_first_of does not return the expected value

I am trying to create an XML parser in C++. I am currently using cygwin and gcc to compile and gdb to debug. I have this piece of code:
const size_t mDataSize = mData.size();
...
size_t ltPos = mData.find_first_of('<', pos);
if (ltPos==mData.npos) {
...
mData is declared as private const std::string & within the class and holds the XML file content. After debugging with gdb I found the following:
(gdb) print pos
$12 = 636
(gdb) print mDataSize
$13 = 2692
(gdb) n
141 size_t ltPos = mData.find_first_of('<', pos);
(gdb) print ltPos
$14 = 114
(gdb) print pos
$15 = 636
(gdb) n
143 if (ltPos==mData.npos)
(gdb) print ltPos
$16 = 4294967295
(gdb) print mData[636]
$17 = (const char &) #0xb2b2a8: 10 '\n'
(gdb) print mData[637]
$18 = (const char &) #0xb2b2a9: 32 ' '
(gdb) print mData[638]
$19 = (const char &) #0xb2b2aa: 32 ' '
(gdb) print mData[639]
$20 = (const char &) #0xb2b2ab: 60 '<'
I was expecting 639 as result of calling find_first_of, but I am getting 4294967295 (which is -1 in a signed 32-bit int and matches std::string::npos). Can someone justify this behaviour? Or tell me how to workaround this?
So mData is declared as a reference? If so it doesn't really hold the content it holds a reference to the content. Is the thing to which mData refers still in existence at the time you're calling find_first_of?