Sunday, 24 December 2017

Moving genomsnittet kernel


MOVING FORTH Del 1: Designbeslut i den främre kärnan av Brad Rodriguez Denna artikel uppträdde först i The Computer Journal 59 (januari februari 1993). INLEDNING Alla i Forth community talar om hur lätt det är att porta fram till en ny CPU. Men som många quoteasyquot - och quotobviousquot-uppgifter, skrivs inte mycket om hur man gör det. Så när Bill Kibler föreslog det här ämnet för en artikel bestämde jag mig för att bryta med den stora muntliga traditionen av författare och dokumentera processen i svartvitt. Under dessa artiklar kommer jag att utveckla Forths för 6809, 8051 och Z80. Jag gör 6809 för att illustrera en enkel och konventionell Forth-modell plus, Ive publicerade redan en 6809 assembler ROD91, ROD92 och Ill behöver en 6809 Forth för framtida TCJ-projekt. Jag gör 8051 Forth för ett universitetsprojekt, men det illustrerar också några ganska olika designbeslut. Z80 Forth är för alla CPM-läsare av TCJ, och för några vänner med TRS-80s som samlar damm. ESSENTIAL HARDWARE Du måste välja en CPU. Jag kommer inte att dyka in i fördelarna med en CPU över en annan för Forth, eftersom en CPU-val vanligtvis är tvungen på dig av andra överväganden. Dessutom är syftet med den här artikeln att visa hur man flyttar fram till en CPU. Du kan förvänta dig den vanliga 16-bitars framåtkärnan (se nedan) för att uppta cirka 8K byte av programutrymme. För en fullständig kärna som kan kompilera Forth-definitioner, bör du tillåta minst 1 K byte RAM. För att använda Forths block management system för disklagring, bör du lägga till 3 Kbytes eller mer för buffertar. För en 32-bitars Forth-modell, dubbelklara dessa siffror. Det här är minsta möjliga för att få en fortsatt kärnkörning. För att köra en applikation på hårdvaran bör du öka PROM och RAM-storlekarna för att passa. 16 ELLER 32 BIT Ordstorleken som används av Forth är inte nödvändigtvis densamma som för CPU. Den minsta praktiska Forth är en 16-bitars modell, dvs en som använder 16-bitars heltal och 16-bitars adresser. Forth community kallar detta kvotcellquotstorleken, eftersom quotwordquot refererar till en vidare definition. 8-bitars processorer stöder nästan alltid 16-bitars framåt. Detta kräver vanligtvis explicit kodning av dubbelbyte-aritmetik, även om vissa 8-bitars CPU-enheter har några 16-bitarsoperationer. 16-bitars CPU körs vanligtvis 16 bitars framåt, även om samma dubbla precisionstekniker kan användas för att skriva en 32-bitars framåt på en 16-bitars CPU. Minst en 32-bitars Forth har skrivits för 80868088. 32-bitars CPU kör normalt 32-bitars Forths. En mindre Forth-modell sällan sparar kodlängd eller processortid. Jag vet emellertid om minst en 16-bitars Forth-skrivning för 68000. Det minskar programkodstorleken med en faktor på två, eftersom avancerade Forth-definitioner blir en sträng med 16-bitars adresser snarare än en sträng av 32- bitadresser. (Detta kommer att bli uppenbart inom kort.) De flesta 68000-tal har dock gott om RAM. Alla exemplen som beskrivs i den här artikeln är 16 bitars framåt som körs på 8-bitars CPU: er. TRÄDNINGSTEKNIKEN citerad kodquot är kännetecknet för Forth. En vidare quotthreadquot är bara en lista över adresser till rutiner som ska utföras. Du kan tänka på detta som en lista över subrutin samtal, med CALL instruktioner borttagen. Under åren har många dragvariationer utformats, och vilken som är bäst beror på processorn och applikationen. För att fatta beslut måste du förstå hur de fungerar, och deras kompromisser. Indirekt trådad kod (ITC) Detta är den klassiska Forth-trådertekniken, som används i figurerna Forth och F83, och beskrivs i de flesta böcker på Forth. Alla andra trådlösa system är quotimprovementsquot på detta, så du behöver förstå ITC för att uppskatta de andra. Låt oss se på definitionen av ett framåtgående ord SQUARE: I en typisk ITC Forth visas detta i minnet som visas i Figur 1. (Rubriken kommer att diskuteras i en framtida artikel, den innehåller hushållsinformation som används för sammanställning och är inte inblandad i gängning .) Antag att SQUARE stöter på att exekvera något annat Forth ord. Future Interpreter Pointer (IP) kommer att peka på en cell i minnet - som ingår i det kvoterotet - som innehåller adressen till ordet SQUARE. (För att vara exakt, innehåller den cellen adressen till SQUAREs Code Field.) Tolken hämtar den adressen och använder den för att hämta innehållet i SQUAREs Code Field. Dessa innehåll är ännu en adress - adressen till en maskinspråkunderrutin som utför ordet SQUARE. I pseudokod är detta: Detta illustrerar en viktig men sällan upplyst princip: Adressen till det fortsatta ordet som just angetts sparas i W. CODE-ord behöver inte denna information, men alla andra typer av Forth ord gör. Om SQUARE skrevs i maskinkod skulle detta vara slutet på berättelsen: den här maskinkoden skulle exekveras och sedan hoppa tillbaka till Forth interpreter - som, sedan IP inkrementer, pekar på nästa ord till exekveras. Därför kallas den främre tolken vanligtvis NEXT. Men, SQUARE är en högkvalitativ quotcolonquot-definition - den innehåller en quotthreadquot, en lista över adresser. För att kunna utföra denna definition måste den fortsatta tolken startas på nytt på en ny plats: Parameterfältet för SQUARE. Naturligtvis måste tolkarnas gamla plats sparas, för att återuppta kvotkontraktet Framåt ord när SQUARE är färdig. Det här är precis som ett subrutin-samtal SQUARE-maskinens språkåtgärd är helt enkelt att trycka på den gamla IP, ställa in IP till en ny plats, springa tolken, och när SQUARE är klar, pop IP-adressen. (Som du kan se är IP-kvoten mot kvoten på högnivå Forth.) Detta kallas DOCOLON eller ENTER i olika Forths: Detta identiska kodfragment används av alla högnivåer (dvs. gängade) Forth definitions Thats varför en pekare till detta kodfragment, inte fragmentet i sig, ingår i förkortningsdefinitionen. Över hundratals definitioner lägger besparingarna upp och det är därför det heter Indirect threading. Kvoten från subrutinquot är ordet EXIT, som sammanställs när Forth ser. (I vissa fall kallas det S istället för EXIT.) EXIT exekverar bara en maskinspråkrutin som gör följande: Gå igenom ett par nestade Forth definitioner, för att försäkra dig om att detta fungerar. Notera egenskaperna hos ITC: varje föregående ord har ett encells kodfält. Kolondefinitioner kompilera en cell för varje ord som används i definitionen. Och den framåtriktade tolken måste faktiskt utföra en dubbel indirektion för att få adressen till nästa maskinkod att köra (först genom IP, sedan genom W). ITC är varken den minsta eller den snabbaste gängningstekniken. Det kan vara det enklaste även om DTC (beskrivet nästa) verkligen inte är mer komplex. Så varför är så många Forths indirekt-threaded För det första eftersom tidigare Forths, som används som modeller, var indirektgängade. Dessa dagar blir DTC mer populär. Så när ska ITC användas Av de olika teknikerna producerar ITC de renaste och mest eleganta definitionerna - inget annat än adresser. Om du är anpassad till sådana överväganden, kan ITC vädja till dig. Om din kod snubblar runt med insider av definitioner, kan ITC-representationens enkelhet och enhetlighet öka bärbarheten. ITC är den klassiska Forth-modellen, så det kan vara att föredra för utbildning. Slutligen, på processorer som saknar en subrutinanvisningsinstruktion - som 1802 - ITC är ofta effektivare än DTC. Direktgängad kod (DTC) Direkt trådad kod skiljer sig från ITC i endast en respekt: ​​i stället för kodfältet som innehåller adressen till någon maskinkod innehåller kodfältet själva maskinkoden själv. Jag säger inte att den fullständiga koden för ENTER finns i varje kolondefinition I quothigh-levelquot Forth ord, innehåller kodfältet ett subrutin samtal. som visas i figur 2. Kolondefinitioner, till exempel, kommer att innehålla ett samtal till ENTER-rutinen. NÄSTA pseudokoden för direktrådning är helt enkelt: Detta ökar hastigheten: tolken utför nu bara en enda indirektion. På Z80 minskar detta NEXT-rutin - det mest använda kodfragmentet i kärnan - från elva instruktioner till sju. Det kostar utrymme: varje högnivådefinition i en Z80 Forth (till exempel) är nu en byte längre, eftersom en 2-byte-adress har ersatts av ett 3-byte-samtal. Men det här är inte helt sant. En 32-bitars 68000 Forth kan ersätta en 4-byte-adress med en 4-byte BSR-instruktion, utan förluster. Och på Zilog Super8, som har maskininstruktioner för DTC Forth, ersätts 2-byte-adressen med en 1-byte ENTER-instruktion, vilket gör en DTC Forth mindre på Super8. DTC CODE-definitionerna är naturligtvis två bitar kortare eftersom de behöver inte längre en pekare alls Jag trodde att definitioner på hög nivå i DTC Forths krävde användningen av ett subrutinanrop i kodfältet. Frank Sergeants Pygmy Forth SER90 visar att ett enkelt hopp kan användas lika enkelt och kommer vanligtvis att bli snabbare. Guy Kelly har sammanställt en fantastisk recension av Forth-implementeringar för IBM PC KEL92, som jag starkt rekommenderar till alla kärnförfattare. Av de 19 Forths studerade han, 10 använda DTC, 7 använda ITC och 2 använda subroutin threading (diskuteras därefter). Jag rekommenderar att du använder Direct-Threaded Code via Indirect-Threaded Code för alla nya Forth-kärnor. Hoppa till NEXT, eller koda den in-line Den främre inre tolken, NEXT, är en vanlig rutin för alla CODE-definitioner. Du kan bara behålla en kopia av denna vanliga rutin och få alla CODE-ord att hoppa till den. (Observera att du hoppa till NEXT ett subrutin Samtal är inte nödvändigt.) Hastigheten på NEXT är dock avgörande för hela Forth-systemet. På många processorer är NEXT-rutinen också ganska kort, ofta bara två eller tre instruktioner. Så det kan vara att föredra att koda NEXT in-line, varhelst den används. Detta görs ofta genom att göra NEXT ett assembler-makro. Detta är en enkel hastighet mot rymdbeslut: in-line NEXT är alltid snabbare, men nästan alltid större. Den totala storleken ökar är antalet extra byte som krävs för in-line expansion, gånger antalet CODE-ord i systemet. Ibland är det ingen överraskning alls: i en 6809 DTC Forth, är en in-line NEXT kortare än en Hoppa-instruktion Subroutine Threaded Code (STC) En högnivå-Forth definition är ingenting annat än en lista över subrutiner som ska utföras. Du behöver inte tolkar för att åstadkomma detta, du kan få samma effekt genom att helt enkelt stryka en lista med subrutin samtal: Se Figur 3. Denna representation av Forth ord har använts som utgångspunkt för att förklara Framåtgående tekniker för monteringstalsprogrammerare KOG82. STC är en elegant representation av kolondefinitioner och CODE-ord är nu identiska. quotDefined wordsquot (VARIABLEs, CONSTANTs och liknande) hanteras på samma sätt som i DTC - kodfältet börjar med ett hopp eller anrop till någon maskinkod någon annanstans. Den största nackdelen är att subrutin samtal är vanligtvis större än enkla adresser. På Z80, till exempel, ökar storleken på kolondefinitioner med 50 - och det mesta av din ansökan är kolondefinitioner Kontrarivis, på 32-bitars 68000 kan det inte hända att någon storlek ökar när 4-byteadresser ersätts med 4-byte BSRs. (Men om din kodstorlek överstiger 64k, måste några av dessa adresser bytas ut med 6-byte-JSR.) Subrutingängning kan vara snabbare än direktgängning. Du sparar tid genom att inte ha en tolk, men du förlorar tid eftersom varje hänvisning till ett Förhandsord innebär ett tryck och en pop av en returadress. I en DTC Forth orsakar endast högnivåord ordna aktivitet på returstapeln. På 6809 eller Zilog Super8 är DTC snabbare än STC. Det finns en annan fördel för STC: den disponerar med IP-registret. Vissa processorer - som 8051 - är desperat bristfälliga för att registrera register. Att eliminera IP kan verkligen förenkla och påskynda kärnan. Det enda sättet att veta är att skriva provkod. Detta är nära involverat i registerval, som diskuteras i nästa avsnitt. STC med direktinsamlingsoptimering för direktutbyggnad På äldre och 8-bitars processorer involverar nästan alla tidigare primitiva flera maskininstruktioner. Men på mer kraftfulla processorer skrivs många tidigare primitiva i en enda instruktion. Till exempel, på 32-bitars 68000, är ​​DROP helt enkelt I en subrutin-gängad Forth, använder DROP i en kolon definition skulle resultera i sekvensen ADDQ är en tvåbyte instruktion. Varför skriva ett subbyte för fyra byte till en tvåbyte instruktion Oavsett hur många gånger DROP används, det finns ingen sparande Koden är mindre och snabbare om ADDQ är kodad direkt i strömmen av BSR. Några Forth compilers gör denna quotin-line expansionquot av CODE ord CUR93a. Nackdelen med in-line expansion är att dekompilering tillbaka till den ursprungliga källkoden blir mycket svår. Så länge som subrutin samtal används, har du fortfarande pekare (subrutinen adresser) till Forth ord som innehåller tråden. Med pekar på orden kan du få sina namn. Men en gång har ett ord utvidgats till in-line-kod, all kunskap om var den här koden kom från är förlorad. Fördelen med in-line expansion - bortsett från hastighet och storlek - är potentialen för kodoptimering. Exempelvis skulle den föregående sekvensen sammanställas i 68000 STC som men kunde utökas in-line som en enskild maskininstruktion Optimering Forth compilers är för bred ett ämne för denna artikel. Detta är ett aktivt område för Forth språkforskning, se till exempel SCO89 och CUR93b. Den slutliga kulmineringen av optimerad STC är en Forth som kompilerar till quotpurequot maskinkod, precis som en C - eller Fortran-kompilator. Token trådad kod (TTC) DTC och STC syftar till att förbättra hastigheten på framtida program, till en viss kostnad i minnet. Nu kan vi flytta den andra riktningen från ITC, mot något långsammare men mindre. Syftet med en vidare tråd är att ange en lista över framåtord (subrutiner) som ska utföras. Antag att ett 16-bitars Forth-system endast hade högst 256 olika ord. Då kan varje ord identifieras unikt med ett 8-bitars nummer. Istället för en lista med 16-bitars adresser skulle du ha en lista med 8-bitars identifierare eller quottokens, cit och storleken på kolondefinitionerna skulle halveras. En token-threaded Forth håller ett bord med adresser på alla Forth ord, som visas i figur 4. Token-värdet används sedan för att indexera i den här tabellen, för att hitta framåtordet som motsvarar en given token. Detta lägger till en nivå av indirection till Forth interpreter, så det är långsammare än en quotaddress-threadedquot Forth. Den främsta fördelen med token-threaded Forths är liten storlek. TTC ses oftast i handdatorer och andra kraftigt begränsade applikationer. Dessutom kan bordet med quotentrypoints i alla Forth ord förenkla koppling av separat sammanställda moduler. Nackdelen med TTC är hastighet: TTC gör de långsammaste framåt. TTC-kompilatorn är också något mer komplex. Om du behöver mer än 256 Forth-ord behöver du ha ett öppet kodningssystem för att blanda 8-bitars och större tokens. Jag kan tänka mig en 32-bitars framåt med 16-bitars tokens, men hur många 32-bitars system är storleksbegränsad Segmentgängad kod Eftersom det finns så många 8086-derivat i världen, förtjänar segmenttråden ett kort omnämnande. I stället för att använda quotumormalquot-byteadresser inom ett 64K-segment används styckadresser. (Ett kvotvärde är 16 byte i 8086.) Då kan tolken ladda dessa adresser i segmentregistren istället för i de vanliga adressregistren. Detta gör det möjligt för en 16-bitars Forth-modell att effektivt komma åt hela megabyte 8086-minnet. Den huvudsakliga nackdelen med segmenttråden är 16-bytes quotgranularityquot av minnesutrymmet. Varje föregående ord måste anpassas till en 16-bytegräns. Om Forth ord har slumpmässiga längder, kommer ett genomsnitt på 8 byte att slösas bort per Förord. REGISTRERA ALLOVERING Vid sidan om trådertekniken är användningen av CPU-registren det viktigaste designbeslutet. Det är förmodligen det svåraste. Tillgängligheten av CPU-registren kan avgöra vilken trådläsningsteknik som kan användas, och även vad minneskartan kommer att vara Klassiska Forth-register. Den klassiska Forth-modellen har fem kvotvärda registers. quot Dessa är abstrakta enheter som används i Forths primitive operations. NEXT, ENTER och EXIT definierades tidigare med avseende på dessa abstrakta register. Var och en av dem är en cell bred - det vill säga i 16-bitars Forth är dessa 16-bitars register. (Det finns undantag från denna regel, som du kommer att se senare.) Det här är kanske inte alla CPU-register. Om din CPU inte har tillräckligt med register kan några av dessa sparas i minnet. Ill beskriver dem i storleksordning av deras betydelse, dvs botten av denna lista är de bästa kandidaterna som ska lagras i minnet. W är arbetsregistret. Den används för många saker, inklusive minnesreferens, så det borde vara ett adressregister, dvs du måste kunna hämta och lagra minne med innehållet i W som adress. Du måste också kunna göra aritmetik på W. (I DTC Forths måste du också kunna hoppa indirekt med W.) W används av tolken i varje föregående ord. I en CPU som bara har ett register, skulle du använda det för W och behålla allting i minnet (och systemet skulle vara otroligt långsamt). IP är tolkpointeren. Detta används av alla föregående ord (genom NEXT, ENTER eller EXIT). IP måste vara ett adressregister. Du måste också kunna öka IP. Subroutine threaded Forths behöver inte detta register. PSP är Parameter Stack (eller quotdata stackquot) Pointer, ibland kallas helt enkelt SP. Jag föredrar PSP eftersom SP ofta är namnet på ett CPU-register, och de borde inte vara förvirrade. De flesta CODE-ord använder det här. PSP måste vara en stapelpekare eller ett adressregister som kan ökas och minskas. Det är också ett plus om du kan göra indexerad adress från PSP. RSP är Return Stack Pointer, ibland kallas helt enkelt RP. Detta används av kolondefinitioner i ITC och DTC Forths, och av alla ord i STC Forths. RSP måste vara en stapelpekare eller ett adressregister som kan ökas och minskas. Om ens möjligt . sätt W, IP, PSP och RSP i register. De virtuella register som följer kan hållas i minnet, men det finns vanligtvis en snabb fördel att hålla dem i CPU-register. X är ett arbetsregister, inte betraktat som ett av de quotclassicalquot Forth-registeren, trots att den klassiska ITC Forths behöver det för andra indirectionen. I ITC måste du kunna hoppa indirekt med X. X kan också användas av några CODE-ord för att göra aritmetiska och så. Detta är särskilt viktigt för processorer som inte kan använda minne som operand. Till exempel kan ADD på en Z80 vara (i pseudokod) Ibland definieras även ett annat arbetsregister, Y. UP är användarpekaren och håller basadressen till arbetsområdets användarområde. UP läggs vanligtvis till förskjutning, och används av högkvalitativ Forth-kod, så det kan bara lagras någonstans. Men om CPU: n kan göra indexerad adressering från UP-registret, kan CODE-ord lättare och snabbt komma åt användarvariablerna. Om du har ett överskott av adressregistren, använd en för UP. Enkelt uppgift Förut behöver inte UPP. X - om det behövs - är viktigare att hålla sig i registret än UP. UP är det enklaste av de föregående virtuella registren att flytta till minnet. Användning av hårdvarupack De flesta processorer har en stapelpekare som en del av hårdvaran, som används av avbrott och subrutin samtal. Hur går kartan i Forth-registeren Om det är PSP eller RSP Det korta svaret beror det på. Det sägs att PSP används mer än RSP i ITC och DTC Forths. Om din CPU har få adressregistren, och PUSH och POP är snabbare än explicit referens, använd hårdvarupacken som parameterstack. Å andra sidan, om din CPU är rik på adresseringslägen - och tillåter indexerad adressering - det är ett plus att ha PSP som ett allmänt ändamålsenligt adressregister. Använd i så fall hårdvarupacken som Return Stack. Ibland gör du inte TMS320C25s hårdvarupack är bara åtta celler djupt - allt men meningslöst för Forth. Så dess hårdvarupack används endast för avbrott, och både PSP och RSP är adressbokar med allmänt ändamål. (ANS Forth anger minst 32 celler i Parameter Stack och 24 celler i Return Stack. Jag föredrar 64 celler av vardera.) Du kommer ibland att stöta på dogmen som hårdvarupacket berodde på Parameterstacken, eller kvittot tillfälle Return Stack. Istället kodar du något exempel Framför primitiver, till exempel och se vilken tillvägagångssätt som är mindre eller snabbare. (DUP och DROP är för övrigt inget test - de är vanligtvis triviala.) Ibland når du konstiga slutsatser Gary Bergstrom har påpekat att en 6809 DTC Forth kan göras några cykler snabbare genom att använda 6809 användarstapelpekaren som IP NEXT blir en POP. Han använder ett indexregister för en av Forths staplar. Top-Of-Stack in Register Framgångs prestanda kan förbättras avsevärt genom att hålla det övre elementet i Parameter Stack i ett register Många Forth ord (t. ex. 0) behöver då inte använda stacken. Andra ord gör fortfarande samma antal pushes och pops, bara på en annan plats i koden. Bara ett fåtal fortsatta ord (DROP och 2DROP) blir mer komplicerade, eftersom du inte längre kan justera stackpekaren - du måste också uppdatera TOS-registret. Det finns några regler när du skriver CODE-ord: Ett ord som tar bort objekt från stapeln måste pop-up quotnewquot-TOS i dess register. Ett ord som lägger till objekt i stapeln måste trycka quotoldquot-TOS på stapeln (såvida det inte förstås konsumeras av ordet). Om du har minst sex cellstorlek CPU-register rekommenderar jag att du håller TOS i ett register. Jag anser att TOS är viktigare än att UP ska ha register, men mindre viktigt än W, IP, PSP och RSP. (TOS i register utför många av funktionerna i X-registret.) Det är användbart om detta register kan utföra minnesadressering. PDP-11s, Z8s och 68000s är bra kandidater. Nio av de 19 IBM PC Forths som studerats av Guy Kelly KEL92 håller TOS i registret. Jag tycker att den här innovationen har motsatt sig på grund av den falska övertygelsen att a) det lägger till instruktioner, och b) toppstackelementet måste vara tillgängligt som minne. Det visar sig att även sådana ord som PICK, ROLL och DEPTH är trivialt modifierade för TOS-in-register. Vad sägs om att buffra två stapelelement i registren När du håller toppen av stapeln i ett register, är det totala antalet utförda åtgärder fortfarande väsentligen desamma. Ett tryck är ett tryck, oavsett om det är före eller efter den operation du utför. Å andra sidan lägger buffering av två stapelelement i registren ett stort antal instruktioner - ett tryck blir ett tryck följt av ett drag. Endast dedikerade Forth-processorer som RTX2000 och fantastiskt smart optimeringssamlare kan dra nytta av att buffra två stapelelement i registren. Några exempel Här är registeruppgifterna från Forths för ett antal olika processorer. Försök att härleda upphovsrättsdesignbesluten från den här listan. quotSPquot hänvisar till hårdvarupackpekaren. quotZpagequot refererar till värden som hålls i 6502s minnessidans noll, vilket är nästan lika användbara som - ibland mer användbara än - värden som hålls i register, t. ex. de kan användas för minnesadressering. quotFixedquot innebär att Paynes 8051 Forth har ett enda, oanvända användarområde, och UP är en hårdkodad konstant. Begränsade register Meddela någonting udda i föregående lista 6502 Forth - en 16-bitars modell - använder 8-bitars stapelpekare Det är möjligt att göra PSP, RSP och UP mindre än cellens storlek på Forth. Detta beror på att staplarna och användarområdet är båda relativt små minnesområden. Varje stapel kan vara så liten som 64 celler i längd och användarområdet överstiger sällan 128 celler. Du behöver helt enkelt se till att antingen a) dessa dataområden är begränsade till ett litet område av minne, så en kort adress kan användas, eller b) de höga adressbitarna tillhandahålls på något annat sätt, t. ex. Välj en minnessida. I 6502 begränsas hårdvarupacken till sidan en av RAM (adresserna 01xxh) av CPU: s design. 8-bitars stapelpekaren kan användas för Return Stack. Parameterstacken hålls på sidan noll av RAM, som kan indirekt nås av 8-bitars indexregistret X. (Fråga för den avancerade studenten: Varför använda 6502s X, och inte Y Tips: kolla på de tillgängliga adresseringslägena. ) I 8051 kan du använda 8-bitarsregistren R0 och R1 för att adressera externt RAM, förutsatt att du uttryckligen matar ut de höga 8 bitarna till adressen till port 2. Detta möjliggör ett kvoteringsval för två staplar. UP är annorlunda än PSP och RSP: det ger helt enkelt en basadress som aldrig ökas eller minskas. Så det är praktiskt att bara leverera de höga bitarna i detta virtuella register. De låga bitarna måste då tillhandahållas med vilken indexerad adresseringsteknik som helst. Till exempel på 6809 kan du använda DP-registret för att hålla de höga 8 bitarna av UP och sedan använda Direkt sidadressering för att komma åt någon av de 256 platserna på den här sidan. Detta tvingar alla användarområden att börja på en adress xx00h, vilket inte är något svårt och begränsar användarområdet till 128 celler i längd. På 8086 kan du tänkbart använda ett segmentregister för att ange basadressen för användarområdet. REFERENSER CUR93a Curley, Charles, quotLife i FastForth Lane, citationstecken i väntan på publicering i Forth Dimensions. Beskrivning av en 68000 subrutingängad Forth. CUR93b Curley, Charles, quotOptimizing i en BSRJSR Threaded Forth, citationstecken i väntan på publicering i Forth Dimensions. Enstaka kodoptimering för FastForth, endast i fem skärmskärmar Inkluderar notering. KEL92 Kelly, Guy M. quotForth Systems Comparisons, citationstecken Mått XIII: 6 (MarApr 1992). Också publicerad i 1991 FORML Conference Proceedings. Båda är tillgängliga från Forth Interest Group, P. O. Box 2154, Oakland, CA 94621. Illustrerar designavvägningar från många 8086 Forths med kodfragment och referensvärden - rekommenderas KOG82 Kogge, Peter M. c. Arkitekturspår till gängade kodsystem, citerad IEEE Computer, vol. 15 nr. 3 (mar 1982). Bibehåller den slutgiltiga beskrivningen av olika gängningstekniker. ROD91 Rodriguez, B. J. quotB. Y.O. Assembler, citat Del 1, The Computer Journal 52 (SepOct 1991). Allmänna principer för skrivning Församlare. ROD92 Rodriguez, B. J. quot. B.Y. O. Assembler, citat Del 2, The Computer Journal 54 (JanFeb 1992). En 6809 assembler i Forth. SCO89 Scott, Andrew, quotAn Extensible Optimizer för kompilering framåt, citerad 1989 FORML Conference Proceedings. Forth Interest Group, P. O. Box 2154, Oakland, CA 94621. Bra beskrivning av en 68000 optimeringsnummer utan kod. CUR86 Curley, Charles, Real-Forth för 68000. privat distribuerad (1986). JAM80 James, John S. fig-Forth för PDP-11. Forth Interest Group (1980). KUN81 Kuntze, Robert E. MVP-Forth för Apple II. Mountain View Press (1981). LAX84 Laxen, H. och Perry, M. F83 för IBM PC. version 2.1.0 (1984). Distribueras av författarna, tillgängliga från Forth Interest Group eller GEnie. LOE81 Loeliger, R. G. Gängade tolknings språk. BYTE Publications (1981), ISBN 0-07-038360-X. Kan vara den enda boken som någonsin skrivits om ämnet för att skapa en Forth-liknande kärna (det använda exemplet är Z80). Värt det om du kan hitta en kopia. MPE92 MicroProcessor Engineering Ltd. MPE Z8Super8 PowerForth-mål. MPE Ltd. 133 Hill Lane, Shirley, Southampton, S01 5AF, U. K. (juni 1992). En kommersiell produkt. PAY90 Payne, William H. Embedded Controller FORTH för 8051-familjen. Academic Press (1990), ISBN 0-12-547570-5. Detta är en komplett quotkitot för en 8051 Forth, inklusive en metakompiler för IBM PC. Endast filer med hårddisk kan laddas ner från GEnie. Inte för nybörjaren SER90 Sergeant, Frank, Pygmy Forth för IBM PC. version 1.3 (1990). Distribueras av författaren, tillgänglig från Forth Interest Group. Version 1.4 är nu tillgänglig på GEnie, och värt den extra ansträngningen att få. TAL80 Talbot, R. J. fig-Forth för 6809. Forth Interest Group (1980). Författarnas anteckning för webbpublicering: Filerna som tidigare var tillgängliga på GEnie-tjänsten online finns nu tillgängliga från FTP-serveren Forth Interest Group, ftp: ftp. forth. orgpubForth. Uppdaterad: 14 juni 2010 Den här artikeln är en del av min Linux Kernel Crash Bok. Den är tillgänglig för gratis nedladdning i PDF-format Slutligen har det stora ögonblicket kommit. Läser informationen som visas av kraschverktyget, förstå vad de nyfikna linjerna betyder och hackar dig igenom problemet till andra sidan. Vi har lärt oss hur du konfigurerar våra system för kärnkraschdumpning, med hjälp av LKCD och Kdump. både lokalt och över nätverket. Vi har lärt oss hur du installerar kraschdumpningsmekanismen på både CentOS och openSUSE. och vi granskade de subtila skillnaderna mellan de två operativsystemen. Därefter behärskade vi den grundläggande användningen av kraschverktyget, med hjälp av den för att öppna den dumpade minneskärnan och bearbeta informationen däri. Men vi lärde oss inte att tolka produktionen. Pre-Introduktion Idag kommer vi att fokusera på just det. Läs vmcore-analysen, förstå vad posterna betyder, utföra grundläggande granskning av problemet, granska källkoden och härleda en effektiv metod för hantering av kärnkraschproblem i framtiden. Så om du är i humör för någon super-allvarlig hackologi, följ mig. Innehållsförteckning Nödvändig läsning Du MÅSTE läsa andra artiklar i andra för att förstå hur krasch fungerar. Du hittar den detaljerade listan med referenser nedan. Utan att behärska de grundläggande begreppen, inklusive Kdump och kraschfunktionalitet, kommer du inte att kunna följa denna handledning effektivt. Analysera kraschrapporten - Första steg När du startar kraschen får du den ursprungliga rapportinformationen som skrivs ut till konsolen. Det är här analysen av kraschen börjar. krasch 4.0-8.9.1.el5.centos Upphovsrätt (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Red Hat, Inc. Copyright (C) 2004, 2005, 2006 IBM Corporation Copyright (C) 1999 -2006 Hewlett-Packard Co Copyright (C) 2005, 2006 Fujitsu Limited Upphovsrätt (C) 2006, 2007 VA Linux Systems Japan KK Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. Detta program är fri programvara, som omfattas av GNU General Public Licens, och du är välkommen att ändra den andor distribuera kopior av det under vissa förutsättningar. Ange hjälpkopiering för att se villkoren. Det här programmet har absolut ingen garanti. Ange hjälpgaranti för detaljer. OBS! Stdin: inte en tty GNU gdb 6.1 Copyright 2004 Free Software Foundation, Inc. GDB är fri programvara, som omfattas av GNU General Public License, och du är välkommen att ändra det och distribuera kopior av det under vissa förutsättningar. Skriv visa kopiering för att se villkoren. Det finns absolut ingen garanti för GDB. Skriv ut garanti för detaljer. Denna GDB har konfigurerats som x8664-okänd-linux-gnu. bt: kan inte övergå från undantagsstapel till nuvarande processstapel: undantagsstapelpekare: ffff810107132f20 processstapelpekare: ffff81010712bef0 currentstackbase: ffff8101b509c000 KERNEL: usrlibdebuglibmodules2.6.18-164.10.1.el5.centos. plusvmlinux DUMPFILE: vmcore CPUS: 2 DATUM: tis Jan 19 20:21:19 2010 UPPDAG: 00:00:00 LOAD AVERAGE: 0.00, 0.04, 0.07 Uppgifter: 134 NODENAME: testhost2localdomain RELEASE: 2.6.18-164.10.1.el5 VERSION: 1 SMP Thu Jan 7 19:54: 26 EST 2010 MASKIN: x8664 (3000 MHz) MINNE: 7.5 GB PANIC: SysRq. Trigger en crashdump PID: 0 COMMAND: swapper TASK: ffffffff80300ae0 (1 av 2) THREADINFO: ffffffff803f2000 CPU: 0 STAT: TASKRUNNING (AKTIV) Låt oss gå igenom rapporten. Det första du ser är något slags fel: bt: kan inte övergå från undantagsstapel till nuvarande processstapel: undantagsstapelpekare: ffff810107132f20 processstapelpekare: ffff81010712bef0 currentstackbase: ffff8101b509c000 Den tekniska förklaringen till det här felet är lite knepigt. Citat från crash utility-postlistorna om förändringar i crashverktyget 4.0-8.11-utgåvan, lär vi oss följande information: Om en kdump NMI utfärdad för en icke-kraschning fick x8664 cpu emot när den kördes i schema (), efter att ha satt nästa uppgift som aktuell i cpus runqueue, men innan du ändrar kärnstacken till den för nästa uppgift, skulle en backtrace misslyckas med att göra övergången från NMI-undantagsstacken tillbaka till processstacken med felmeddelandet bt: kan inte övergång från undantagsstack till aktuell processstapel. Denna patch kommer att rapportera inkonsekvenser som hittats mellan en uppgift som är markerad som den aktuella uppgiften i en cpus runqueue och uppgiften som finns i per-cpu x8664pda pcurrent-fältet (2.6.29 och tidigare) eller per-cpu currenttask-variabeln (2.6.30 och senare). Om det säkert kan fastställas att runqueue-inställningen (används som standard) är förhastad, så kommer den aktiva aktiviteten för kraschverktyget intern per-cpu att ändras till att vara den uppgift som anges med lämpligt arkitektur-specifikt värde. Vad betyder detta att det är en varning som du bör tänka på när du analyserar kraschrapporten. Det hjälper oss att bestämma vilken uppgiftsstruktur vi behöver titta på för att felsöka kraschförklaringen. För borta ignorerar du detta fel. Det är inte viktigt att förstå vad kraschrapporten innehåller. Du kan eller kanske inte se den. Nu kan vi granska koden under det här felet. KERNEL: anger kärnan som körs vid kraschens gång. DUMPFILE: är namnet på den dumpade minneskärnan. CPUS: är antalet CPUer på din maskin. DATE: anger kraschens tid. UPPGIFTER: anger antalet uppgifter i minnet vid kraschtidpunkten. Uppgift är en uppsättning programinstruktioner som laddas i minnet. NODENAME: Namnet på den kraschade värden. RELEASE: och VERSION: Ange kärnans release och version. MASKIN: specificerar CPU: s arkitektur. MEMORY: är storleken på det fysiska minnet på den kraschade maskinen. Och nu kommer de intressanta bitarna: PANIC: specificerar vilken typ av krasch som inträffade på maskinen. Det finns flera typer som du kan se. SysRq (System Request) avser Magic Keys, som låter dig skicka instruktioner direkt till kärnan. De kan åberopas med hjälp av en tangentbordssekvens eller genom att echoing brevkommandon till procsysrq-trigger. förutsatt att funktionaliteten är aktiverad. Vi har diskuterat detta i Kdump-handledningen. Oj, är en avvikelse från det förväntade, korrekta beteendet hos kärnan. Ojämnderna resulterar vanligtvis i att den kränkande processen dödas. Systemet kan eller kanske inte återuppta sitt normala beteende. Mest troligt kommer systemet att komma in i ett oförutsägbart, instabilt tillstånd, vilket kan leda till kärnan panik om några av de buggy, dödade resurser begärs senare. Till exempel, i mina Ubuntu Karmic och Fedora Constantine recensioner, har vi sett bevis på kärnkrascher. Systemet fortsatte dock att fungera. Dessa kraschar var faktiskt oopses. Vi kommer att diskutera Fedora-fallet senare. Panik är ett tillstånd där systemet har stött på ett dödligt fel och kan inte återhämta sig. Panik kan orsakas genom att försöka få åtkomst till otillåtna adresser, tvingad laddning eller lossning av kärnmoduler eller maskinvaruproblem. I vårt första, mest godartade exempel hänvisar PANIC: strängen till användningen av Magic Keys. Vi utsåg medvetet en krasch. PANIC: SysRq. Utlös en crashdump PID: är processens ID för. process som orsakade kraschen. COMMAND: är namnet på processen, i det här fallet swapper. swapper. eller PID 0 är schemaläggaren. Det är processen som delegerar CPU-tiden mellan runnable processer och om det inte finns några andra processer i runqueue, tar det kontroll. Du kanske vill hänvisa till swapper som den lediga uppgiften, så att säga. Theres en swapper per CPU, som du snart kommer att se när vi börjar utforska kraschen i större djup. Men det här är inte riktigt viktigt. Vi kommer att stöta på många processer med olika namn. TASK: är adressen i minnet för den pågående processen. Vi kommer att använda denna information senare. Det finns en skillnad i minnet som adresserar för 32-bitars och 64-bitars arkitekturer. CPU: är CPU: ns nummer (relevant om mer än en) där den kränkande processen körde vid kraschens gång. CPU refererar till CPU-kärnor och inte bara fysiska CPU-enheter. Om du kör din Linux med hyperthreading aktiverad, räknar du också separata trådar som CPU: er. Detta är viktigt att komma ihåg, eftersom återkommande krascher på bara en specifik CPU kan indikera ett CPU-problem. Om du kör dina processer med affinitet som är inställd på vissa CPU (taskset), kan du ha svårare att hitta CPU-relaterade problem när du analyserar kraschrapporterna. Du kan undersöka antalet CPU-enheter genom att köra proccpuinfo-katten. STAT: Indikerar processläget vid kraschtidpunkten. TASKRUNNING hänvisar till runnable processer, dvs processer som kan fortsätta deras utförande. Återigen kommer vi att prata mer om detta senare. Bli varmare Vi har sett ett godartat exempel hittills. Bara en introduktion. Vi ska ta en titt på flera fler exempel, inklusive verkliga fall. För närvarande vet vi lite om kraschen, förutom att processen som orsakade det. Vi ska nu undersöka flera fler exempel och försöka förstå vad vi ser där. Fedora exempel Låt oss gå tillbaka till Fedora-fallet. Ta en titt på skärmdumpen nedan. Medan informationen är ordnad något annorlunda än vad vi tidigare sett, är det i huvudsak samma sak. Men det finns en ny del av informationen: Pid: 0, comm: swapper Inte smittad. Låt oss fokusera på den icke-tunna strängen för ett ögonblick. Vad betyder det? Det betyder att kärnan inte kör någon modul som har laddats kraftigt. Med andra ord står vi antagligen inför en kodfel någonstans snarare än en kränkning av kärnan. Du kan undersöka din körkärna genom att exekvera: Hittills har vi lärt oss en annan information. Vi kommer att prata om detta senare. Ett annat exempel, från vitboken Titta på det här: MEMORY: 128MB PANIC: Oops: 0002 (kontrollera logg för detaljer) PID: 1696 COMMAND: insmod Vad har vi här En ny bit av information. Oj: 0002. Vad betyder det här kärnan Sidfel De fyra siffrorna är en decimalkod för kärnan Sidfel. Läsning av OReillys Förstå Linux-kärnan, Kapitel 9: Processadressutrymme, Sidfelundantagshanterare, sid 376-382, vi lär oss följande information: Om den första biten är klar (0) berodde undantaget av en åtkomst till en sida som är inte närvarande om biten är inställd (1), det betyder otillåtet åtkomsträtt. Om den andra biten är klar (0) orsakades undantaget av att läsa eller exekvera åtkomst om set (1), undantaget orsakades av en skrivåtkomst. Om den tredje biten är klar (0), orsakades undantaget medan processorn var i Kärneläge annars uppstod det i användarläge. Den fjärde biten berättar om felet var en instruktionshämta. Detta gäller endast för 64-bitars arkitektur. Eftersom vår maskin är 64-bitars, har biten betydelse här. Detta är ganska intressant. Verkligen oförståelig information börjar känna sig väldigt logisk. Åh, du kan också se kärnans sidfel i följande format, som ett bord: Ibland kallas ogiltig åtkomst också som Skyddsfel: För att förstå vad som hände måste vi översätta decimalkoden till binär och undersöka sedan de fyra bitarna, från höger till vänster. Du kan hitta den här informationen under archarchmmfault. c i kärnkällsträdet: Sidfel Felkodsbit definierar PFPROT (1ltlt0) eller ingen sida hittad definiera PFWRITE (1ltlt1) definiera PFUSER (1ltlt2) definiera PFRSVD (1ltlt3) definiera PFINSTR (1ltlt4) In vårt fall, decimal 2 är binärt 10. Ser från höger till vänster är bit 1 noll, bit 2 lyser, bit 3 och 4 är noll. Observera binärräkning, från noll. 0002 (dec) --gt 0010 (binär) --gt Ej instruktionsfetchKernel-lägeWriteInvalidåtkomst Därför har vi en sida som inte hittades under en skrivoperation i Kärnläge felet var inte en instruktionshämta. Naturligtvis är det lite mer komplicerat än det, men fick fortfarande en mycket bra uppfattning om vad som händer. Tja, det börjar bli intressant, det är inte det. Titta på den förekommande processen, insmod. det här berättar ganska lite. Vi försökte ladda en kärnmodul. Det försökte skriva till en sida som den inte kunde hitta, vilket innebar skyddsfel, vilket ledde till att vårt system kraschar. Det här kan vara ett felaktigt skrivet kodnummer. Statuskontroll OK, hittills har vi sett en hel del användbar information. Vi lärde oss om de grundläggande identifieringsfälten i kraschrapporten. Vi lärde oss om de olika typerna av paniker. Vi lärde oss att identifiera den förekommande processen, bestämma om kärnan är beslagad och vilken typ av problem inträffade vid kraschens gång. Men vi har just börjat vår analys. Låt oss ta det här till en ny nivå. Bli varm I den första artikeln om krasch lärde vi oss om några grundläggande kommandon. Det är dags att använda dem bra. Det första kommandot vi vill ha är bt-backtrace. Vi vill se exekveringshistoriken för den förekommande processen, dvs backtrace. PID: 0 UPPGIFT: ffffffff80300ae0 CPU: 0 COMMAND: swapper 0 ffffffff80440f20 crashnmicallback vid ffffffff8007a68e en ffffffff80440f40 donmi vid ffffffff8006585a 2 ffffffff80440f50 nmi vid ffffffff80064ebf undantag RIP: defaultidle61 RIP: ffffffff8006b301 RSP: ffffffff803f3f90 RFLAGS: 00.000.246 RAX: 0000 biljoner RBX: ffffffff8006b2d8 RCX: 0000 biljoner RDX : 0000000000000000 RSI: 0000000000000001 RDI: ffffffff80302698 RBP: 0000000000090000 R8: ffffffff803f2000 R9: 000000000000003e R10: ffff810107154038 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 ORIGRAX: ffffffffffffff CS: 0010 SS: 0018 --- ltexception stackgt - - 3 ffffffff803f3f90 defaultidle på ffffffff8006b301 4 ffffffff803f3f90 cpuidle på ffffffff8004943c Vi har mycket data här, vi kan börja smälta det långsamt. Samtalsspårning Sekvensen av numrerade linjer, som börjar med hash-tecknet () är samtalspåret. Det är en lista över kärnfunktioner som exekverats precis före kraschen. Detta ger oss en bra indikation på vad som hände innan systemet gick ner. 0 ffffffff80440f20 crashnmicallback vid ffffffff8007a68e en ffffffff80440f40 donmi vid ffffffff8006585a 2 ffffffff80440f50 nmi vid ffffffff80064ebf undantag RIP: defaultidle61 RIP: ffffffff8006b301 RSP: ffffffff803f3f90 RFLAGS: 00.000.246 RAX: 0000 biljoner RBX: ffffffff8006b2d8 RCX: 0000 biljoner RDX: 0000 biljoner RSI: 0000000000000001 RDI: ffffffff80302698 RBP: 0000000000090000 R8 : ffffffff803f2000 R9: 000000000000003e R10: ffff810107154038 R11: 0000000000000246 R12: 0000 biljoner R13: 0000 biljoner R14: 0000 biljoner R15: 0000 biljoner ORIGRAX: ffffffffffffffff CS: 0010 SS: 0018 --- ltexception stackgt --- 3 ffffffff803f3f90 defaultidle vid ffffffff8006b301 4 ffffffff803f3f90 cpuidle vid ffffffff8004943c Vi kommer att diskutera detta mer senare. Instruktionspekare Den första riktigt intressanta raden är den här: Undantags RIP: defaultidle61 Vi har undantag RIP: defaultidle61. Vad betyder detta Först kan vi diskutera RIP. RIP är instruktionspekaren. Det pekar på en minnesadress, vilket indikerar hur programutförandet i minnet fortskrider. I vårt fall kan du se den exakta adressen i raden strax nedanför den begränsade undantagslinjen: undantag RIP: defaultidle61 RIP: ffffffff8006b301 RSP: ffffffff803f3f90. För tillfället är adressen i sig inte viktig. Obs! På 32-bitars arkitektur kallas instruktionspekaren EIP. Den andra delen av informationen är mycket mer användbar för oss. defaultidle är namnet på den kärnfunktion där RIP ligger. 61 är förskjutningen, i decimalformat, inuti den funktionen där undantaget inträffade. Detta är den väldigt viktiga bit som vi kommer att använda senare i vår analys. Kodsegment (CS) - registret Koden mellan den fästa strängen ner till --- ltexception stackgt --- är dumpningen av register. De flesta är inte användbara för oss, förutom CS (Kodsegment) - registret. Återigen möter vi en fyrsiffrig kombination. För att förklara detta begrepp måste jag avvika lite och prata om privilegierivåer. Privilege-nivå är begreppet att skydda resurser på en CPU. Olika körningstrådar kan ha olika behörighetsnivåer, vilket ger tillgång till systemresurser, till exempel minnesområden, IO-portar etc. Det finns fyra nivåer, från 0 till 3. Nivå 0 är mest privilegierade, känt som kärnläge. Nivå 3 är minst privilegierad, känd som användarläge. De flesta moderna operativsystem, inklusive Linux, ignorerar de mellanliggande två nivåerna, med bara 0 och 3. Nivåerna är också kända som Ringar. Ett anmärkningsvärt undantag för användningen av nivåer var IBM OS2-systemet. Nuvarande Privilege Level (CPL) Code Segment (CS) register är det som pekar på ett segment där programinstruktioner är inställda. De två minst signifikanta bitarna i detta register anger CPU: ns nuvarande privilegierivå (CPL). Två bitar, vilket betyder siffror mellan 0 och 3. Beskrivning av Privilege Level (DPL) Amp Required Privilege Level (RPL) Beskrivnings Privilege Level (DPL) är den högsta nivån av behörighet som kan komma åt resursen och definieras. Detta värde definieras i segmentbeskrivningen. Begärd Privilege Level (RPL) definieras i Segmentväljaren, de två sista bitarna. Matematiskt får CPL inte överskrida MAX (RPL, DPL), och om det gör det kommer det att orsaka ett allmänt skyddsfel. Varför är allt detta viktigt, du frågar väl, till exempel om du stöter på ett fall där systemet kraschade medan CPL var 3, då kan detta indikera felaktig hårdvara, eftersom systemet inte ska krascha på grund av ett problem i användarläget . Alternativt kan det vara ett problem med ett buggysystemsamtal. Bara några grova exempel. För mer information, var vänlig överväga att hänvisa till OReillys Understanding Linux Kernel, Kapitel 2: Minnesadressering, Sid 36-39. Du hittar användbar information om Segmentmarkörer, Segmentbeskrivare, Tabellindex, Globala och Lokala Descriptor Tabeller, och naturligtvis nuvarande Privilege Level (CPL). Tillbaka till vår kraschlogg: Som vi vet anger de två minst signifikanta bitarna CPL. Två bitar betyder fyra nivåer, men nivåerna 1 och 2 ignoreras. Detta lämnar oss med 0 och 3, Kernel-läge respektive Användarläge. Omräknat till binärt format har vi 00 och 11. Formatet som används för att presentera beskrivningsdata kan vara förvirrande, men det är väldigt enkelt. Om den högsta siffran är jämn, var det i Kernel-läget om den sista siffran är udda, var då i användarläget. Därför ser vi att CPL är 0, den uppsåtliga uppgiften som ledde till att kraschen körde i kärnläget. Detta är viktigt att veta. Det kan hjälpa oss att förstå beskaffenheten av vårt problem. Bara för referens, här är ett exempel där kraschen inträffade i användarläge, samlad på en SUSE-maskin: Men det är bara nöje. Tillbaka till vårt exempel har vi lärt oss många användbara viktiga detaljer. Vi känner till den exakta minnesadressen där instruktionspekaren var vid kraschens gång. Vi vet privilegiumnivån. Ännu viktigare, vi vet namnet på kärnfunktionen och förskjutningen där RIP pekade vid kraschtidpunkten. För alla praktiska ändamål behöver vi bara hitta källfilen och granska koden. Det kan givetvis inte alltid vara möjligt av olika anledningar, men det kommer vi ändå att göra som en övning. Så vi vet att crashnmicallback () funktionen heter donmi (), donmi () kallades av nmi (), nmi () kallades av defaultidle (), vilket orsakade kraschen. Vi kan undersöka dessa funktioner och försöka förstå djupare vad de gör. Vi ska göra det snart. Nu kan vi återkomma till vårt Fedora-exempel en gång till. Fedora exempel, igen Nu när vi förstår vad som är fel kan vi ta en titt på Fedora-exemplet igen och försöka förstå problemet. Vi har en krasch i en icke-tainted kärna, orsakad av swapper processen. Kraschrapporten pekar på funktionen nativeapicwritedummy. Då är det också ett mycket långt samtalspår. Ganska lite användbar information som bör hjälpa oss att lösa problemet. Vi kommer att se hur vi kan använda kraschrapporterna för att hjälpa utvecklare att fixa fel och producera bättre och stabilare program. Nu kan vi fokusera mer på krasch och de grundläggande kommandona. backtrace för alla uppgifter Som standard kommer kraschen att visa backtrace för den aktiva uppgiften. Men du kanske också vill se backtrace av alla uppgifter. I det här fallet vill du springa förbi. Dump system meddelande buffert logg-dump system meddelande buffert Detta kommando dumpar innehållet i kernel logbuf i kronologisk ordning. Kärnloggbugger (logbuf) kan innehålla användbara ledtrådar före kraschen, vilket kan hjälpa oss att hitta problemet enklare och förstå varför vårt system gick ner. Log-kommandot kan inte vara riktigt användbart om du har intermittenta hårdvaruproblem eller rent programvaruproblem, men det är definitivt värt försöket. Heres vår kraschlogg, de sista linjerna: ide: misslyckad opcode var: 0xec mtrr: typmatchning för f8000000.400000 gammal: oklippbar ny: skrivkombinering ISO 9660 Extensions: Microsoft Joliet Level 3 ISO 9660 Extensions: RRIP1991A SysRq. Trigger en kraschdump och det är SysRq-meddelandet. Användbar att veta. I verkliga fall kan det finnas något mycket mer intressant. Visa statusinformation för informationen PS - statusinformation för visningsprocessen Detta kommando visar processstatus för vald eller alla processer i systemet. Om inga argument läggs in visas processdata för alla processer. Ta en titt på exemplet nedan. Vi har två swapper-processer Som jag sa tidigare har varje CPU sin egen schemaläggare. Den aktiva uppgiften är markerad med gt. Kraschverktyget kan laddas pekar på en uppgift som inte orsakade paniken eller kanske inte kan hitta panikuppgiften. Det finns inga garantier. Om du använder virtuella maskiner, inklusive VMware eller Xen, kan sakerna bli ännu mer komplicerade. I det här fallet markerar pekaren i PS-utgången den felaktiga processen: Använda backtrace för alla processer (med foreach) och kör PS-kommandot, du borde kunna lokalisera den förekommande processen och undersöka uppgiften. Övrig användbar information som du kan behöva: Häftiga föremål är kärntråd, till exempel init och udevd är det inte. Därefter finns information om minnesanvändning, VSZ och RSS, processstatus och mer. Supernackiga saker Obs! Det här avsnittet är omöjligt svårt. För svårt för de flesta. Mycket få personer är skickliga nog att dabble i kärnkod och vet verkligen vad som händer där inne. Att försöka vara modig och ta itu med de möjliga buggarna som är dolda i kraschkärnor är ett ädelt försök, men du borde inte ta det lätt. Jag måste erkänna att även om jag kan läsa kraschrapporter och medföljande källor, har jag fortfarande en stor sak att lära mig om de små sakerna och bitarna. Förvänta dig inte några mirakel. Theres ingen silver-bullet lösning till kraschanalys Tid att bli extremt allvarlig. Låt oss säga att du kanske vill analysera C-koden för den förekommande funktionen. Naturligtvis bör du ha C-källorna tillgängliga och kunna läsa dem. Det här är inte något som alla borde göra, men det är en intressant mental träning. Källkod Okej, du vill undersöka koden. Först måste du få källorna. Vissa fördelningar gör källorna lättillgängliga. Till exempel i openSUSE behöver du bara hämta kärnkällspaketet. Med CentOS är det lite svårare, men genomförbart. Du kan också besöka Linux Kernel Archive och ladda ner kärnan som matchar din egen, även om vissa källor kan skilja sig från de som används på ditt system, eftersom vissa leverantörer gör egna anpassade ändringar. När du har källorna, är det dags att undersöka dem. Exempel på openSUSE: Du kan bläddra i källorna med hjälp av standardverktygen som hitta och grep, men det kan vara ganska tråkigt. Istället varför inte låta systemet göra allt det hårda arbetet för dig. Ett mycket snyggt verktyg för att surfa på C-kod kallas cscope. Verktyget går från kommandoraden och använder ett vi-liknande gränssnitt. Som standard söker den efter källor i den aktuella katalogen, men du kan konfigurera den på vilket sätt. cscope är tillgängligt i repositories: Nu, i katalogen innehållande källor (som standard, usrsrclinux), kör cscope: Detta kommer rekursivt att söka igenom alla underkataloger, indexera källorna och visa huvudgränssnittet. Det finns andra användningsområden, liksom försök på manens sida eller --hjälpsflagga. Nu är det dags att sätta verktyget i god användning och söka efter önskade funktioner. Vi börjar med Hitta denna C-symbolen. Använd markörknapparna för att komma ner till den här raden, skriv sedan önskat funktionsnamn och tryck på Enter. Resultaten kommer att visas: Beroende på vad som hände kan du få många resultat eller ingen. Det är ganska möjligt att det inte finns någon källkod som innehåller funktionen som ses i kraschrapporten. Om det finns för många resultat, kanske du vill söka efter nästa funktion i samtalsspårningen med hjälp av de Sökfunktioner som kallas med detta funktionsalternativ. Använd fliken för att hoppa mellan inmatnings - och utmatningssektionen. Om du har officiell leverantörs support är det här ett bra ögonblick att vända kommandot över och låt dem köra. Om du håller med undersökningen kan du leta efter de andra funktionerna som anges i samtalspåret hjälpa dig att begränsa den C-fil du behöver. Men det finns ingen garanti och det här kan vara en lång, tråkig process. Vidare, när som helst du behöver hjälp, tryck bara på. och du kommer att få en grundläggande användarhandbok: I kärnkällkatalogen kan du också skapa cscope-index, för snabbare sökningar i framtiden, genom att köra gör cscope. Demontera objektet Antag att du har hittat källan, det är dags att demontera objektet som är sammanställt från den här källan. Först om du kör en debug-kärna, har alla objekten sammanställts med debug-symbolerna. Du har tur. Du behöver bara dumpa objektet och gräva in i den blandade monterings-C-koden. Om inte, måste du kompilera källan med felsymboler och sedan omvända den. Detta är inte en enkel eller en trivial uppgift. Först, om du använder en kompilator som är annorlunda än den som användes för att kompilera originalet, kommer ditt objekt att vara annorlunda än det i kraschrapporten, vilket gör dina ansträngningar svåra om inte omöjliga. Trivial exempel Jag kallar detta exempel trivialt eftersom det inte har något att göra med kärnan. Det visar bara hur man sammanställer objekt och sedan demonterar dem. Vilken källa som helst kommer att göra. I vårt fall, använd väl MPlayer, en populär open-source mediaspelare som vår syndabock. Hämta MPlayer källkoden, kör. configure, make. När objekten är skapade, ta bort en av dem och kompilera sedan den. Kör gör ltobject namegt. till exempel: Observera att märket inte har någon mening utan en Makefile, som anger vad som behöver göras. Men vi har en Makefile. Det skapades när vi körde. configure. Annars skulle allt detta verkligen inte fungera. Makefile är mycket viktigt. Vi kommer snart att se ett mindre trivsamt exempel. Om du inte tar bort det befintliga objektet kommer du förmodligen inte att kunna göra det. Gör jämför tidstämplar på källor och objektet, så om du inte ändrar källorna kommer återkompilering av objektet att misslyckas. Nu, här är ett annat enkelt exempel och notera skillnaden i storleken på det skapade objektet, en gång med felsökningssymboler och en gång utan: Om du inte har en Makefile kan du påmana gcc manuellt med alla typer av flaggor. Du behöver kärnhuvuden som matchar arkitekturen och kärnversionen som användes för att skapa kärnan där kraschen inträffade, annars kommer dina nyligen sammanställda objekt att vara helt annorlunda än de du vill analysera, inklusive funktioner och förskjutningar. Ett verktyg som du vill använda för demontering är objdump. Du kommer antagligen vilja använda verktyget med - S-flaggan, vilket innebär visningskodkod blandad med monteringsanvisningar. Du kan också vilja - s flagga, som visar innehållet i alla sektioner, inklusive tomma. - S innebär - d. som visar monteringskonfigurationen för maskininstruktionerna från objfile detta alternativ endast demonterar de avsnitt som förväntas innehålla instruktioner. Alternativt, använd - D för alla sektioner. Således skulle den mest inkluderande objdumpen vara: objdump - D - S ltcompiled objekt med debug symbolsgt gt ltoutput filegt Det kommer att se något så här: Och ett ännu bättre exempel, memhog-dumpningen: Att flytta till kärnkällor Uppvärmning. När du är säker på att träna med trivial kod, är det dags att flytta till kärnan. Se till att du inte bara tar bort någon viktig fil. För övningens skull, flytta eller byt namn på eventuella befintliga kärnobjekt som du kan hitta lurar om. Därefter kompilera dem. Du behöver den. config-fil som används för att kompilera kärnan. Det bör ingå i källorna. Alternativt kan du dumpa det från procconfig. gz. zcat procconfig. gz gt. config På RedHat-maskiner hittar du även konfigurationsfilerna under uppstart. Se till att du använder den som matchar den kraschade kärnan och kopierar den till källkatalogen. Om det behövs, ändra några av alternativen, som CONFIGDEBUGINFO. Mer om det senare. Utan. config-filen kan du inte kompilera kärnkällor: Du kan också stöta på ett fel där Makefile saknas, men det finns det. I det här fallet kan du komma inför ett relativt enkelt problem, med fel inställd ARCH-miljövariabel. Till exempel, i585 kontra i686 och x86-64 versus x8664. Var uppmärksam på felet och jämför arkitekturen med ARCH-variabeln. I värsta fall kan du behöva exportera det korrekt. Till exempel: Som en långsiktig lösning kan du också skapa symboliska länkar under usrsrclinux från den dåliga arkitekturen till den rätta. Detta är inte strikt relaterat till analysen av kärnkrascher, men om och när du sammanställer kärnkällor kan det hända att du stöter på det här problemet. Nu när det gäller CONFIGDEBUGINFO-variabeln. Det ska vara inställt på 1 i din. config-fil. Om du kommer ihåg handledningen Kdump var det en förutsättning som vi bad om för att kunna felsöka kärnkrascher. Detta berättar kompilatorn att skapa objekt med felsökningssymboler. Alternativt exporterar du variabeln i skalet, som CONFIGDEBUGINFO1. Ta en titt på Makefile. Du bör se att om denna variabel är inställd kommer objektet att kompileras med felsymboler (-g). Det här är vad vi behöver. Därefter kommer vi återigen att använda objdump. Nu kan Makefile verkligen saknas. I det här fallet får du en hel massa fel relaterade till kompileringsprocessen. Men med Makefile på plats borde det fungera smidigt. Och då är objektet aktuellt exempel igen. Om du inte tar bort en befintlig, kan du inte kompilera en ny, speciellt om du behöver debug-symboler för senare demontering. Slutligen, det demonterade objektet: Vad gör vi nu Tja, du letar efter den funktion som anges i undantagsperioden och markera startadressen. Lägg sedan till offset till detta nummer, översatt till hexadecimalt format. Gå sedan till den angivna raden. Allt som är kvar är att försöka förstå vad som verkligen hände. Du har en monteringsinstruktion som anges och eventuellt någon C-kod, som berättar för oss vad som kan ha gått fel. Its not easy. In fact, its very difficult. But its exciting and you may yet succeed, finding bugs in the operating system. Whats more fun than that Above, we learned about the compilation and disassembly procedures, without really doing anything specific. Now that we know how to go about compiling kernel objects and dissecting them into little bits, lets do some real work. Intermediate example We will now try something more serious. Grab a proof-of-concept code that crashes the kernel, compile it, examine the crash report, then look for the right sources, do the whole process we mentioned above, and try to read the alien intermixed assembly and C code. Of course, we will be cheating, cause we will know what were looking for, but still, its a good exercise. The most basic non-trivial example is to create a kernel module that causes panic. Before we panic our kernel, lets do a brief overview of the kernel module programming basics. Create problematic kernel module This exercise forces us to deviate from the crash analysis flow and take a brief look at the C programming language from the kernel perspective. We want to crash our kernel, so we need kernel code. While were going to use C, its a little different from everyday stuff. Kernel has its own rules. We will have a sampling of kernel module programing. Well write our own module and Makefile, compile the module and then insert it into the kernel. Since our module is going to be written badly, it will crash the kernel. Then, we will analyze the crash report. Using the information obtained in the report, we will try to figure out whats wrong with our sources. Step 1: Kernel module We first need to write some C code. Lets begin with hello. c. Without getting too technical, heres the most basic of modules, with the init and cleanup functions. The module does not nothing special except print messages to the kernel logging facility. hello. c - The simplest kernel module. include ltlinuxmodule. hgt Needed by all modules include ltlinuxkernel. hgt Needed for KERNINFO int initmodule(void) printk(KERNINFO Hello world. n) A non 0 return means initmodule failed module cant be loaded. return 0 void cleanupmodule(void) printk(KERNINFO Goodbye world. n) We need to compile this module, so we need a Makefile: all: make - C libmodules(shell uname - r)build M(PWD) modules clean: make - C libmodules(shell uname - r)build M(PWD) clean Now, we need to make the module. In the directory containing your hello. c program and the Makefile, just run make. You will see something like this: Our module has been compiled. Lets insert it into the kernel. This is done using the insmod command. However, a second before we do that, we can examine our module and see what it does. Maybe the module advertises certain bits of information that we might find of value. Use the modinfo command for that. In this case, nothing special. Now, insert it: If the module loads properly into the kernel, you will be able to see it with the lsmod command: sbinlsmod grep hello Notice that the use count for our module is 0. This means that we can unload it from the kernel without causing a problem. Normally, kernel modules are used for various purposes, like communicating with system devices. Finally, to remove the module, use the rmmod command: If you take at a look at varlogmessages, you will notice the Hello and Goodbye messages, belonging to the initmodule and cleanupmodule functions: That was our most trivial example. No crash yet. But we have a mechanism of inserting code into the kernel. If the code is bad, we will have an oops or a panic. Step 2: Kernel panic Well now create a new C program that uses the panic system call on initialization. Not very useful, but good enough for demonstrating the power of crash analysis. Heres the code, we call it kill-kernel. c. kill-kernel. c - The simplest kernel module to crash kernel. include ltlinuxmodule. hgt Needed by all modules include ltlinuxkernel. hgt Needed for KERNINFO int initmodule(void) printk(KERNINFO Hello world. Now we crash. n) panic(Down we go, panic called) void cleanupmodule(void) printk(KERNINFO Goodbye world. n) When inserted, this module will write a message to varlogmessages and then panic. Indeed, this is what happens. Once you execute the insmod command, the machine will freeze, reboot, dump the kernel memory and then reboot back into the production kernel. Step 3: Analysis Lets take a look at the vmcore. And the backtrace: What do we have here First, the interesting bit, the PANIC string: Kernel panic - not syncing: Down we go, panic called That bit looks familiar. Indeed, this is our own message we used on panic. Very informative, as we know what happened. We might use something like this if we encountered an error in the code, to let know the user what the problem is. Another interesting piece is the dumping of the CS register - CS: 0033. Seemingly, we crashed the kernel in user mode. As Ive mentioned before, this can happen if you have hardware problems or if theres a problem with a system call. In our case, its the latter. Well, that was easy - and self-explanatory. So, lets try a more difficult example. For more information about writing kernel modules, including benevolent purposes, please consult the Linux Kernel Module Programming Guide. Difficult example Now another, a more difficult example. We panicked our kernel with. panic. Now, lets try some coding malpractice and create a NULL pointer testcase. Weve seen earlier how to create a kernel module. Now, lets spice up our code. We will now create a classic NULL pointer example, the most typical problem with programs. NULL pointers can lead to all kinds of unexpected behavior, including kernel crashes. Our program, called null-pointer. c. now looks like this: null-pointer. c - A not so simple kernel module to crash kernel. include ltlinuxmodule. hgt Needed by all modules include ltlinuxkernel. hgt Needed for KERNINFO int initmodule(void) printk(KERNINFO We is gonna KABOOM nown) void cleanupmodule(void) printk(KERNINFO Goodbye world. n) We declare a NULL pointer and then dereference it. Not a healthy practice. I guess programmers can explain this more eloquently than I, but you cant have something pointing to nothing get a valid address of a sudden. In kernel, this leads to panic. Indeed, after making this module and trying to insert it, we get panic. Now, the sweet part. Step 1: Analysis Looking at the crash report, we see a goldmine of information: Lets digest the stuff: PANIC: Oops: 0002 1 SMP (check log for details) We have an Oops on CPU 1. 0002 translates to 0010 in binary, meaning no page was found during a write operation in kernel mode. Exactly what were trying to achieve. Were also referred to the log. More about that soon. WARNING: panic task not found There was no task, because we were just trying to load the module, so it died before it could run. In this case, we will need to refer to the log for details. This is done by running log in the crash utility, just as weve learned. The log provides us with what we need: The RIP says nullpointer:initmodule0x190x22. Were making progress here. We know there was a problem with NULL pointer in the initmodule function. Time to disassemble the object and see what went wrong. Theres more useful information, including the fact the kernel was Tainted by our module, the dumping of the CS register and more. Well use this later. First, lets objdump our module. objdump - d - S null-pointer. ko gt tmpwhatever Looking at the file, we see the Rain Man code: The first part, the cleanup is not really interesting. We want the initmodule. The problematic line is even marked for us with a comment: 27 ltinitmodule0x19gt. 27: c6 00 01 movb 0x1,(rax) What do we have here Were trying to load (assembly movb ) value 1 ( 0x1 ) into the RAX register ( rax ). Now, why does it cause such a fuss Lets go back to our log and see the memory address of the RAX register: RAX register is: 0000000000000000. In other words, zero. Were trying to write to memory address 0. This causes the page fault, resulting in kernel panic. Problem solved Of course, in real life, nothing is going to be THAT easy, but its a start. In real life, you will face tons of difficulties, including missing sources, wrong versions of GCC and all kinds of problems that will make crash analysis very, very difficult. Remember that For more information, please take a look at the case study shown in the crash White Paper. Again, its easier when you know what youre looking for. Any example you encounter online will be several orders of magnitude simpler than your real crashes, but it is really difficult demonstrating an all-inclusive, abstract case. Still, I hope my two examples are thorough enough to get you started. Alternative solution (debug kernel) If you have time and space, you may want to download and install a debug kernel for your kernel release. Not for everyday use, of course, but it could come handy when youre analyzing kernel crashes. While it is big and bloated, it may offer additional, useful information that cant be derived from standard kernels. Plus, the objects with debug symbols might be there, so you wont need to recompile them, just dump them and examine the code. Next steps So the big question is, what do crash reports tell us Well, using the available information, we can try to understand what is happening on our troubled systems. First and foremost, we can compare different crashes and try to understand if theres any common element. Then, we can try to look for correlations between separate events, environment changes and system changes, trying to isolate possible culprits to our crashes. Combined with submitting crash reports to vendors and developers, plus the ample use of Google and additional resources, like mailing lists and forums, we might be able to narrow down our search and greatly simply the resolution of problems. Kernel crash bug reporting When your kernel crashes, you may want to take the initiative and submit the report to the vendor, so that they may examine it and possibly fix a bug. This is a very important thing. You will not only be helping yourself but possibly everyone using Linux anywhere. What more, kernel crashes are valuable. If theres a bug somewhere, the developers will find it and fix it. Kerneloops. org is a website dedicated to collecting and listing kernel crashes across the various kernel releases and crash reasons, allowing kernel developers to work on identifying most critical bugs and solving them, as well as providing system administrators, engineers and enthusiasts with a rich database of crucial information. Remember the Fedora 12 kernel crash report We had that nativeapicwritedummy Well, lets see what kerneloops. org has to say about it. As you can see, quite a lot. Not only do you have all sorts of useful statistics, you can actually click on the exception link and go directly to source, to the problematic bit of code and see what gives. This is truly priceless information As we mentioned earlier, some modern Linux distributions have an automated mechanism for kernel crash submission, both anonymously and using a Bugzilla account. For example, Fedora 12 uses the Automatic Bug Reporting Tool (ABRT), which collects crash data, runs a report and then sends it for analysis with the developers. For more details, you may want to read the Wiki. Beforehand, Fedora 11 used kerneloops utility, which sent reports to, yes, you guessed it right, kerneloops. org. Some screenshots. Heres an example of live submission in Fedora 11. And more recently in Fedora 12. Hopefully, all these submissions help make next releases of Linux kernel and the specific distributions smarter, faster, safer, and more stable. Google for information Sounds trivial, but it is not. If youre having a kernel crash, theres a fair chance someone else saw it too. While environments differ from one another, there still might be some commonality for them all. Then again, there might not. A site with 10 database machines and local logins will probably experience different kinds of problems than a 10,000-machine site with heavy use of autofs and NFS. Similarly, companies working with this or that hardware vendor are more likely to undergo platform-specific issues that cant easily be find elsewhere. The simplest way to search for data is to paste the exception RIP into the search box and look for mailing list threads and forum posts discussing same or similar items. Once again, using the Fedora case an an example: Crash analysis results And after you have exhausted all the available channels, its time to go through the information and data collected and try to reach a decisionresolution about the problem at hand. We started with the situation where our kernel is experiencing instability and is crashing. To solve the problem, we setup a robust infrastructure that includes a mechanism for kernel crash collection and tools for the analysis of dumped memory cores. We now understand what the seemingly cryptic reports mean. The combination of all the lessons learned during our long journey allows us to reach a decision what should be done next. How do we treat our crashing machines Are they in for a hardware inspection, reinstallation, something else Maybe theres a bug in the kernel internals Whatever the reason, we have the tools to handle the problems quickly and efficiently. Finally, some last-minute tips, very generic, very generalized, about what to do next: Single crash A single crash may seem as too little information to work with. Dont be discouraged. If you can, analyze the core yourself or send the core to your vendor support. Theres a fair chance you will find something wrong, either with software at hand, the kernel or the hardware underneath. Hardware inspection Speaking of hardware, kernel crashes can be caused by faulty hardware. Such crashes usually seem sporadic and random in reason. If you encounter a host that is experiencing many crashes, all of which have different panic tasks, you may want to considering scheduling some downtime and running a hardware check on the host, including memtest, CPU stress, disk checks, and more. Beyond the scope of this article, Im afraid. The exact definition of what is considered many crashes, how critical the machine is, how much downtime you can afford, and what you intend to do with the situation at hand is individual and will vary from one admin to another. Reinstallation amp software changes Did the software setup change in any way that correlates with the kernel crashes If so, do you know what the change is Can you reproduce the change and the subsequent crashes on other hosts Sometimes, it can be very simple sometimes, you may not be able to easily separate software from the kernel or the underlying hardware. If you can, try to isolate the changes and see how the system responds with or without them. If theres a software bug, then you might be just lucky enough and have to deal with a reproducible error. Kernel crashes due to a certain bug in software should look pretty much the same. But theres no guarantee youll have it that easy. Now, if your system is a generic machine that does not keep any critical data on local disks, you may want to consider wiping the slate clean - start over, with a fresh installation that you know is stable. Its worth a try. Submit to developervendor Regardless of what you discovered or you think the problem is, you should send the kernel crash report to the relevant developer andor vendor. Even if youre absolutely sure you know what the problem is and youve found the cure, you should still leave the official fix in the hands of people who do this kind of work for a living. I have emphasized this several times throughout the article, because I truly believe this is important, valuable and effective. You can easily contribute to the quality of Linux kernel code by submitting a few short text reports. Its as simple and powerful as that. And that would be all for now, I think. Im spent. I still owe you some information, but I cant possibly include everything in a single article. We will revisit some of the stuff when we discuss gdb. Official documentation Heres a selection of highly useful articles and tutorials:PECAN WEEVIL Where it is found in Texas, the pecan weevil is the most damaging late-season pecan pest. Infestations are often localized and vary greatly within orchards. In August, adult weevils begin to emerge from the soil and feed on nuts in the water stage, causing them to drop. After the kernel has entered the gel stage, the nut is susceptible to egg laying and attack by pecan weevil larvae. Infested nuts remain on the tree while the developing larvae consume the kernel. Full-grown larvae emerge from the nut in late fall or early winter through a round hole chewed through the shell. The life cycle of the pecan weevil egg, larva, pupa and adult usually is completed in 2 years but can require 3. Adult weevils begin emerging from the soil in August their numbers peak from late August through early September. Rainfall, soil moisture and soil type influence the ability of the weevils to emerge from the soil. Drought can delay adult emergence until rain or irrigation loosens the soil. Adult weevils feed on nuts and live for several weeks. Once nuts reach the gel stage, they are suitable for egg laying. For this reason, early-maturing varieties are infested first. The female weevil drills a hole through the shell and deposits one or more eggs within the developing kernel. A single female lays eggs in about 30 nuts. Larvae hatch from the eggs and feed inside the nut, destroying the kernel. Larvae emerge from the nuts about 42 days after the eggs are deposited. Emergence of full-grown larvae from nuts begins in late September and continues as late as December. Larvae burrow 4 to 12 inches into the soil and build a cell, where they remain for 8 to 10 months. Most of the larvae then pupate and transform to the adult stage within a few weeks. However, the adults remain in the underground cell for an additional (second) year before emerging from the soil the following summer. Those larvae (about 10 percent) not pupating after the first year remain as larvae for 2 years and then emerge from the soil as adults the third year. PECAN NUT CASEBEARER - Adult Pecan nut casebearer adults have been collected in pheromone traps in Texas as far north as College Station, TX as of April 19. During this time of year pecan bud moth adults occasionally are collected in PNC pheromone traps. Proper identification of PNC adults is important for determining scouting time. PNC adults have a ridge of scales that sticks up that appears as a band across the forewings approximately 13 the distance from where the wings attach to the body. This is a key identification character for PNC. The picture shows a PNC adult on the left and a pecan bud moth adult on the right. Pecan Nut Casebearer - Egg Female casebearer adults will deposit singular eggs on the stigma end of small nutlets. Oviposition or egg lay will begin 7 and 10 days after the initia l catch of adults in pheromone traps. New eggs are a pearly white color but as eggs mature, red spots will form and the egg will take on a pink or red color prior to hatch. Time from egg lay to larval hatch is 3 to 5 days. STINK BUGS AND LEAFFOOTED BUGS Several species of stink bugs and leaffooted bugs feed on pecan nuts. Infestations often develop on field crops or weeds and then move into pecans. Stink bugs and leaffooted bugs suck sap from developing nuts. Nuts injured before the shells harden fall from the tree. Feeding after shell hardening causes brown or black spots on the kernel. Affected areas taste bitter. As adults, these bugs overwinter under fallen leaves and in other sheltered places on the ground. Adults lay eggs on many crops and weeds, where populations increase in summer. Fields of soybeans, other legumes and sorghum may be sources of adults that fly to pecans. Infestations are usually greatest from September through shuck split. Weed control in and near the orchard helps suppress stink bugs and lower the possibility of their moving into pecans. Cypermethrin (Ammo reg. Cymbush reg ), esfenvalerate (Asana reg. azinphosmethyl (Guthion reg ) or carbaryl (Sevin reg ) applied for other pests may also control stink bugs and leaffooted bugs. These kernel-feeding insects can also be managed by planting certain host or trap crops, which lure adult stink bugs and leaffooted bugs away from pecans in September, October and November. Planting plots or single rows of peas (blackeye, purple hull, crowder, etc.) along the edge of the pecan orchard in the last week of July through the first week of August produces an attractive trap crop for these pests. The trap crop does not have to be continuous around the entire orchard. Small plantings in several selected locations can be enough. To help ensure having an attractive trap crop longer into the fall, stagger the plantings by a couple of weeks. Monitor the peas for adult leaffooted and stink bugs when the plants begin to bloom and set pods. Apply an insecticide to the trap crop to kill stink b ugs and leaffooted bugs once the crop stops blooming and setting pods. This treatment is necessary to kill the bugs before they have a chance to leave and fly into the pecans. Before planting a trap crop, consider these factors: having available water to obtain a stand planting a variety of pea suited to the soil type and soil pH of the orchard weed control and grazing of plots by wildlife and livestock. High populations on nut clusters can result in nut loss. Currently there are no well defined guidelines for treatment thresholds. Provado reg is a selective insecticide for sucking insects and could be used to treat spittle bugs and not disrupt beneficial insects. HICKORY SHUCKWORM . Hickory shuckworm is an important mid - and late-season pest of pecans throughout much of Texas. Shuckworm larvae tunnel in the shuck, interrupting the flow of nutrients and water needed for normal kernel development. Infested nuts are scarred, late in maturing and of poor quality. Damaged shucks stick to the nuts and fail to open, creating sticktights that reduce harvesting efficiency. Infestations occurring before shell hardening may cause nuts to fall. Adult shuckworms are dark brown to grayish-black moths about 38 inch long. They are active in spring before pecan nuts are available. Adults deposit eggs on hickory nuts and pecan buds. Larvae on pecan feed in phylloxera galls in spring. Later in the season when pecan nuts are present, moths deposit eggs singly on the nuts. The egg is attached to the shuck with a creamy white substance visible on the shuck surface. The tiny larva hatches in a few days and burrows into the shuck to feed for about 15 to 20 days. Mature larvae are about 12 inch long, and cream colored with light brown heads. Pupation occurs in the shuck and the moth soon emerges. Several generations are completed each year. Shuckworms overwinter as full-grown larvae in old pecan shucks on the tree or the orchard floor. Pecans are most susceptible to hickory shuck-worm damage during the water through gel stages. If the orchard has a history of shuckworm damage, treat with insecticide when pecans reach the half-shell hardening stage. Asecond application 10 to 14 days later may be needed. Cultivars such as Pawnee and other early-maturing varieties that reach half-shell hardening earlier than other varieties must be treated earlier for hickory shuckworm. Removing and destroying old shucks and dropped nuts, where shuckworms overwinter, can reduce shuckworm infestations. Pheromone traps are available that attract and capture hickory shuckworm moths. Guidelines for using trap catches to determine the need for treatment have not been validated in Texas. RED IMPORTED FIRE ANT Fire ants can lower pecan production when they interfere with such operations as grafting, mowing and harvesting. They also may damage drip or sprinkler irrigation systems. Chlorpyrifos (Lorsban reg ) is registered for use in pecan orchards as an orchard floor spray for fire ants. Logic Fire Ant Bait reg is registered for use only in nonbearing pecan orchards. BLACK PECAN APHID The black pecan aphid is much more destructive than the two species of yellow aphid. Three black pecan aphids per compound leaf can cause severe leaf damage and defoliation. Like yellow aphids, the black pecan aphid feeds on the undersides of leaves and occurs throughout the pecan growing region of Texas. While feeding, black pecan aphids inject a toxin that turns the leaf tissue between major veins bright yellow. These damaged areas, up to 14 inch across, turn brown and die. Infested leaves soon fall. Premature defoliation reduces nut fill and the next yearOtildes production. The black pecan aphid is pear-shaped. Nymphs are dark olive-green while adults, which may be winged, are black. Like yellow aphids, all summer forms are females that reproduce without mating. Male and female forms appear in fall and females lay eggs that overwinter on branches. Densities often are very low until August or September, when infestations often increase rapidly. Monitor the orchard frequently for black pecan aphids and their characteristic leaf injury. Because these aphids feed singly and can be damaging in low numbers, examine leaves closely. Examine the interior of the canopy, where infestation often begins. In general, treat when black pecan aphids average two to three per compound leaf. In most cases, black pecan aphids are easier than yellow aphids to control with insecticides. Natural enemies are important in maintaining low numbers of black pecan aphids. YELLOW APHIDS Aphids are small, soft-bodied insects that suck sap from pecan leaves. There are two species of yellow or honeydew aphids, the blackmargined aphid, Monellia caryella. and the yellow pecan aphid, Monelliopsis pecanis. The blackmargined aphid has a black stripe along the outside margin of its wings, which are held flat over the body. The yellow pecan aphid holds its wings roof-like over its body and lacks the black stripe along the wing margin. Immature aphids are difficult to identify because they lack wings. Infestations may contain both species. Blackmargined aphid infestations typically increase to large numbers during June to August and then decline after about 3 weeks. Outbreaks on most cultivars (except possibly Cheyenne) usually decline without causing measurable damage to foliage or yield. The yellow pecan aphid occurs later in the season. Outbreaks of this species can cause defoliation and reduce yield and quality on most cultivars. Both species of yellow aphids have piercingsucking mouthparts for removing water and plant nutrients from leaf veins. As they feed, aphids excrete large amounts of excess sugars. This sticky material, called honeydew, collects on leaves. Honeydew serves as a food source for sooty mold, which can cover leaves when humidity is high. The shading effect of sooty mold can reduce photosynthesis. Studies have also shown that aphid feeding can reduce leaf efficiency large, persistent infestations of the yellow pecan aphid, M. pecanis, can defoliate trees. This leaf injury and loss can reduce current and subsequent yields and quality because of lower carbohydrate production. Yellow aphid eggs survive the winter hidden in bark crevices on twigs and tree trunks. Immature aphids, called nymphs, hatch from eggs in spring and begin to feed on newly expanded leaves. Nymphs mature in about a week and give birth to live young. All individuals are females that reproduce without males during spring and summer. In late September and October, males and females develop, and females deposit overwintering eggs. Control. Aphids have a short life cycle and high reproductive capacity, so infestations can increase quickly under favorable conditions. Natural enemies, including lacewings, lady beetles, spiders and other insects, can suppress aphid infestations if there are enough of them. Insecticides applied for aphids or other pests can sometimes destroy these natural enemies, allowing aphids to increase to even greater densities than before treatment. Inspect leaves frequently to monitor yellow aphid densities. Treatment of either species of yellow aphid may be justified on Cheyenne when aphid densities are high and persist for several weeks. Pawnee is the least susceptible cultivar to yellow aphids and normally needs no protection with insecticides. Consider treatment when infestations of yellow pecan aphid exceed 25 per compound leaf, indicating the onset of an outbreak. Scouting the orchard on a 4- to 5-day schedule will determine if yellow pecan aphid numbers are increasing or decreasing and indicate the need for insecticide treatment. Do not base the need for treatment on the amount of honeydew alone, as infestations often decline rapidly (crash) because of weather or physiological effects. Insecticides do not consistently control either species of yellow aphids. Aphids may become tolerant to an insecticide used frequently in an orchard. An insecticide that is effective in one orchard may be ineffective in a nearby orchard. Studies have shown that in some cases, applications of pyrethroid insecticides (Asana reg. Ammo reg. Cymbush reg ) to control casebearers or aphids may be followed by large increases in yellow aphids. PECAN PHYLLOXERA : Feeding by the immature stages of the pecan phylloxera, Phylloxera devastatrix causes galls or knots to form on the woody portion of the new growth. This includes stems, leaf petioles and midribs, nutlets and catkins. Heavy infestations of this insect can cause nut loss and defoliation. The immature stage hatches from eggs in the spring that have overwintered on the tree. The immatures, also known as stem mothers migrate to the new growth where they settle and begin to feed. As the phylloxera feed, gall formation is initiated with tissue forming around the insect. If an insecticide is needed, it should be applied before the immatures become embedded in the new tissue. Insecticides only need to be applied to a tree if a tree had galls the previous season. The time of treatments should be when the foliage is at the stage shown in the picture. Recommended insecticides can be found in the Texas Agricultural Extension Service publication Managing Insect and Mite Pests of Commercial Pecans in Texas B-1238. Since the last printing of the pecan insect control guide, the insecticide imidacloprid, (Provado 1.6F or Admire 2F) has received a label for pecans. Provado 1.6F, the formulation for foliar application has provided good control of phylloxera. In addition, this product does not have a grazing restriction. SAWFLY Adult sawflies are small, bee-like in appearance and are about 14 to 13 inch long. Larvae feed on foliage and leave holes in the leaves or consume the whole leaf. Sawfly larvae resemble caterpillars but are actually larvae of a wasp. Larvae of moths and butterflies have 1 to 4 sets of abdominal prolegs, whereas sawfly larvae have 6 sets. Once larvae finish feeding, they drop to the ground and burrow into the soil to overwinter. There is only one generation per year. FALL WEBWORM . Fall webworm caterpillars build large silken webs in pecan trees. A hundred or more caterpillars may be found inside the web, where they feed on pecan leaves. Large infestations may cover the tree with webs, causing severe defoliation. Mature larvae are about 1 inch long, pale yellow or green, and covered with tufts of long, white hairs. The adult is a white moth with dark spots on the wings. Female moths emerge in spring and deposit eggs in masses of several hundred on the undersides of pecan and other tree leaves. The greenish-white eggs are covered by gray hairs left by the female. There are two to four generations each year, depending on location in the state. The last or fall generation is usually the most damaging. Many insect parasites and predators feed on and reduce the number of fall webworm larvae. Also, insecticides applied for other pecan pests help reduce webworm densities. If webs are common and the potential defoliation appears unacceptable, spot spraying of infested trees may be practical. The insecticide spray must penetrate the web to be effective. WALNUT CATERPILLAR . Walnut caterpillars feed together in large numbers on pecan leaves, but do not build silken webs like fall webworms. Larvae eat leaves, leaving only the mid-ribs and leaf stems. Large infestations can defoliate entire trees. This insect is found throughout Texas east of the Pecos River. Although economic infestations are uncommon, severe and widespread outbreaks of walnut caterpillar have occasionally occurred in Texas. Walnut caterpillar moths emerge in spring, de-positing eggs in masses of 500 or more on the undersides of leaves. The egg masses are round, about the size of a half-dollar and are not covered with hairs or scales. Eggs hatch in about 10 days larvae feed for about 25 days. Young larvae are reddish-brown with yellow lines running the length of the body. Full-grown larvae are about 2 inches long, black with grayish lines and are covered with long, soft, gray hairs. Larvae congregate in large masses on the trunk and scaffold branches to shed their skins before crawling back to complete feeding on leaves. These final-stage larvae consume most of the foliage, and defoliation can occur very quickly. Mature larvae crawl to the soil to pupate. A generation is completed in about 6 to 8 weeks. There are two to three generations each year. Because walnut caterpillars do not build tents or webs, infestations often go unnoticed until leaf damage becomes obvious. To detect infestations early, look for egg masses or leaf feeding. Egg masses can be detected at night by shining a flashlight on the undersides of leaves and looking for white spots about the size of a half dollar. SPIDER MITES . The pecan leaf scorch mite is the most important spider mite attacking pecans. Large numbers of these tiny mites feed on the undersides of pecan leaves. Mites suck plant sap, causing irregular brown spots on infested leaves. Infestations often develop first along the leaf midrib. Damaged leaves appear russeted or scorched. Large infestations can result in leaf loss, especially if trees are under moisture stress. Scorch mites overwinter as adults in the rough bark of limbs. Adult females begin laying eggs in spring. Mites can complete a generation in 5 to 15 days and are more numerous during hot, dry weather. Natural enemies of scorch mites, including predatory mite species, are important in controlling these pests. Because scorch mites prefer the shady, interior portion of the tree, significant damage can occur before infestations are detected. Check water sprouts and shady, lower branches to detect early mite infestations. Mites may increase after some insecticides (e. g. Sevin reg ) are applied for hickory shuckworm, aphids or other pests. Monitor the orchard for mites when the weather is hot and dry and after insecticides are used. Spray when mites are present and damaging leaves. Mark infested trees or areas to determine if spot treatment is practical. ASIAN AMBROSIA BEETLE Infestations of the Asian ambrosia beetle can be identified by the toothpick-like projections from the trunk or the main scaffold limbs. Infested trees should be removed and surrounding trees should be treated with lindane or chlorpyrifos (Lorsban reg). This is an early season pest with most infestations observed in April or May. Infested trees should be burned or shredded to prevent the adults from from emerging from the wood.

No comments:

Post a Comment