尝试/捕获Linux上的分割错误

时间:2021-02-27 08:52:59

I have a Linux C++ application and I'd like to test an object pointer for validity before dereferencing it. However try/catch doesn't work for this on Linux because of the segmentation fault. How can this be done?

我有一个Linux c++应用程序,我想在取消引用之前测试一个对象指针的有效性。然而,由于分割错误,try/catch在Linux上不适用。怎么做呢?

9 个解决方案

#1


8  

If you have a scenario where many pointers across your app reference the same limited-lifetime objects, a popular solution is to use boost smart pointers. Edit: in C++11, both of these types are available in the standard library

如果您的应用程序中有多个指针引用相同的限定生存期对象,那么一个流行的解决方案是使用boost智能指针。编辑:在c++ 11中,这两种类型都可以在标准库中找到

You would want to use shared_ptr for pointer(s) that are responsible for the lifetime of your object and weak_ptr for the other pointers, which may become invalid. You'll see that weak_ptr has the validity check you're asking for built in.

您将希望使用shared_ptr作为指针(s),它负责对象的生存期和其他指针的weak_ptr,这些指针可能会变得无效。您将看到weak_ptr具有您所要求的内置有效性检查。

#2


8  

A segmentation fault is not an Exception (like Java's NullPointerException); it is a signal sent from the OS to the process. Have a look at the manpage for sigaction for pointers on how to install a handler for the segmentation fault (SIGSEGV).

分割错误不是异常(如Java的NullPointerException);它是一个从操作系统发送到进程的信号。查看关于如何安装分割错误处理程序(SIGSEGV)的指针的sigaction手册。

#3


4  

Initialize your pointer to NULL. If after some processing it is still NULL it’s invalid, otherwise it’s valid.

将指针初始化为空。如果经过一些处理,它仍然为空,那么它是无效的,否则它是有效的。

#4


4  

You could enable a signal handler for SIGSEGV for this one occurrence. See the man page "signal" for details. The other alternative is to use references which are guaranteed to be valid. It depends on your application of course.

您可以为这个事件启用SIGSEGV的信号处理程序。详情请参阅手册页“信号”。另一种选择是使用保证有效的引用。这当然取决于你的应用。

#5


2  

There is no natural, universal way with raw C++ pointers. C++ assumes that you will track that information.

对于原始的c++指针,没有一种自然的、通用的方法。c++假定您将跟踪该信息。

In most situations, you can handle this by remembering to set pointers to NULL when they are invalid. New pointers that initially don't point should be set to NULL and newly deleted objects should have their pointers set to NULL.

在大多数情况下,您可以通过记住在无效时将指针设置为NULL来处理。最初不指向的新指针应该设置为NULL,新删除的对象的指针应该设置为NULL。

#6


1  

How do you test the pointer for validity? Compare to NULL?

如何测试指针的有效性?比较空?

The best thing you do is to run your program under Valgrind. A bug might be in a quite different place.

最好的办法就是在Valgrind中运行程序。一个bug可能在一个完全不同的地方。

Update: On Win32 platform there is something like __try __except which allows to catch some exceptions. As far I know there is no Linux equivalent for that Win32 feature.

更新:在Win32平台上有类似于__try的东西,除了它允许捕获一些异常。据我所知,Win32特性没有Linux对应的功能。

#7


0  

If you attach a handler to the SIGSEGV there isn't much you can do besides log the fact that the error occurred and fail gracefully. Your program is in an undefined state when this violation occurs and it therefore may not be safe to continue normal operation.

如果您将一个处理程序附加到SIGSEGV,那么除了记录错误发生并优雅地失败这一事实之外,您没有什么可以做的。当发生这种违反时,您的程序处于未定义的状态,因此继续正常操作可能不安全。

Beyond checking for NULL I don't believe there is a way to check if a pointer is 'valid' in the sense you are describing. During normal operation errors like this shouldn't happen as they represent a bug, so you should want your program to fail, albeit gracefully.

除了检查NULL之外,我不相信有一种方法可以检查指针在您所描述的意义上是否“有效”。在正常的操作过程中,像这样的错误不应该发生,因为它们代表一个bug,所以您应该希望您的程序失败,尽管应该很优雅地失败。

#8


0  

Pointers are stored in objects. They are initialized in the constructor, potentially to 0 (NULL). They're deleted in the destructor, possibly in assignment and rarely in other functions. When deleted in members other than the destructor, they're immediately assigned a new value or 0.

指针存储在对象中。它们在构造函数中初始化,可能为0 (NULL)。它们在析构函数中被删除,可能在赋值中被删除,很少在其他函数中被删除。当在除析构函数之外的成员中删除时,它们立即被分配一个新值或0。

#9


0  

Generally, regarding the pretty weird idea of "checking a non-NULL pointer for validity", have a look at this article: http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx ("IsBadXxxPtr should really be called CrashProgramRandomly")

一般来说,关于“检查非空指针是否有效”这一相当奇怪的想法,请参阅本文:http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx(“IsBadXxxPtr应该真正被称为crashprogramrandom”)

#1


8  

If you have a scenario where many pointers across your app reference the same limited-lifetime objects, a popular solution is to use boost smart pointers. Edit: in C++11, both of these types are available in the standard library

如果您的应用程序中有多个指针引用相同的限定生存期对象,那么一个流行的解决方案是使用boost智能指针。编辑:在c++ 11中,这两种类型都可以在标准库中找到

You would want to use shared_ptr for pointer(s) that are responsible for the lifetime of your object and weak_ptr for the other pointers, which may become invalid. You'll see that weak_ptr has the validity check you're asking for built in.

您将希望使用shared_ptr作为指针(s),它负责对象的生存期和其他指针的weak_ptr,这些指针可能会变得无效。您将看到weak_ptr具有您所要求的内置有效性检查。

#2


8  

A segmentation fault is not an Exception (like Java's NullPointerException); it is a signal sent from the OS to the process. Have a look at the manpage for sigaction for pointers on how to install a handler for the segmentation fault (SIGSEGV).

分割错误不是异常(如Java的NullPointerException);它是一个从操作系统发送到进程的信号。查看关于如何安装分割错误处理程序(SIGSEGV)的指针的sigaction手册。

#3


4  

Initialize your pointer to NULL. If after some processing it is still NULL it’s invalid, otherwise it’s valid.

将指针初始化为空。如果经过一些处理,它仍然为空,那么它是无效的,否则它是有效的。

#4


4  

You could enable a signal handler for SIGSEGV for this one occurrence. See the man page "signal" for details. The other alternative is to use references which are guaranteed to be valid. It depends on your application of course.

您可以为这个事件启用SIGSEGV的信号处理程序。详情请参阅手册页“信号”。另一种选择是使用保证有效的引用。这当然取决于你的应用。

#5


2  

There is no natural, universal way with raw C++ pointers. C++ assumes that you will track that information.

对于原始的c++指针,没有一种自然的、通用的方法。c++假定您将跟踪该信息。

In most situations, you can handle this by remembering to set pointers to NULL when they are invalid. New pointers that initially don't point should be set to NULL and newly deleted objects should have their pointers set to NULL.

在大多数情况下,您可以通过记住在无效时将指针设置为NULL来处理。最初不指向的新指针应该设置为NULL,新删除的对象的指针应该设置为NULL。

#6


1  

How do you test the pointer for validity? Compare to NULL?

如何测试指针的有效性?比较空?

The best thing you do is to run your program under Valgrind. A bug might be in a quite different place.

最好的办法就是在Valgrind中运行程序。一个bug可能在一个完全不同的地方。

Update: On Win32 platform there is something like __try __except which allows to catch some exceptions. As far I know there is no Linux equivalent for that Win32 feature.

更新:在Win32平台上有类似于__try的东西,除了它允许捕获一些异常。据我所知,Win32特性没有Linux对应的功能。

#7


0  

If you attach a handler to the SIGSEGV there isn't much you can do besides log the fact that the error occurred and fail gracefully. Your program is in an undefined state when this violation occurs and it therefore may not be safe to continue normal operation.

如果您将一个处理程序附加到SIGSEGV,那么除了记录错误发生并优雅地失败这一事实之外,您没有什么可以做的。当发生这种违反时,您的程序处于未定义的状态,因此继续正常操作可能不安全。

Beyond checking for NULL I don't believe there is a way to check if a pointer is 'valid' in the sense you are describing. During normal operation errors like this shouldn't happen as they represent a bug, so you should want your program to fail, albeit gracefully.

除了检查NULL之外,我不相信有一种方法可以检查指针在您所描述的意义上是否“有效”。在正常的操作过程中,像这样的错误不应该发生,因为它们代表一个bug,所以您应该希望您的程序失败,尽管应该很优雅地失败。

#8


0  

Pointers are stored in objects. They are initialized in the constructor, potentially to 0 (NULL). They're deleted in the destructor, possibly in assignment and rarely in other functions. When deleted in members other than the destructor, they're immediately assigned a new value or 0.

指针存储在对象中。它们在构造函数中初始化,可能为0 (NULL)。它们在析构函数中被删除,可能在赋值中被删除,很少在其他函数中被删除。当在除析构函数之外的成员中删除时,它们立即被分配一个新值或0。

#9


0  

Generally, regarding the pretty weird idea of "checking a non-NULL pointer for validity", have a look at this article: http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx ("IsBadXxxPtr should really be called CrashProgramRandomly")

一般来说,关于“检查非空指针是否有效”这一相当奇怪的想法,请参阅本文:http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx(“IsBadXxxPtr应该真正被称为crashprogramrandom”)