This is quite strange for me, but I'm getting an unexpected and random segmentation fault when I launch my program. Some times it works, some times it crashes.. The debugger of Dev-C++ points me to a line of the file : stl_construct.h
这对我来说很奇怪,但是当我启动程序时,我遇到了意想不到的随机分段错误。有时它会工作,有时会崩溃.. Dev-C ++的调试器指向我的文件行:stl_construct.h
/**
* @if maint
* Constructs an object in existing memory by invoking an allocated
* object's constructor with an initializer.
* @endif
*/
template<typename _T1, typename _T2>
inline void
_Construct(_T1* __p, const _T2& __value)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_]allocator::construct
-> ::new(static_cast<void*>(__p)) _T1(__value);
}
I'm using the STL extensively by the way.. What should i do to detect the origin of the segfault? Are there any tools that can help? What are the reasons that can lead to random crashes like this.
顺便说一句,我正在广泛使用STL ..如何检测段错误的起源?有没有可以提供帮助的工具?导致这样的随机崩溃的原因是什么?
Edit:
My program counts around 5000 lines of code. I don't know what piece of code I have to show in order to get some help since I have no clue about the origin of the problem, all I got from the debugger is that it has to do with the STL.
我的程序大约有5000行代码。我不知道为了得到一些帮助我必须显示哪些代码,因为我对问题的根源一无所知,我从调试器得到的只是它与STL有关。
Edit:
I moved to Code::Blocks
now, here is the call stack:
我现在转移到Code :: Blocks,这里是调用堆栈:
#0 00464635 std::_Construct<std::pair<double const, int>, std::pair<double const, int> >(__p=0xb543e8, __value=@0x10) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_construct.h:81)
#1 00462306 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_create_node(this=0x406fe50, __x=@0x10) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:367)
#2 00461DA7 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_clone_node(this=0x406fe50, __x=0x0) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:379)
#3 004625C6 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_copy(this=0x406fe50, __x=0x0, __p=0x406fe54) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:1029)
#4 00462A9D std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_Rb_tree(this=0x406fe50, __x=@0xb59a7c) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:559)
#5 0045A928 std::map<double, int, std::less<double>, std::allocator<std::pair<double const, int> > >::map(this=0x406fe50, __x=@0xb59a7c) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_map.h:166)
#6 0040B7E2 VehicleManager::get_vehicles_distances(this=0xb59a50) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/VehicleManager.cpp:232)
#7 00407BDA Supervisor::IsMergeInstruction(id_vehicle=1) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/Supervisor.cpp:77)
#8 00408430 CheckingInstructionsThread(arg=0x476100) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/Supervisor.cpp:264)
#9 00413950 _glfwNewThread@4() (??:??)
#10 75A24911 KERNEL32!AcquireSRWLockExclusive() (C:\Windows\system32\kernel32.dll:??)
#11 00476100 std::__ioinit() (??:??)
#12 0406FFD4 ??() (??:??)
#13 76E5E4B6 ntdll!RtlInitializeNtUserPfn() (C:\Windows\system32\ntdll.dll:??)
#14 00476100 std::__ioinit() (??:??)
#15 70266582 ??() (??:??)
#16 00000000 ??() (??:??)
A few more precisions :
更精确一些:
1/ It's a multi-threaded application. 2/ The method : get_vehicles_distances(); returns a map. 3/ It's possible that the map isn't initalised by the time when it's called by IsMergeInstruction();
1 /这是一个多线程应用程序。 2 /方法:get_vehicles_distances();返回一张地图。 3 / IsMergeInstruction()调用时,地图可能不会被初始化;
Edit:
Apparently the line that is causing the segfault is :
显然导致段错误的行是:
vehicles_distances_.erase(vehicles_distances_.begin(), vehicles_distances_.end());
Where vehicles_distances_ is the Map. This line is a part of the method : VehicleManager::MoveAllVehicles();
其中vehicles_distances_是Map。这一行是方法的一部分:VehicleManager :: MoveAllVehicles();
void VehicleManager::MoveAllVehicles() {
vehicles_distances_.erase(vehicles_distances_.begin(), vehicles_distances_.end());
vector<Vehicle>::iterator iter_end = VehicleManager::vehicles_.end();
for(vector<Vehicle>::iterator iter = VehicleManager::vehicles_.begin();
iter != iter_end; ++iter) {
(*iter).MoveVehicle();
vehicles_distances_[(*iter).get_vec_vehicle_position().y] = (*iter).get_id_vehicle();
}
}
What is wrong with that ?
这有什么问题?
Edit:
I tried to use map::clear(); as a replacement to map::erase(); but the same problem occurs!
我试着用map :: clear();作为map :: erase()的替代;但同样的问题发生了!
Edit:
I think i get it... A thread is trying to make a use of vehicles_distances_ while it's cleared.. (?)
我想我明白了...一个线程试图利用vehicles_distances_而它被清除..(?)
Edit:
Problem solved! So it was coming from the map::erase(); as expected. i bypassed the problem by creating another map variable where the pair <key, value>
was inverted so i can update the map. (since the key that i need is the distance, and the distance isn't unique since it changes everytime but the id_vehicle is unique!). At the end i just took that map, inverted the <key, value>
again and transferred it to the original map that can be redeclared in each cycle...
问题解决了!所以它来自map :: erase();正如所料。我通过创建另一个映射变量绕过了问题,其中对
Thanks everyone !
感谢大家 !
13 个解决方案
#1
First, for the love of all that is, well, lovable, don't use Dev-C++. I wish I knew how people keep running into that piece of junk. It hasn't been maintained for years, and even when it was maintained, it was still a buggy piece of junk that lacked very basic functionality. Ditch it, and go for one of the countless better free alternatives.
首先,对于所有可爱的人来说,可爱,不要使用Dev-C ++。我希望我知道人们如何继续遇到那块垃圾。它已经多年没有维护,即使维护它,它仍然是一个缺乏基本功能的垃圾。放弃它,去寻找无数更好的免费替代品之一。
Now, onto your question: Your program segfaults randomly because you've done something illegal earlier. Don't do that. ;)
现在,在您的问题上:您的程序会随机发生段错误,因为您之前已经做过非法的事情。不要那样做。 ;)
if your program writes out of bounds somewhere, anything might happen. It might hit an unallocated page, in which case you get a segfault. Or it might hit unused data on a page that is allocated to your process in which case it won't have any practical effect (unless it is properly initialized afterwards, overwriting your first, illegal, write, and you then try to read from it, expecting the original (invalid) value to still be there. Or it might hit data that's actually in use, in which case you'll get errors later, when the program tries to read that data.
如果你的程序在某个地方写出了界限,那么任何事情都可能发生。它可能会打到一个未分配的页面,在这种情况下,您会遇到段错误。或者它可能会在分配给您的进程的页面上查找未使用的数据,在这种情况下它将没有任何实际效果(除非之后正确初始化,覆盖您的第一次,非法,写入,然后您尝试从中读取期望原始(无效)值仍然存在。或者它可能会触及实际使用的数据,在这种情况下,当程序尝试读取该数据时,您将在以后遇到错误。
Pretty much the same scenarios exist when reading data. You can be lucky and get a segfault immediately, or you can hit unused and uninitialized memory, and read garbage data out (which will most likely cause an error later, when that data is used), or you can read from memory addresses that are already in use (which will also give you garbage out).
阅读数据时几乎存在相同的情况。您可以很幸运并立即获得段错误,或者您可以查看未使用和未初始化的内存,并读取垃圾数据(这很可能会在以后使用该数据时导致错误),或者您可以从内存地址读取已经在使用(这也会给你垃圾)。
So yes, these errors are tricky to find. The best advice I can give is to 1) sprinkle asserts all over your code to ensure basic invariants are maintained, and 2) step through the program, and at every step, verify that you're not reading or writing to addresses that don't belong to you.
所以是的,这些错误很难找到。我可以给出的最好的建议是:1)在代码上撒上断言以确保维护基本不变量,以及2)逐步完成程序,并在每一步中,验证您没有读取或写入地址。属于你。
MSVC has a secure SCL option enabled by default which will perform bounds checking on STL code, which can help spotting errors like this.
MSVC默认启用安全SCL选项,它将对STL代码执行边界检查,这有助于发现这样的错误。
I believe GCC has an option to do something similar (but it's not enabled by default).
我相信GCC可以选择做类似的事情(但默认情况下不启用)。
Segfaults are nasty. Once people have been bitten by an error like this a few times, they tend to become a lot more disciplined with avoiding accessing memory out of bounds. :)
Segfaults很讨厌。一旦人们被这样的错误咬了几次,他们往往会因为避免访问内存而变得更加自律。 :)
#2
You might try Valgrind as a way to help find the problem. Given the line that you've put in the question, I'd have to guess that you've either corrupted the heap, or you have a stack problem.
您可以尝试Valgrind来帮助找到问题。鉴于你在问题中提出的问题,我不得不猜测你已经破坏了堆,或者你有堆栈问题。
#3
The obvious question would be "what is _p". In the debugger you should be able to look at the callstack. Follow _p back to its origin. Confirm its the correct size, that it hasn't been deleted, and that it does in fact exist.
显而易见的问题是“什么是_p”。在调试器中,您应该能够查看callstack。按照_p返回原点。确认其大小正确,尚未删除,并确实存在。
If that's not easy, there's always the brute force methods of commenting out random (suspected) code until it works or going back and diffing against a known, working copy.
如果这并不容易,那么总会有蛮力的方法来评论随机(可疑)代码,直到它工作或返回并与已知的工作副本进行区分。
#4
This is incredibly vague, so it's almost impossible to answer. One obvious suggestion would be to check if you're initializing all your variables. Some compilers will zero out your uninitialized stuff in debug and not do that in release for example, leading to random and unexpected results.
这非常模糊,所以几乎不可能回答。一个明显的建议是检查你是否正在初始化所有变量。有些编译器会在调试中将未初始化的内容清零,而不是在发布中执行此操作,从而导致随机和意外的结果。
#5
You can use _CrtSetDbgFlag()
at the beginning of your program to enable some heap debugging options. See also The CRT Debug Heap. This may help you track down where you're doing bad stuff with memory. It's available in Microsoft's C runtime, which you the MinGW compiler links against by default. If you're instead using GNU's C runtime, then you won't be able to go this route.
您可以在程序开头使用_CrtSetDbgFlag()来启用一些堆调试选项。另请参见CRT调试堆。这可以帮助您追踪您在内存中做坏事的地方。它可以在Microsoft的C运行时中使用,默认情况下MinGW编译器将链接到该运行时。如果您使用的是GNU的C运行时,那么您将无法使用此路由。
#6
The problem is much more likely to be in your code than in stl_construct.h. I'm assuming that file is part of the STL distribution for Dev-C++. The segmentation fault may be happening in code that was instantiated using the templates in stl_construct.h, but the root cause of the problem is going to be elsewhere. I would try to solve this by getting the stack trace at the time of crash. For each function in the stack trace (especially the ones which are newly written), try to examine the code and look for the following types of possible errors:
问题更可能出现在代码中而不是stl_construct.h中。我假设该文件是Dev-C ++的STL发行版的一部分。分段错误可能发生在使用stl_construct.h中的模板实例化的代码中,但问题的根本原因将在其他地方。我会尝试通过在崩溃时获取堆栈跟踪来解决这个问题。对于堆栈跟踪中的每个函数(尤其是新编写的函数),请尝试检查代码并查找以下类型的可能错误:
- Uninitialized variables (especially indices used for array access)
- Memory used after it has been freed or deleted.
- Array access outside the bounds of the array
- Memory allocation that is used without being checked for NULL (not a problem if you use new because that doesn't return NULL, it throws an exception)
未初始化的变量(尤其是用于数组访问的索引)
释放或删除后使用的内存。
阵列边界外的数组访问
在没有检查NULL的情况下使用的内存分配(如果你使用new则没有问题,因为它不返回NULL,它会引发异常)
#7
Your description, and the call stack, suggest that the program is crashing during initialization of static variables. This is a common pitfall of C++ : There is no simple way to control the order of initialization for static variables.
您的描述和调用堆栈表明程序在静态变量初始化期间崩溃。这是C ++的常见缺陷:没有简单的方法来控制静态变量的初始化顺序。
For example, your program may have object foo
that depends on object bar
; but it may be that the program is calling the constructor for foo
before it constructs bar
. That would be bad, and could cause the kind of problem you're describing. (Is CheckingInstructionsThread
a static variable that spawns a thread? That could be the problem right there.)
例如,您的程序可能具有依赖于对象栏的对象foo;但它可能是程序在构造bar之前调用foo的构造函数。那会很糟糕,可能会导致你所描述的那种问题。 (CheckingInstructionsThread是一个产生线程的静态变量吗?那可能是问题所在。)
To fix this, you might need to look through your program's .cpp files for static variables (including class statics and globals), especially those that are of some class type. It may or may not help to modify your constructors to write some traces to stderr; use fprintf
rather than cerr
if you do so.
要解决这个问题,您可能需要查看程序的.cpp文件中的静态变量(包括类静态和全局变量),尤其是某些类类型的变量。修改构造函数可能会或者可能没有帮助将一些跟踪写入stderr;如果你这样做,请使用fprintf而不是cerr。
EDIT: If you're unsure whether it has anything to do with statics, try putting a line like this at the beginning of main()
:
编辑:如果您不确定它是否与静态有关,请尝试在main()的开头添加这样的行:
fprintf(stderr, "main() entered\n");
This wouldn't rule out static initialization as the cause of the problem; even if it doesn't crash before main()
, you could still have data structures being set up incorrectly. But, if you never get to the fprintf, then you know that static initialization is the cause.
这不排除静态初始化是问题的原因;即使它在main()之前没有崩溃,你仍然可能错误地设置了数据结构。但是,如果你从未进入fprintf,那么你知道静态初始化是原因。
#8
what does the stack trace tell you after running the debugger with the core file? run gdb the normal way gdb a.out
在使用核心文件运行调试器后,堆栈跟踪会告诉您什么?以正常方式运行gdb gdb a.out
then examine the core file
然后检查核心文件
core a.out.core
And take a look at the stack
看看堆栈
bt
#9
This is most probably related to invalidated iterator - search for places where you iterate over containers and/or keep iterators into containers and remove/insert elements at the same time.
And as everybody else noted - use a call-stack to find the exact spot.
这很可能与无效迭代器有关 - 搜索迭代容器和/或将迭代器保存到容器中并同时删除/插入元素的位置。正如其他人所指出的那样 - 使用一个调用堆栈来找到确切的位置。
#10
The first thing that you must do when you end up in code that has been tested thoroughly which is not yours is going up the call stack until you end up in your own code, where you will find the information that caused this problem to happen.
当您最终完成已经过彻底测试但不属于您的代码时,您必须做的第一件事就是调试堆栈,直到您最终使用自己的代码,在那里您将找到导致此问题发生的信息。
In the call stack the most important location to look is at your code (the caller) and the parameters you passed to the function you called (the callee).
在调用堆栈中,要查看的最重要的位置是您的代码(调用者)以及传递给您调用的函数(被调用者)的参数。
Without this information, we can't help you more. ;-)
没有这些信息,我们无法帮助您。 ;-)
More on segmentation faults: http://en.wikipedia.org/wiki/Segmentation_fault
(Must-read, also see the links at "See also" and "External links")
有关分段错误的更多信息:http://en.wikipedia.org/wiki/Segmentation_fault(必读,另请参阅“另请参阅”和“外部链接”中的链接)
#11
Maps are not very thread friendly. If you perform map operations in thread code you really need to lock all accesses to that map and realize any iterators you may hold could be invalidated.
地图不是非常友好的。如果在线程代码中执行映射操作,则确实需要锁定对该映射的所有访问,并实现可能无效的任何迭代器。
#12
It looks like a dangerous function :)
它看起来像一个危险的功能:)
One thing striked me though. Where does the allocated memory go? Intuitively I'd like to have a pointer to a pointer as first argument and then dereference it. Like this:
但有一件事打动了我。分配的内存在哪里?直觉上我希望有一个指针指针作为第一个参数,然后取消引用它。像这样:
template<typename _T1, typename _T2>
inline void
_Construct(_T1** __p, const _T2& __value)
{
::new(static_cast<void*>(*__p)) _T1(__value);
}
Alternatively, a reference to a pointer:
或者,对指针的引用:
template<typename _T1, typename _T2>
inline void
_Construct(_T1*& __p, const _T2& __value)
{
::new(static_cast<void*>(__p)) _T1(__value);
}
#13
The debugger should let you go up the call stack. This way you should be able to see the place in your own code which is causing the seg fault.
调试器应该让你上调调用堆栈。通过这种方式,您应该能够在自己的代码中看到导致seg错误的位置。
#1
First, for the love of all that is, well, lovable, don't use Dev-C++. I wish I knew how people keep running into that piece of junk. It hasn't been maintained for years, and even when it was maintained, it was still a buggy piece of junk that lacked very basic functionality. Ditch it, and go for one of the countless better free alternatives.
首先,对于所有可爱的人来说,可爱,不要使用Dev-C ++。我希望我知道人们如何继续遇到那块垃圾。它已经多年没有维护,即使维护它,它仍然是一个缺乏基本功能的垃圾。放弃它,去寻找无数更好的免费替代品之一。
Now, onto your question: Your program segfaults randomly because you've done something illegal earlier. Don't do that. ;)
现在,在您的问题上:您的程序会随机发生段错误,因为您之前已经做过非法的事情。不要那样做。 ;)
if your program writes out of bounds somewhere, anything might happen. It might hit an unallocated page, in which case you get a segfault. Or it might hit unused data on a page that is allocated to your process in which case it won't have any practical effect (unless it is properly initialized afterwards, overwriting your first, illegal, write, and you then try to read from it, expecting the original (invalid) value to still be there. Or it might hit data that's actually in use, in which case you'll get errors later, when the program tries to read that data.
如果你的程序在某个地方写出了界限,那么任何事情都可能发生。它可能会打到一个未分配的页面,在这种情况下,您会遇到段错误。或者它可能会在分配给您的进程的页面上查找未使用的数据,在这种情况下它将没有任何实际效果(除非之后正确初始化,覆盖您的第一次,非法,写入,然后您尝试从中读取期望原始(无效)值仍然存在。或者它可能会触及实际使用的数据,在这种情况下,当程序尝试读取该数据时,您将在以后遇到错误。
Pretty much the same scenarios exist when reading data. You can be lucky and get a segfault immediately, or you can hit unused and uninitialized memory, and read garbage data out (which will most likely cause an error later, when that data is used), or you can read from memory addresses that are already in use (which will also give you garbage out).
阅读数据时几乎存在相同的情况。您可以很幸运并立即获得段错误,或者您可以查看未使用和未初始化的内存,并读取垃圾数据(这很可能会在以后使用该数据时导致错误),或者您可以从内存地址读取已经在使用(这也会给你垃圾)。
So yes, these errors are tricky to find. The best advice I can give is to 1) sprinkle asserts all over your code to ensure basic invariants are maintained, and 2) step through the program, and at every step, verify that you're not reading or writing to addresses that don't belong to you.
所以是的,这些错误很难找到。我可以给出的最好的建议是:1)在代码上撒上断言以确保维护基本不变量,以及2)逐步完成程序,并在每一步中,验证您没有读取或写入地址。属于你。
MSVC has a secure SCL option enabled by default which will perform bounds checking on STL code, which can help spotting errors like this.
MSVC默认启用安全SCL选项,它将对STL代码执行边界检查,这有助于发现这样的错误。
I believe GCC has an option to do something similar (but it's not enabled by default).
我相信GCC可以选择做类似的事情(但默认情况下不启用)。
Segfaults are nasty. Once people have been bitten by an error like this a few times, they tend to become a lot more disciplined with avoiding accessing memory out of bounds. :)
Segfaults很讨厌。一旦人们被这样的错误咬了几次,他们往往会因为避免访问内存而变得更加自律。 :)
#2
You might try Valgrind as a way to help find the problem. Given the line that you've put in the question, I'd have to guess that you've either corrupted the heap, or you have a stack problem.
您可以尝试Valgrind来帮助找到问题。鉴于你在问题中提出的问题,我不得不猜测你已经破坏了堆,或者你有堆栈问题。
#3
The obvious question would be "what is _p". In the debugger you should be able to look at the callstack. Follow _p back to its origin. Confirm its the correct size, that it hasn't been deleted, and that it does in fact exist.
显而易见的问题是“什么是_p”。在调试器中,您应该能够查看callstack。按照_p返回原点。确认其大小正确,尚未删除,并确实存在。
If that's not easy, there's always the brute force methods of commenting out random (suspected) code until it works or going back and diffing against a known, working copy.
如果这并不容易,那么总会有蛮力的方法来评论随机(可疑)代码,直到它工作或返回并与已知的工作副本进行区分。
#4
This is incredibly vague, so it's almost impossible to answer. One obvious suggestion would be to check if you're initializing all your variables. Some compilers will zero out your uninitialized stuff in debug and not do that in release for example, leading to random and unexpected results.
这非常模糊,所以几乎不可能回答。一个明显的建议是检查你是否正在初始化所有变量。有些编译器会在调试中将未初始化的内容清零,而不是在发布中执行此操作,从而导致随机和意外的结果。
#5
You can use _CrtSetDbgFlag()
at the beginning of your program to enable some heap debugging options. See also The CRT Debug Heap. This may help you track down where you're doing bad stuff with memory. It's available in Microsoft's C runtime, which you the MinGW compiler links against by default. If you're instead using GNU's C runtime, then you won't be able to go this route.
您可以在程序开头使用_CrtSetDbgFlag()来启用一些堆调试选项。另请参见CRT调试堆。这可以帮助您追踪您在内存中做坏事的地方。它可以在Microsoft的C运行时中使用,默认情况下MinGW编译器将链接到该运行时。如果您使用的是GNU的C运行时,那么您将无法使用此路由。
#6
The problem is much more likely to be in your code than in stl_construct.h. I'm assuming that file is part of the STL distribution for Dev-C++. The segmentation fault may be happening in code that was instantiated using the templates in stl_construct.h, but the root cause of the problem is going to be elsewhere. I would try to solve this by getting the stack trace at the time of crash. For each function in the stack trace (especially the ones which are newly written), try to examine the code and look for the following types of possible errors:
问题更可能出现在代码中而不是stl_construct.h中。我假设该文件是Dev-C ++的STL发行版的一部分。分段错误可能发生在使用stl_construct.h中的模板实例化的代码中,但问题的根本原因将在其他地方。我会尝试通过在崩溃时获取堆栈跟踪来解决这个问题。对于堆栈跟踪中的每个函数(尤其是新编写的函数),请尝试检查代码并查找以下类型的可能错误:
- Uninitialized variables (especially indices used for array access)
- Memory used after it has been freed or deleted.
- Array access outside the bounds of the array
- Memory allocation that is used without being checked for NULL (not a problem if you use new because that doesn't return NULL, it throws an exception)
未初始化的变量(尤其是用于数组访问的索引)
释放或删除后使用的内存。
阵列边界外的数组访问
在没有检查NULL的情况下使用的内存分配(如果你使用new则没有问题,因为它不返回NULL,它会引发异常)
#7
Your description, and the call stack, suggest that the program is crashing during initialization of static variables. This is a common pitfall of C++ : There is no simple way to control the order of initialization for static variables.
您的描述和调用堆栈表明程序在静态变量初始化期间崩溃。这是C ++的常见缺陷:没有简单的方法来控制静态变量的初始化顺序。
For example, your program may have object foo
that depends on object bar
; but it may be that the program is calling the constructor for foo
before it constructs bar
. That would be bad, and could cause the kind of problem you're describing. (Is CheckingInstructionsThread
a static variable that spawns a thread? That could be the problem right there.)
例如,您的程序可能具有依赖于对象栏的对象foo;但它可能是程序在构造bar之前调用foo的构造函数。那会很糟糕,可能会导致你所描述的那种问题。 (CheckingInstructionsThread是一个产生线程的静态变量吗?那可能是问题所在。)
To fix this, you might need to look through your program's .cpp files for static variables (including class statics and globals), especially those that are of some class type. It may or may not help to modify your constructors to write some traces to stderr; use fprintf
rather than cerr
if you do so.
要解决这个问题,您可能需要查看程序的.cpp文件中的静态变量(包括类静态和全局变量),尤其是某些类类型的变量。修改构造函数可能会或者可能没有帮助将一些跟踪写入stderr;如果你这样做,请使用fprintf而不是cerr。
EDIT: If you're unsure whether it has anything to do with statics, try putting a line like this at the beginning of main()
:
编辑:如果您不确定它是否与静态有关,请尝试在main()的开头添加这样的行:
fprintf(stderr, "main() entered\n");
This wouldn't rule out static initialization as the cause of the problem; even if it doesn't crash before main()
, you could still have data structures being set up incorrectly. But, if you never get to the fprintf, then you know that static initialization is the cause.
这不排除静态初始化是问题的原因;即使它在main()之前没有崩溃,你仍然可能错误地设置了数据结构。但是,如果你从未进入fprintf,那么你知道静态初始化是原因。
#8
what does the stack trace tell you after running the debugger with the core file? run gdb the normal way gdb a.out
在使用核心文件运行调试器后,堆栈跟踪会告诉您什么?以正常方式运行gdb gdb a.out
then examine the core file
然后检查核心文件
core a.out.core
And take a look at the stack
看看堆栈
bt
#9
This is most probably related to invalidated iterator - search for places where you iterate over containers and/or keep iterators into containers and remove/insert elements at the same time.
And as everybody else noted - use a call-stack to find the exact spot.
这很可能与无效迭代器有关 - 搜索迭代容器和/或将迭代器保存到容器中并同时删除/插入元素的位置。正如其他人所指出的那样 - 使用一个调用堆栈来找到确切的位置。
#10
The first thing that you must do when you end up in code that has been tested thoroughly which is not yours is going up the call stack until you end up in your own code, where you will find the information that caused this problem to happen.
当您最终完成已经过彻底测试但不属于您的代码时,您必须做的第一件事就是调试堆栈,直到您最终使用自己的代码,在那里您将找到导致此问题发生的信息。
In the call stack the most important location to look is at your code (the caller) and the parameters you passed to the function you called (the callee).
在调用堆栈中,要查看的最重要的位置是您的代码(调用者)以及传递给您调用的函数(被调用者)的参数。
Without this information, we can't help you more. ;-)
没有这些信息,我们无法帮助您。 ;-)
More on segmentation faults: http://en.wikipedia.org/wiki/Segmentation_fault
(Must-read, also see the links at "See also" and "External links")
有关分段错误的更多信息:http://en.wikipedia.org/wiki/Segmentation_fault(必读,另请参阅“另请参阅”和“外部链接”中的链接)
#11
Maps are not very thread friendly. If you perform map operations in thread code you really need to lock all accesses to that map and realize any iterators you may hold could be invalidated.
地图不是非常友好的。如果在线程代码中执行映射操作,则确实需要锁定对该映射的所有访问,并实现可能无效的任何迭代器。
#12
It looks like a dangerous function :)
它看起来像一个危险的功能:)
One thing striked me though. Where does the allocated memory go? Intuitively I'd like to have a pointer to a pointer as first argument and then dereference it. Like this:
但有一件事打动了我。分配的内存在哪里?直觉上我希望有一个指针指针作为第一个参数,然后取消引用它。像这样:
template<typename _T1, typename _T2>
inline void
_Construct(_T1** __p, const _T2& __value)
{
::new(static_cast<void*>(*__p)) _T1(__value);
}
Alternatively, a reference to a pointer:
或者,对指针的引用:
template<typename _T1, typename _T2>
inline void
_Construct(_T1*& __p, const _T2& __value)
{
::new(static_cast<void*>(__p)) _T1(__value);
}
#13
The debugger should let you go up the call stack. This way you should be able to see the place in your own code which is causing the seg fault.
调试器应该让你上调调用堆栈。通过这种方式,您应该能够在自己的代码中看到导致seg错误的位置。