Nasz jest wbudowanym systemem opartym na PowerPC z systemem Linux. Zdarza się losowa awaria SIGILL, która jest widoczna dla szerokiej gamy aplikacji. Podstawową przyczyną awarii jest wyzerowanie instrukcji do wykonania. Wskazuje to na uszkodzenie fragmentu tekstu znajdującego się w pamięci. Ponieważ segment tekstowy jest ładowany tylko do odczytu, aplikacja nie może go uszkodzić. Podejrzewam więc, że jakiś wspólny podsystem (DMA?) Powoduje to zepsucie. Ponieważ odtworzenie problemu zajmuje kilka dni (awarie spowodowane SIGILL), trudno jest je zbadać. Na początek chcę wiedzieć, czy i kiedy segment tekstowy każdej aplikacji został uszkodzony. Spojrzałem na ślad stosu i wszystkie wskaźniki, rejestry są prawidłowe.
Czy macie jakieś sugestie, jak mogę to zrobić?Debugowanie nieprzyjemnej awarii SIGILL: korupcja w segmencie tekstowym
Niektóre Info:
Linux 3.12.19-RT30 # 1 SMP Pią 11 marca 01:31:24 IST 2016 ppc64 GNU/Linux
(gdb) bt
0 0x10457dc0 w xxx
wyjście Demontaż:
=> 0x10457dc0 < +80> mr r1 r11
0x10457dc4 < +84>: BLR
Instruction spodziewać pod adresem 0x10457dc0: 0x7d615b78
Instruction znaleźć po łapania SIGILL 0x10457dc0: 0x00000000
(gdb) konserwacji sekcje informacji
0x10006c60-> 0x106cecac na 0x00006c60: .text ALLOC LOAD READONLY KOD HAS_CONTENTS
Oczekiwany (od binarnego aplikacji):
(gdb) x/32 0x10457da0
0x10457da0: 0x913e0000 0x4bff4f5d 0x397f0020 0x800b0004
0x10457db0: 0x83abfff4 0x83cbfff8 0x7c0803a6 0x83ebfffc
0x10457dc0: 0x7d615b78 0x4e800020 0x7c7d1b78 0x7fc3f378
0x10457dd0: 0x4bcd8be5 0x7fa3eb78 0x4857e109 0x9421fff0
Actual (po manipulowaniu SIGILL i dumping pobliskie lokalizacje pamięci):
Błąd adres instrukcji: 0x10457dc0
0x10457da0: 0x913E0000
0x10457db0: 0x83ABFFF4
=> 0x10457dc0: 0x00000000
0x10457dd0: 0x4BCD8BE5
0x10457de0: 0x93E1000C
Edit:
jeden przewód, który mamy jest to, że korupcja jest zawsze występujące w offsetem kończy 0xdc0.
Dla np.
Błąd adres instrukcji: 0x10653dc0 < < drukowane w naszym zgłoszeniu po uchwyt SIGILL
Błąd adres instrukcji: 0x1000ddc0 < < drukowane w naszym zgłoszeniu po uchwyt SIGILL
flash_erase [8557] Sygnał nieobsłużonego 4 w 0fed6dc0 nip 0fed6dc0 LR kod 0fed6dac 30001
nandwrite [8561] sygnał nieobsłużonego 4 w 0fed6dc0 zacisku 0fed6dc0 LR 0fed6dac kod 30001
WK [4448] Sygnał nieobsłużonego 4 w 0fe09dc0 zacisku 0fe09dc0 LR 0fe09dbc kod 30001
awk [16002] nieobsłużonego sygnał 4 na 0fe09dc0 zacisku 0fe09dc0 LR 0fe09dbc kodu 30001
getStats [20670] Signal nieobsłużonego 4 w 0fecfdc0 nip 0fecfdc0 LR 0fecfdbc kod 30001
wyrażenie [27923] signal nieobsłużonego 4 w 0fe74dc0 zacisku 0fe74dc0 LR 0fe74dc0 kodzie 30001
Edycja 2: Kolejny przewód jest, że uszkodzenie jest zawsze występujące w fizycznej numer ramki 0x00a4d. Przypuszczam, że z PAGE_SIZE z 4096 przekłada się to na adres fizyczny 0x00A4DDC0. Podejrzewamy parę sterowników jądra i sprawdzamy dalej. Czy jest jakiś lepszy pomysł (np. Umieszczanie punktu obserwacji sprzętu), który mógłby być bardziej wydajny? Co powiesz na KASAN, jak zasugerowano poniżej?
Każda pomoc jest doceniana. Dzięki.
Ile serwery są uruchomione? Czy błąd SIGILL występuje na jednym serwerze lub wielu serwerach? Czy można uzyskać * fizyczny * adres uszkodzonej pamięci? Jak blisko granicy strony znajdują się adresy, które widzisz? –
Jest widoczny na wielu serwerach. Sprawdzę, jak uzyskać te informacje. Będzie musiał spróbować odtworzyć problem. Czy możesz dać mi znać, co dokładnie sprawdzimy z wyrównaniem do granicy strony? –
Oczekiwany zrzut heksadecymalny pokazuje 16 bajtów między 0x10457b0 i 0x10457dc0. Rzeczywisty pokazuje tylko 4 bajty. Co znajduje się w pozostałych 12 bajtach? Także między c0 a d0. Może nadpisywanie jest czymś więcej niż show.Czasami wartość nadpisywania może dać wskazówkę np. ciąg znaków ASCII. Czy istnieje niezawodny sposób na odtworzenie problemu pod tym samym adresem? Jeśli tak, możesz umieścić punkt kontrolny w debugerze i pozwolić mu się ostrzyć. –