C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Standardising 0xdeadbeef for pointers

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Fri, 25 Jul 2025 14:08:02 +0100
On Fri, Jul 25, 2025 at 1:19 PM Frederick Virchanza Gotham wrote:

> struct badptr_t {
> alignas(PAGE_SIZE) inline static char unsigned const
> dummy[PAGE_SIZE] = {};
>
> template<typename T>
> operator T*(void) const
> {
> return static_cast<T*>( const_cast<void*>(
> static_cast<void const*>( dummy + PAGE_SIZE / 2u ) ) );
> }
> };


We can get it to segfault upon reading by setting the page permission to "none".

Check out the following GodBolt, and then try comment out Line #12
where it says "mprotect".

    https://godbolt.org/z/9MGas1xPe

And here it is copy-pasted:

    #include <cstdlib> // abort, aligned_alloc
    #include <sys/mman.h> // mprotect
    #include <unistd.h> // getpagesize

    struct badptr_t {
        inline static int page_size = 0;
        static char *Init(void) noexcept
        {
            page_size = ::getpagesize();
            char *p = (char*)std::aligned_alloc(page_size,page_size);
            if ( nullptr == p ) std::abort();
            ::mprotect(p,page_size,PROT_NONE);
            return p;
        }
        inline static char *const p_bad_page = Init();
        template<typename T>
        operator T*(void) const
        {
            return static_cast<T*>( static_cast<void*>( p_bad_page +
page_size / 2 ) );
        }
    };

    constexpr badptr_t badptr{};

    #include <iostream>

    int main(void)
    {
        std::cout << "First line in main\n";
        char *p = badptr;
        std::cout << p << std::endl;
        std::cout << "Last line in main\n";
    }

Even though this works . . . i.e. we get a segfault . . . it would be
nicer to have the compiler's cooperation so that when NDEBUG is
undefined, it gives a good explanatory message saying that 'badptr'
was dereferenced.

Received on 2025-07-25 13:08:19