Sprawdzanie wskaznikow

0

Witam!
Czy jest możliwość sprawdzenia wskaźnika czy nie wykracza on poza zakres pamięci procesu?

0

moze coś z tego ci pomoże:
http://4programmers.net/Forum/538578#538578

0

W Linuksie jest ciekawy sposób na zrobienie tego. Można zarejestrowac signal handler na sygnal SIGSEGV lub SIGBUS i spróbować odwołać się do badanej pamięci. Jeżeli pamięć nie należy do procesu do zostanie uruchomiony signal handler, z którego można zrobić długi skok do miejsca przed odwołaniem. Kawałek kodu z mojego Garbage Collectora, który sprawdza pod jakim adresem zaczyna się stos:

void Utils::FaultSignalHandler(int) {
    siglongjmp(_environment, 128);
}

TPtr Utils::readSpUnsafe() {
    GC_TRACE_ENTER;
    //TODO - iter have to be volatile
    TPtr* iter = reinterpret_cast<TPtr*>(approxCurrentSp());

    struct sigaction sa;
    struct sigaction oldSigSegv;
    struct sigaction oldSigBus;

    sa.sa_handler = Utils::FaultSignalHandler;
    sa.sa_flags = 0;
    if(sigfillset(&sa.sa_mask) != 0) {
        throw SignalHandlerException(strerror(errno), errno);
    }

    if(sigaction(SIGSEGV, &sa, &oldSigSegv) != 0) {
        throw SignalHandlerException(strerror(errno), errno);
    }

    if(sigaction(SIGBUS, &sa, &oldSigBus) != 0) {
        GC_TRACE_ERROR("Cannot register handler for SIGBUS");
    }

    if(sigsetjmp(_environment, 1) == 0) {
        volatile TPtr tmp;
        while(true) {
            tmp = *iter;
            GC_TRACE_DEBUG("Scanned address [", iter, "]");
            GC_PREV_ITER(iter);
        }
    }
    GC_NEXT_ITER(iter);
    GC_TRACE_DEBUG("Stack bottom address of main thread [", iter, "]");

    if(sigaction(SIGSEGV, &oldSigSegv, 0) != 0) {
        GC_TRACE_ERROR("Cannot restore old signal handler for SIGSEGV");
    }

    if(sigaction(SIGBUS, &oldSigBus, 0) != 0) {
        GC_TRACE_ERROR("Cannot restore old signal handler for SIGSEGBUS");
    }

    GC_TRACE_LEAVE;
    return reinterpret_cast<TPtr>(iter);
}

Nawiasem mówiąc w taki sposób VM Javy "sprawdza" czy nie odwołujemy się do nullowej referencji.
Jeżeli chcesz sprawdzić czy adres należy do sterty procesu to możesz śledzić rezerwowane obszary przez aplikacje. Np. można podmienić funkcję malloc (opcją linkera -Wl,--wrap).
Obszary stosu głównego wątku można też zczytać z pliku /proc/self/stat ale nie ma gwarancji, że ten plik zawsze istnieje.

0

No to znowu Windows lepszy - wystarczy skorzystać z SEH - AV to wyjątek jak każdy inny, można go sobie złapać (kompilator MS ma do tego __try .. __except, nie wiem jak pod innymi).
@down: No widzisz, nie wiedziałem, że IsBadReadPtr istnieje. Zawsze się czegoś można dowiedzieć, dzięki!

0

Tylko po co na Windows używać wyjątków? Wyjątki są tak cholernie wolne, że naprawdę korzystać z nich się nie powinno poza łapaniem faktycznie występująch błędów. IsBadReadPtr - standardowa funkcja WINAPI sprawdzająca czy dany fragment przestrzeni adresowej jest dotępny, poza tym jest chociażby VirtualQuery, które do tego samego celu użyć można (co w praktyce jest najlepszym wyjściem).

0

dzieki ... za odpowiedz!

1 użytkowników online, w tym zalogowanych: 0, gości: 1