Aktualizacja
Znalazłem wiersz w debug.c wspomniany w OP i widzimy z dwóch wierszy powyżej tego kodu:
redisLog(REDIS_WARNING,"(forcing SIGSEGV to print the bug report.)");
a ten sam kod można znaleźć w _redisPanic
również, więc wygląda na to, że ich sposób na wymuszenie SIGSEGV
gdy asercja nie powiedzie się lub pojawi się panika.
Oryginał
Wygląda to na narzędzie do debugowania, które możemy zobaczyć w tym dokumencie Przewodnik debugowania Redis i odpowiednia sekcja mówi:
Redis ma polecenie symulujące błąd segmentacji (innymi słowy złą awarię) za pomocą polecenia DEBUG SEGFAULT (oczywiście nie używaj go przeciwko rzeczywistej instancji produkcyjnej;). Więc użyję tego polecenia, aby zawiesić moją instancję, aby pokazać, co dzieje się po stronie GDB:
i pokazuje to wyjście gdb:
(gdb) continue
Continuing.
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xffffffffffffffff
debugCommand (c=0x7ffc32005000) at debug.c:220
220 *((char*)-1) = 'x';
^^^^^^^^^^^^^^^^^^^
To, co robi, to rzutowanie -1
do *znaku **, a następnie wykonując na nim pośredni i przypisując 'x'
do tej lokalizacji w pamięci. Jako wątek, który łączy alk Czy ((nieważne *) -1) jest prawidłowym adresem? mówi w większości systemów, że dostęp do niego nie będzie prawidłowy, nie mówiąc już o przypisaniu wartości. Spowoduje to błąd segmentacji w większości nowoczesnych systemów operacyjnych.
Jest to zachowanie niezdefiniowane i jak zostało to omówione w wątku Jaki jest najprostszy zgodny ze standardami sposób tworzenia Segfault w C? nie można na nim polegać. Kompilatory stają się coraz mądrzejsze i jest kilka znanych przykładów, w których kompilator jest sprytny w wykorzystywaniu niezdefiniowanych zachowań w nieoczekiwany i zły sposób.