std::sort 中的 SIGSEGV,如何缩小范围

2022-01-12 00:00:00 segmentation-fault c++

这是与 this one 相关的帖子,因为它处理相同的程序,但是我现在实现了它迭代而不是递归,但是在运行程序时我仍然得到 SIGSEGV(但稍后).我对我的程序进行了一些其他更改以缩小范围,并且我认为将对象向量更改为 ptr 到堆上对象的向量确实给了我一些额外的回合(大约 200 次),但仍然崩溃.我建议以某种方式在程序中保存变量的内存耗尽,但是当我转储程序的堆栈大小时:

This is a related post to this one as it deals with the same program, but i now implemented it iterative and not recursive anymore, but I still get SIGSEGV (but later) while running the program. I did some other changes to my program to narrow it down, and I figured that changing a vector of objects, to a vector of ptr to the objects on the heap does give me some extra rounds (about 200), but still crashes. I suggest that somehow my memory to save variables within the program gets exhausted, but as I dump the stacksize of the program:

rlimit rlim;
getrlimit(RLIMIT_STACK,&rlim);

std::cout << "rlim_cur ist:" << rlim.rlim_cur << std::endl;
std::cout << "rlim_max ist:" << rlim.rlim_max << std::endl;

输出是:

rlim_cur ist:8388608
rlim_max ist:18446744073709551615

而且这似乎很大并且没有用完,还有其他相关的转储限制吗进一步缩小我的问题并希望解决它?

and this seems to be pretty big and not used up, are there any other relevant limits to dump to narrow my problem down further and hopefully solve it?

这里是我的调试器的转储:

Here the dump of my debugger:

Program received signal SIGSEGV, Segmentation fault.
0x000000000040b2a0 in Town::get_cur_capacity (this=0x0) at ./solver/Darstellung.cpp:98
98      return left_over_capacity;
(gdb) backtrace
#0  0x000000000040b2a0 in Town::get_cur_capacity (this=0x0) at ./solver/Darstellung.cpp:98
#1  0x000000000040b9ab in Town::compare_by_capacity (eins=0x0, zwei=0x0) at ./solver/Darstellung.cpp:135
#2  0x00000000004124c7 in std::__move_median_first<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__a=..., __b=..., __c=..., 
    __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:108
#3  0x0000000000411250 in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__first=..., __last=..., 
    __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2260
#4  0x000000000040f111 in std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, long, bool (*)(Town const*, Town const*)> (__first=..., __last=..., __depth_limit=21, 
    __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2302
#5  0x000000000040de63 in std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__first=..., __last=..., __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>)
    at /usr/include/c++/4.5/bits/stl_algo.h:5250
#6  0x000000000040ce5a in Solution_Stack::get_towns_by_capacity (this=0x7fffffffe010) at ./solver/Darstellung.cpp:331
#7  0x000000000040a6cf in solver::treat_towns_with_zero_capacity (ptr=0x7fffffffe010) at ./solver/Solver.cpp:184
#8  0x0000000000409ff2 in solver::solve_problem (ptr=0x7fffffffe010) at ./solver/Solver.cpp:94
#9  0x000000000041475f in main (argc=3, argv=0x7fffffffe208) at ./main/Main.cpp:50

添加检查功能以追踪零值后的新转储:

The new dump after adding a check-function to trace down zero values:

    #0  0x000000000040b2a0 in Town::get_cur_capacity (this=0x40) at ./solver/Darstellung.cpp:98
    #1  0x000000000040b9e9 in Town::compare_by_index (eins=0x40, zwei=0x73b4d0) at ./solver/Darstellung.cpp:139
    #2  0x000000000040bad1 in Town::compare_by_index_inv (eins=0x40, zwei=0x73b4d0) at ./solver/Darstellung.cpp:153
    #3  0x00000000004127ea in std::__unguarded_partition<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, Town*, bool (*)(Town const*, Town const*)> (
        __first=..., __last=..., __pivot=@0x631ef0, __comp=0x40baae <Town::compare_by_index_inv(Town const*, Town const*)>)
        at /usr/include/c++/4.5/bits/stl_algo.h:2229
    #4  0x0000000000411444 in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (
        __first=..., __last=..., __comp=0x40baae <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2261
    #5  0x000000000040f2c5 in std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, long, bool (*)(Town const*, Town const*)> (
        __first=..., __last=..., __depth_limit=7, __comp=0x40baae <Town::compare_by_index_inv(Town const*, Town const*)>)
        at /usr/include/c++/4.5/bits/stl_algo.h:2302
    #6  0x000000000040e017 in std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__first=..., __last=..., 
        __comp=0x40baae <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:5250
    #7  0x000000000040d1e6 in Solution_Stack::get_partners_of_by_index_inv (this=0x7fffffffe010, id=523) at ./solver/Darstellung.cpp:371
    #8  0x000000000040a4d7 in solver::treat_towns_considering_their_index (ptr=0x7fffffffe010) at ./solver/Solver.cpp:165
    #9  0x000000000040a016 in solver::solve_problem (ptr=0x7fffffffe010) at ./solver/Solver.cpp:100
    #10 0x0000000000414913 in main (argc=3, argv=0x7fffffffe208) at ./main/Main.cpp:50

Valgrind 把这个作为垃圾场给了我,反正就在问题曾经发生的地方.由于它的大小,我很困惑:

Valgrind gave me this as a dump, just at the place where the problem used to occure anyways. I is quite confusing to me, due to its size:

==16150== Invalid read of size 4
==16150==    at 0x40B2A0: Town::get_cur_capacity() const (Darstellung.cpp:98)
==16150==    by 0x40B9AA: Town::compare_by_capacity(Town const*, Town const*) (Darstellung.cpp:135)
==16150==    by 0x4124C6: void std::__move_median_first<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:108)
==16150==    by 0x41124F: __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > > std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:2260)
==16150==    by 0x40F110: void std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, long, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, long, bool (*)(Town const*, Town const*)) (stl_algo.h:2302)
==16150==    by 0x40DE62: void std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:5250)
==16150==    by 0x40CE59: Solution_Stack::get_towns_by_capacity() (Darstellung.cpp:331)
==16150==    by 0x40A6CE: solver::treat_towns_with_zero_capacity(Solution_Stack*) (Solver.cpp:184)
==16150==    by 0x409FF1: solver::solve_problem(Solution_Stack*) (Solver.cpp:94)
==16150==    by 0x41475E: main (Main.cpp:50)
==16150==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
==16150== 
==16150== 
==16150== Process terminating with default action of signal 11 (SIGSEGV)
==16150==  Access not within mapped region at address 0x8
==16150==    at 0x40B2A0: Town::get_cur_capacity() const (Darstellung.cpp:98)
==16150==    by 0x40B9AA: Town::compare_by_capacity(Town const*, Town const*) (Darstellung.cpp:135)
==16150==    by 0x4124C6: void std::__move_median_first<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:108)
==16150==    by 0x41124F: __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > > std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:2260)
==16150==    by 0x40F110: void std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, long, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, long, bool (*)(Town const*, Town const*)) (stl_algo.h:2302)
==16150==    by 0x40DE62: void std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:5250)
==16150==    by 0x40CE59: Solution_Stack::get_towns_by_capacity() (Darstellung.cpp:331)
==16150==    by 0x40A6CE: solver::treat_towns_with_zero_capacity(Solution_Stack*) (Solver.cpp:184)
==16150==    by 0x409FF1: solver::solve_problem(Solution_Stack*) (Solver.cpp:94)
==16150==    by 0x41475E: main (Main.cpp:50)
==16150==  If you believe this happened as a result of a stack
==16150==  overflow in your program's main thread (unlikely but
==16150==  possible), you can try to increase the size of the
==16150==  main thread stack using the --main-stacksize= flag.
==16150==  The main thread stack size used in this run was 8388608.
==16150== 
==16150== HEAP SUMMARY:
==16150==     in use at exit: 771,174 bytes in 19,239 blocks
==16150==   total heap usage: 9,821,251 allocs, 9,802,012 frees, 384,861,557 bytes allocated
==16150== 
==16150== 50,678 bytes in 1,491 blocks are possibly lost in loss record 28 of 35
==16150==    at 0x4C28B42: operator new(unsigned long) (vg_replace_malloc.c:261)
==16150==    by 0x4ECBE6C: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14)
==16150==    by 0x4ECC08D: std::string::_M_mutate(unsigned long, unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14)
==16150==    by 0x4ECC730: std::string::erase(unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14)
==16150==    by 0x407FB6: utility::split_helper(std::string, std::string) (Tools.cpp:28)
==16150==    by 0x4080B5: utility::split_helper(std::string, std::string) (Tools.cpp:49)
==16150==    by 0x4081C3: utility::split(std::string, std::string) (Tools.cpp:66)
==16150==    by 0x40539C: parser::get_city_prototypes(std::vector<std::string, std::allocator<std::string> >) (Parser.cpp:27)
==16150==    by 0x4050EB: parser::get_problem_configuration(std::string, std::string) (Parser.cpp:17)
==16150==    by 0x414699: main (Main.cpp:34)
==16150== 
==16150== 62,606 (11,928 direct, 50,678 indirect) bytes in 1,491 blocks are definitely lost in loss record 30 of 35
==16150==    at 0x4C28B42: operator new(unsigned long) (vg_replace_malloc.c:261)
==16150==    by 0x407F68: utility::split_helper(std::string, std::string) (Tools.cpp:24)
==16150==    by 0x4080B5: utility::split_helper(std::string, std::string) (Tools.cpp:49)
==16150==    by 0x4081C3: utility::split(std::string, std::string) (Tools.cpp:66)
==16150==    by 0x40539C: parser::get_city_prototypes(std::vector<std::string, std::allocator<std::string> >) (Parser.cpp:27)
==16150==    by 0x4050EB: parser::get_problem_configuration(std::string, std::string) (Parser.cpp:17)
==16150==    by 0x414699: main (Main.cpp:34)
==16150== 
==16150== 94,406 (18,440 direct, 75,966 indirect) bytes in 2,305 blocks are definitely lost in loss record 32 of 35
==16150==    at 0x4C28B42: operator new(unsigned long) (vg_replace_malloc.c:261)
==16150==    by 0x407F68: utility::split_helper(std::string, std::string) (Tools.cpp:24)
==16150==    by 0x4080B5: utility::split_helper(std::string, std::string) (Tools.cpp:49)
==16150==    by 0x4081C3: utility::split(std::string, std::string) (Tools.cpp:66)
==16150==    by 0x40573F: parser::get_finished_cities(std::vector<std::string, std::allocator<std::string> >, std::vector<City*, std::allocator<City*> >) (Parser.cpp:42)
==16150==    by 0x40511A: parser::get_problem_configuration(std::string, std::string) (Parser.cpp:17)
==16150==    by 0x414699: main (Main.cpp:34)
==16150== 
==16150== 178,720 (131,208 direct, 47,512 indirect) bytes in 1,491 blocks are definitely lost in loss record 35 of 35
==16150==    at 0x4C28B42: operator new(unsigned long) (vg_replace_malloc.c:261)
==16150==    by 0x40541B: parser::get_city_prototypes(std::vector<std::string, std::allocator<std::string> >) (Parser.cpp:28)
==16150==    by 0x4050EB: parser::get_problem_configuration(std::string, std::string) (Parser.cpp:17)
==16150==    by 0x414699: main (Main.cpp:34)
==16150== 
==16150== LEAK SUMMARY:
==16150==    definitely lost: 161,576 bytes in 5,287 blocks
==16150==    indirectly lost: 174,156 bytes in 5,287 blocks
==16150==      possibly lost: 50,678 bytes in 1,491 blocks
==16150==    still reachable: 384,764 bytes in 7,174 blocks
==16150==         suppressed: 0 bytes in 0 blocks
==16150== Reachable blocks (those to which a pointer was found) are not shown.
==16150== To see them, rerun with: --leak-check=full --show-reachable=yes
==16150== 
==16150== For counts of detected and suppressed errors, rerun with: -v
==16150== Use --track-origins=yes to see where uninitialised values come from
==16150== ERROR SUMMARY: 7 errors from 7 contexts (suppressed: 4 from 4)

推荐答案

#0  0x000000000040b2a0 in Town::get_cur_capacity (this=0x0) at ./solver/Darstellung.cpp:98

看起来您正在对 NULL 指针调用 get_cur_capacity.您是从比较器到达这里的:

It looks like you're invoking get_cur_capacity on a NULL pointer. You're getting here from a comparator:

#1  0x000000000040b9ab in Town::compare_by_capacity (eins=0x0, zwei=0x0) at ./solver/Darstellung.cpp:135

将 NULL 与 NULL 进行比较.你从 sort 进一步到达这里:

which is comparing NULL to NULL. You further get here from a sort:

#5  0x000000000040de63 in std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__first=..., __last=..., __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>)
    at /usr/include/c++/4.5/bits/stl_algo.h:5250

这是排序std::vector,调用自:

#6  0x000000000040ce5a in Solution_Stack::get_towns_by_capacity (this=0x7fffffffe010) at ./solver/Darstellung.cpp:331

您正在排序的向量很可能包含 NULL 指针,并且您的 compare_by_capacity 函数未准备好处理这种可能性.要么确保向量没有 NULL,要么让 compare_by_capacity 显式检查 NULL 并做一些合理的事情(例如,在除另一个 NULL 之外的任何内容之前对其进行排序).

Most likely the vector you're sorting contains NULL pointers, and your compare_by_capacity function is not prepared to handle this eventuality. Either make sure the vector has no NULLs, or have compare_by_capacity explicitly check for NULL and do something sensible (eg, sort it before anything other than another NULL).

#1  0x000000000040b9e9 in Town::compare_by_index (eins=0x40, zwei=0x73b4d0) at ./solver/Darstellung.cpp:139

这个 0x40 看起来您有未初始化的内存或损坏的内存.你如何调整这个向量的大小?

This 0x40 looks like you have either uninitialized memory or corrupted memory. How are you resizing this vector?

在不实际查看任何代码的情况下尝试诊断此问题确实非常困难.

It's really quite difficult to try to diagnose this without actually seeing any of your code.

相关文章