0

In order to prevent crashes, I always check if a pointer is valid using the Windows API, VirtualQuery; in particular, checking the flag PAGE_NOACCESS to verify that the pointer is not pointing to a bad memory allocation. If the pointer is good, then I proceed to use it.

Could I use Exception Handling to achieve the same result? I would like to read/write using the pointer in a try block and then catch the possible exception to prevent the crash. Would this be a bad practice, or even possible?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
DevilMan
  • 19
  • 2
  • 1
    Try deliberately doing a bad access and see for yourself. What I would expect you to see is that the crash does not generate a C++ exception. –  Nov 01 '21 at 11:24
  • Thanks for your reply dratenik. The software crashes anyhow alongside the handling. I assume that i should continue to use VirtualQuary. Do you think VirtualQuary is an overkill ? – DevilMan Nov 01 '21 at 11:35
  • 1
    The preferable solution is to find whatever bug is generating wrong pointers and fix that. If for some reason you cannot do that (bug cast in stone by using a 3rd party binary you have no power over) only then might VirtualQuery be a good idea. –  Nov 01 '21 at 11:42
  • The argument against using VirtualQuery would be that if you put the checks everywhere, your code would be an unreadable mess. The modern C++ approach instead tends to avoid using pointers where possible and provides tools like address sanitizer to help find errors. –  Nov 01 '21 at 11:48
  • Thanks. I just found a little trick. Instead of VirtualQuery, i could try to check if the pointer is within the memory range used by the program. If the module in which im working on is allocated from 0x0AAA to 0x0FFF, and the pointer is trying to point out of this range, probably it's invalid. – DevilMan Nov 01 '21 at 11:51
  • You should know that a pointer pointing to allocated memory does not necessarily mean that dereferencing it makes your program well-defined. There are many more ways that a program can misbehave than crashing. –  Nov 01 '21 at 13:16
  • *"Could I use Exception Handling to achieve the same result?"* - Yes, of course! That's what [`IsBadReadPtr`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-isbadreadptr) and [`IsBadWritePtr`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-isbadwriteptr) are doing. Though keep in mind, that [IsBadXxxPtr should really be called CrashProgramRandomly](https://devblogs.microsoft.com/oldnewthing/20060927-07/?p=29563). – IInspectable Nov 02 '21 at 06:44

1 Answers1

1

This question (How to catch segmentation fault in Linux?) has a lot of info on doing this, including good wording on some of the problems with it, so read all the answers and comments.

Information gleaned from that post:

  1. Supposedly it is possible with MSVC via __try and __catch
  2. Dereferencing an unmapped pointer ultimately ends with a seg fault signal being sent to the process. You can catch this signal with a custom handler, but it's technically UB to return from it.
  3. Some third-party libraries exist that can convert the signal to an exception on some Linux platforms. (How they do it may be questionable.)
  4. It might not even make sense to try to recover from a seg fault.

Does it make sense to try to catch a bad dereference?

Dereferencing a bad pointer is something that you might not be able to catch by checking the pointer. It might be randomly pointing to valid memory, in which case you'll probably end up with some odd UB.

Modern C++ avoids some of the pointer issues by avoiding owning pointers altogether (using RAII pointers instead). You can still pass the pointer (as a non-owned pointer). A good design with smart pointers makes it easier to manage lifetime issues like dangling references and uninitialized/garbage values. But it won't fix all the possible issues.

It can still be useful to check/sanitize pointers in some cases, such as at API boundaries. e.g. In exposed functions that take pointers as input.

If you're having a lot of trouble with pointers, maybe it's a sign that you need to simplify your design or find a better way to manage pointers?

Humphrey Winnebago
  • 1,512
  • 8
  • 15