mercredi 22 septembre 2021

Why the value-returning function without a return statement cause a core dump?

look at the code as follows, the function foo should return a map, but it doesn't. Finally, the program is crashed.

#include <iostream>
#include <map>

std::map<int, int> foo(int i){
  std::cout << i <<  ": foo is called." << std::endl;
}
int main(){
  foo(1);
  return 0;
}

Then I try to use gdb to get more info

(gdb) break 4
Breakpoint 1 at 0x4008e6: file main.cc, line 4.
(gdb) r
Starting program: /data/home/kungli/tmp/cpp-test/core-test/main 

Breakpoint 1, foo (i=1) at main.cc:5
5     std::cout << i <<  ": foo is called." << std::endl;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.tl2.3.x86_64 libgcc-7.3.1-6.tl2.x86_64 libstdc++-7.3.1-6.tl2.x86_64
(gdb) s
1: foo is called.
6   }
(gdb) s
std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::~map (this=0x7fffffffe170, __in_chrg=<optimized out>) at /usr/include/c++/7/bits/stl_map.h:294
294       ~map() = default;
(gdb) s
std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::~_Rb_tree (this=0x7fffffffe170, __in_chrg=<optimized out>)
    at /usr/include/c++/7/bits/stl_tree.h:949
949       { _M_erase(_M_begin()); }
(gdb) s
std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_begin (this=0x7fffffffe170)
    at /usr/include/c++/7/bits/stl_tree.h:737
737       { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
(gdb) s
std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_erase (this=0x7fffffffe170, __x=0x400c60 <__libc_csu_init>)
    at /usr/include/c++/7/bits/stl_tree.h:1854
1854          while (__x != 0)
(gdb) s
1856          _M_erase(_S_right(__x));
(gdb) s
std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_S_right (__x=0x400c60 <__libc_csu_init>)
    at /usr/include/c++/7/bits/stl_tree.h:772
772       { return static_cast<_Link_type>(__x->_M_right); }
(gdb) s
std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_erase (this=0x7fffffffe170, __x=0x2011702d8d4855)
    at /usr/include/c++/7/bits/stl_tree.h:1854
1854          while (__x != 0)
(gdb) s
1856          _M_erase(_S_right(__x));
(gdb) s
std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_S_right (__x=0x2011702d8d4855)
    at /usr/include/c++/7/bits/stl_tree.h:772
772       { return static_cast<_Link_type>(__x->_M_right); }
(gdb) s

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ab3 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_S_right (__x=0x2011702d8d4855)
    at /usr/include/c++/7/bits/stl_tree.h:772
772       { return static_cast<_Link_type>(__x->_M_right); }
(gdb) s

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

According to return statement, we know that Flowing off the end of a value-returning function (except main) without a return statement is undefined behavior. But I don't understand why the dtor of map is called? (gcc version 7.3.1)

Aucun commentaire:

Enregistrer un commentaire