Steen Suder wrote:
>
> Nu dukkede der så nedenstående kernel oops op på en af mine bokse (Linux
> 2.6.10 med nogle netværks relaterede patches)
Kan du reproducere fejlen? Det er nemmere at rette en
fejl, hvis man er i stand til at reproducere den.
>
> Af mere generel interesse: hvordan pokker afkoder jeg sådan et?
Den har sådanset allerede lavet en pæn del af afkodningen
for dig. Med andre ord din Oops er i en form som en kerne
hacker kan bruge til noget.
> Som jeg læser det, er det rateups (en del af MRTG-pakken) aktivitet, der
> fremkalder oopset, på et tidspunkt hvor det er i færd med at slette noget
> på disken.
Tja, den er nok implicit ved at slette noget. Ifølge den
afkodning der er foretaget af stakken har programmet kaldt
munmap systemkaldet som så har kaldet unlink systemkaldet
for at slette noget. Som så til sidst kalder iput til at
gøre det beskidte arbejde.
Der er bare lige den hage ved det, at så vidt jeg kan se
kan denne kald sekvens ikke lade sig gøre. Jeg formoder,
compileren har lavet nogle optimeringer, som forvirrer
stak afkodningen.
Det skal vi nu ikke bekymre os så meget om. En unmappning
vil under ganske normale omstændigheder kunne føre til at
en fil slettes. Det sker hvis den allerede er unlinket og
processen som unmapper filen er den sidste bruger. (Og
selv normale hukommelsesallokeringer implementeres nogle
steder i kernen som filer på et usynligt RAM filsystem.)
Jeg tror faktisk ikke fejlen har noget at gøre med
sletningen. Mit umiddelbare gæt er memory corruption,
fordi der et eller andet sted skrives ud over slutningen
af en allokering.
> Systemet har et load på 0% på pågældende tidspunkt og har vitterligt
> ingenting at lave andet end at serve en webside til en browser, der
> refresher hvert 5. minut.
> Hvordan afkoder jeg det så meget at jeg kan rette problemet eller lave et
> workaround?
>
> **************
> Unable to handle kernel paging request at virtual address 00400004
Her ser vi, at der bruges en ugyldig pointer. Denne
adresse ligger ikke i kernel space, så pointeren er
åbenlyst ugyldig. Enten er den ikke initialiseret,
eller også er den blevet overskrevet. Det ville have
været rare med en NULL pointer, de er lidt nemmere at
identificere end en tilfældig forkert pointer.
> printing eip:
> c012edb3
> *pde = 00000000
> Oops: 0002 [#1]
> Modules linked in: cls_u32 cls_fw sch_sfq ipt_MARK ipt_state iptable_mangle
> iptable_filter af_packet ip_nat_ftp iptable_nat ip_tables ip_conntrack_ftp
> ip_conntrack e100 mii crc32 unix
> CPU: 0
> EIP: 0060:[<c012edb3>] Not tainted VLI
> EFLAGS: 00010097 (2.6.10)
> EIP is at find_get_pages+0x43/0x60
Og her ser vi hvor fejl forekommer. Det sker i
funktionen find_get_pages som jeg har fundet i filen
mm/filemap.c. Den kaldes udelukkende fra mm/swap.c.
Og 0x43/0x60 angiver offset i funktionen og dens
længde i hexadecimal. Funktionen er altså 96 bytes
lang, og fejlen opstår 67 bytes inde. Så mit første
gæt er, at det nok er pages pointeren der er gal, og
derfor går det galt i page_cache_get kaldet i den
sidste del af funktionen.
Hvis du selv vil i gang med at debugge, så kan du
prøve at indsætte
printk(KERN_DEBUG "find_get_pages: %d %08x\n",ret,pages);
lige før for løkken. Det hjælper naturligvis kun hvis
du kan fremprovokere fejlen igen.
--
Kasper Dupont