简体   繁体   中英

Segmentation Fault on std::string

I am running an application which stops at one point because of segmentation fault. I will try to enlist the enviroment: - The application has a class (Generator) which contains a std::string member (data ) and this member is duly intialized to "HelloWorld". - A pointer of this object is passed to a member function(send1) of another class (Product). As soon as I try to print the value of data inside the function it gives segmentation fault. If i try to print the value of data before calling the send1 function it gets correctly printed.

Here is the gdb output :

(gdb) br Generator::test
Breakpoint 1 at 0x80499ef: file ../app/generator/src/generator.cpp, line 58.
(gdb) br Product::send1
Breakpoint 2 at 0x804a17e: file ../app/configurator/src/product.cpp, line 43.
(gdb) run
[Thread debugging using libthread_db enabled]
[New Thread -1208071520 (LWP 18389)]
[Switching to Thread -1208071520 (LWP 18389)]

Breakpoint 1, Generator::test (this=0x9917020) at ../app/generator/src/generator.cpp:58
58                 cout << "data = " << this->data << endl;
(gdb) n
data = HelloWorld
59                 Product* ptr = new Product;
(gdb) n
60                 bool status = ptr->send1( this );
(gdb) s

Breakpoint 2, Product::send1 (this=0x99170c8, genptr=0x9917020) at ../app/configurator/src/product.cpp:43
43              cout << genptr->data << endl;
(gdb) p genptr->data 
$1 = {static npos = 4294967295, 
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    _M_p = 0x99170b4 "HelloWorld"}}
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x076751e6 in std::operator<< <char, std::char_traits<char>, std::allocator<char> > () from /usr/lib/libstdc++.so.6
(gdb) bt
#0  0x076751e6 in std::operator<< <char, std::char_traits<char>, std::allocator<char> > () from /usr/lib/libstdc++.so.6
#1  0x0804a19a in Product::send1 (this=0x99170c8, genptr=0x9917020) at ../app/configurator/src/product.cpp:43
#2  0x08049a85 in Generator::test (this=0x9917020) at ../app/generator/src/generator.cpp:60
#3  0x08048f4c in Configure::init (this=0x9917008) at ../app/configurator/src/configurator.cpp:89
#4  0x08048c93 in main (argc=1, argv=0xbfed7364) at ../launch/main/src/appLaunch.cpp:20
(gdb) 

Here is the valgrind output

valgrind --tool=memcheck --leak-check=yes ./application 
==18328== Memcheck, a memory error detector.
==18328== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==18328== Using LibVEX rev 1575, a library for dynamic binary translation.
==18328== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==18328== Using valgrind-3.1.1, a dynamic binary instrumentation framework.
==18328== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==18328== For more details, rerun with: -v
==18328== 
data = HelloWorld
==18328== Invalid read of size 4
==18328==    at 0x76751E6: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /usr/lib/libstdc++.so.6.0.3)
==18328==    by 0x804A199: Product::send1(Generator*) (product.cpp:43)
==18328==    by 0x8049A84: Generator::test() (generator.cpp:60)
==18328==    by 0x8048F4B: Configure::init() (configurator.cpp:89)
==18328==    by 0x8048C92: main (appLaunch.cpp:20)
==18328==  Address 0x5C040234 is not stack'd, malloc'd or (recently) free'd
==18328== 
==18328== Process terminating with default action of signal 11 (SIGSEGV)
==18328==  Access not within mapped region at address 0x5C040234
==18328==    at 0x76751E6: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /usr/lib/libstdc++.so.6.0.3)
==18328==    by 0x804A199: Product::send1(Generator*) (product.cpp:43)
==18328==    by 0x8049A84: Generator::test() (generator.cpp:60)
==18328==    by 0x8048F4B: Configure::init() (configurator.cpp:89)
==18328==    by 0x8048C92: main (appLaunch.cpp:20)
==18328== 
==18328== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 1)
==18328== malloc/free: in use at exit: 159 bytes in 5 blocks.
==18328== malloc/free: 5 allocs, 0 frees, 159 bytes allocated.
==18328== For counts of detected errors, rerun with: -v
==18328== searching for pointers to 5 not-freed blocks.
==18328== checked 116,636 bytes.

This is actually a part of a bigger application but I have stripped the application and made it very small so that I can easily debug the issue but even now I am having no clue why this issue is occuring. Using gdb I have tried to check the memory layout but before and after calling the function the memory addresses and content looks intact. Infact if I try to print the value of data using gdb print function it comes out to be correct. I have tried many things like allocating memory on heap etc but nothing seems to work. Request you to kindly guide me how can I start debugging this issue.

It would be nice to see the declaration and implementation of send1, very difficult to help otherwise. Do Product/Generator have any virtual functions?

Why write cout << "Data= " << this->data << endl; rather than just data? Does that make any difference?

Try changing Product::send1(Generator* genptr) to Product::send1(const Generator& gen) and call it with ptr->send1(*this) and see if that has the same problem.

My best guess is that genptr has been deleted/destroyed, but the memory used by it has not yet been overwritten by the time you print out the contents of genptr->data in the debugger. However, the ostream operator<< function internally allocates some memory and that just happens to reuse the same space, so its overwritten by the time it actually goes and tries to print the string, leading to a crash.

You can check this by looking at the memory at 0x9917020 (where genptr points) after the SEGV and see if its changed. You should be able to do up and then p genptr->data at the final gdb prompt above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM