Movendo Média Kernel
MOVING FORTH Parte 1: Decisões de Design no Forth Kernel por Brad Rodriguez Este artigo apareceu pela primeira vez em The Computer Journal 59 (janeiro de fevereiro de 1993). INTRODUÇÃO Todo mundo na comunidade Forth fala sobre como é fácil para portar Forth para uma nova CPU. Assim, quando Bill Kibler sugeriu este tópico para um artigo, eu decidi quebrar com a grande tradição oral de Forthwrights, e documentar o processo em preto e branco. Ao longo destes artigos vou desenvolver Forths para o 6809, 8051 e Z80. Estou fazendo o 6809 para ilustrar um fácil e convencional Forth modelo plus, Ive já publicou um montador 6809 ROD91, ROD92, e Ill estar precisando de um 6809 Forth para futuros projetos TCJ. Estou fazendo o 8051 Forth para um projeto da Universidade, mas também ilustra algumas decisões de design bastante diferentes. O Z80 Forth é para todos os leitores CPM de TCJ, e para alguns amigos com TRS-80s recolhendo poeira. O HARDWARE ESSENCIAL Você deve escolher uma CPU. Eu não vou aprofundar os méritos de uma CPU sobre outra para Forth, uma vez que uma escolha de CPU geralmente é forçado sobre você por outras considerações. Além disso, o objetivo deste artigo é mostrar como mover Forth para qualquer CPU. Você pode esperar que o usual kernel Forth de 16 bits (veja abaixo) ocupe cerca de 8K bytes de espaço de programa. Para um kernel completo que pode compilar definições Forth, você deve permitir um mínimo de 1K byte de RAM. Para usar o sistema de gerenciamento de blocos Forths para armazenamento em disco, você deve adicionar 3 Kbytes ou mais para buffers. Para um modelo Forth de 32 bits, duplique esses números. Estes são os mínimos para obter um núcleo de Forth em funcionamento. Para executar um aplicativo em seu hardware, você deve aumentar tamanhos PROM e RAM para atender. 16 OU 32 BIT O tamanho da palavra usado por Forth não é necessariamente o mesmo que o da CPU. O menor prático Forth é um modelo de 16 bits, ou seja, um que usa 16 bits inteiros e endereços de 16 bits. A comunidade Forth chama isso de tamanho quotcellquot, uma vez que quotwordquot se refere a uma definição Forth. As CPUs de 8 bits quase invariavelmente suportam Forths de 16 bits. Isso geralmente requer codificação explícita de aritmética de byte duplo, embora algumas CPUs de 8 bits tenham algumas operações de 16 bits. As CPUs de 16 bits geralmente executam Forths de 16 bits, embora as mesmas técnicas de dupla precisão possam ser usadas para gravar um Forth de 32 bits em uma CPU de 16 bits. Pelo menos um Forth de 32 bits foi escrito para o 80868088. As CPUs de 32 bits normalmente executam Forths de 32 bits. Um menor Forth modelo raramente economiza comprimento do código ou tempo do processador. No entanto, eu sei de pelo menos um 16-bit Forth escrito para o 68000. Isso diminui o tamanho do aplicativo de código por um fator de dois, uma vez que as definições de alto nível Forth se tornar uma seqüência de endereços de 16 bits em vez de uma seqüência de 32- Bit endereços. (Isto ficará evidente logo.) A maioria dos 68000s, porém, tem muita RAM. Todos os exemplos descritos neste artigo são Forths de 16 bits em execução em CPUs de 8 bits. A TÉCNICA DE ROSCA quotThreaded codequot é a marca registrada de Forth. Um Forth quotthreadquot é apenas uma lista de endereços de rotinas a serem executadas. Você pode pensar nisso como uma lista de chamadas de sub-rotina, com as instruções CALL removidas. Ao longo dos anos muitas variações de rosqueamento foram concebidas, e qual é melhor depende da CPU e da aplicação. Para tomar uma decisão, você precisa entender como eles funcionam e seus tradeoffs. Indirect Threaded Code (ITC) Esta é a técnica clássica de Thread, usada na Fig-Forth e F83, e descrita na maioria dos livros sobre Forth. Todos os outros esquemas de threading são quotimprovementsquot sobre isso, então você precisa entender ITC para apreciar os outros. Vamos olhar para a definição de uma palavra Forth QUADRADO: Em um típico ITC Forth isso apareceria na memória, como mostrado na Figura 1. (O cabeçalho será discutido em um futuro artigo que detém informações de manutenção usadas para compilação, e não está envolvido em threading .) Assumir SQUARE é encontrado durante a execução de alguma outra palavra Forth. Forths Interpreter O ponteiro (IP) estará apontando para uma célula na memória - contida nessa quototherquot word - que contém o endereço da palavra SQUARE. (Para ser preciso, essa célula contém o endereço do campo de código SQUAREs.) O interpretador obtém esse endereço e, em seguida, usa-o para buscar o conteúdo do campo SQUAREs Code. Estes conteúdos são ainda outro endereço - o endereço de uma sub-rotina de linguagem de máquina que executa a palavra SQUARE. No pseudo-código, isto é: Isto ilustra um princípio importante, mas raramente elucidado: o endereço da palavra Forth inserido é mantido em W. As palavras CODE não precisam desta informação, mas todos os outros tipos de palavras Forth fazem. Se o SQUARE fosse escrito em código de máquina, este seria o fim da história: esse bit de código de máquina seria executado e então salta de volta para o intérprete de Forth - que, como o IP foi incrementado, está apontando para a próxima palavra para ser executado. É por isso que o interpretador Forth é normalmente chamado de NEXT. Mas, SQUARE é uma definição de quotcolonquot de alto nível - contém um quotthreadquot, uma lista de endereços. Para executar essa definição, o interpretador Forth deve ser reiniciado em um novo local: o campo de parâmetro de SQUARE. Naturalmente, a localização antiga dos intérpretes deve ser salva, para retomar a palavra Quototherquot Forth uma vez que SQUARE estiver concluída. Isso é exatamente como uma chamada de subrotina A ação de linguagem de máquina de SQUARE é simplesmente empurrar o IP antigo, definir IP para um novo local, executar o interpretador, e quando SQUARE é feito pop o IP. (Como você pode ver, o IP é o quotprogram counterquot de alto nível Forth.) Isso é chamado DOCOLON ou ENTER em vários Forths: Este fragmento de código idêntico é usado por todas as definições de alto nível (ou seja, rosca) Forth Por isso um ponteiro Para este fragmento de código, não o próprio fragmento, está incluído na definição Forth. Mais de centenas de definições, as economias somam E é por isso que o seu chamado Threading indireto. O quotreturn da subrotina é a palavra EXIT, que é compilada quando Forth vê. EXIT apenas executa uma rotina de linguagem de máquina que faz o seguinte: Caminhe através de um casal de aninhado Forth definições, apenas para garantir-se que isso funciona. Observe as características de ITC: cada palavra Forth tem um campo de código de uma célula. As definições de dois pontos compilam uma célula para cada palavra usada na definição. E o interpretador Forth deve realmente executar uma indireção dupla para obter o endereço do próximo código de máquina para executar (primeiro através de IP, em seguida, através de W). A ITC não é nem a mais pequena nem a mais rápida técnica de rosqueamento. Pode ser o mais simples embora DTC (descrito em seguida) não é realmente mais complexo. Então, por que tantos Forths indireta-threaded Principalmente porque Forths anterior, usado como modelos, foram indiretamente rosqueado. Estes dias, DTC está se tornando mais popular. Então, quando o ITC deve ser usado Das várias técnicas, ITC produz as definições mais limpas e mais elegante - nada, mas endereços. Se você está em sintonia com tais considerações, a ITC pode apelar para você. Se o seu código fiddles ao redor com o interior de definições, a simplicidade ea uniformidade da representação ITC pode melhorar a portabilidade. ITC é o clássico Forth modelo, por isso pode ser preferido para a educação. Finalmente, em CPUs sem instrução de chamada de subrotina - como o 1802 - ITC é muitas vezes mais eficiente do que o DTC. O Código de Rosca Direta (DTC) O Código de Rosca Direta difere do ITC em apenas um aspecto: em vez do Campo de Código contendo o endereço de algum código de máquina, o Campo de Código contém o próprio código de máquina propriamente dito. Im não dizendo que o código completo para ENTER está contido em cada definição de dois pontos Em quothigh-levelquot Forth palavras, o campo de código irá conter uma chamada de sub-rotina. Como mostrado na Figura 2. Colon definições, por exemplo, irá conter uma chamada para a rotina ENTER. O pseudo-código NEXT para rosqueamento direto é simplesmente: Isso ganha velocidade: o interpretador agora executa apenas uma indireção única. No Z80 isso reduz a rotina NEXT - o fragmento de código mais usado no kernel Forth - de onze instruções para sete Este espaço de custos: cada definição de alto nível em um Z80 Forth (por exemplo) é agora um byte mais, Uma vez que um endereço de 2 bytes foi substituído por uma chamada de 3 bytes. Mas isso não é universalmente verdadeiro. A 32 bits 68000 Forth pode substituir um endereço de 4 bytes com uma instrução BSR de 4 bytes, para nenhuma perda líquida. E no Zilog Super8, que tem instruções de máquina para DTC Forth, o endereço de 2 bytes é substituído por uma instrução ENTER de 1 byte, tornando um DTC Forth menor no Super8 Claro que as definições de CODE de DTC são dois bytes mais curtos, uma vez que eles Já não precisa de um ponteiro em tudo Eu costumava pensar que as definições de alto nível no DTC Forths exigido o uso de uma chamada de subrotina no campo de código. Frank Sergeants Pygmy Forth O SER90 demonstra que um salto simples pode ser usado tão facilmente, e geralmente será mais rápido. Guy Kelly compilou uma excelente revisão de implementações Forth para o IBM PC KEL92, que eu recomendo fortemente a todos os escritores do kernel Forth. Das 19 Forths que estudou, 10 utilizaram DTC, 7 utilizaram ITC e 2 usaram sub-rotinas (discutidas a seguir). Eu recomendo o uso de Direct-Threaded Code sobre Indirect-Threaded Code para todos os novos kernels Forth. Ir para NEXT, ou codificar em linha O interpretador interno Forth, NEXT, é uma rotina comum a todas as definições CODE. Você pode manter apenas uma cópia desta rotina comum e ter todas as palavras CODE saltar para ele. (Observe que você pula para NEXT uma chamada de subrotina não é necessária.) No entanto, a velocidade de NEXT é crucial para a velocidade de todo o sistema Forth. Além disso, em muitas CPUs, a rotina NEXT é bastante curta, muitas vezes apenas duas ou três instruções. Portanto, pode ser preferível codificar NEXT in-line, onde quer que seja usado. Isso é feito freqüentemente fazendo NEXT uma macro assembler. Esta é uma simples velocidade contra a decisão de espaço: em linha NEXT é sempre mais rápido, mas quase sempre maior. O aumento de tamanho total é o número de bytes extras necessários para a expansão em linha, vezes o número de palavras CODE no sistema. Às vezes não há nenhuma compensação em tudo: em um 6809 DTC Forth, um NEXT in-line é mais curto do que uma instrução de salto Subroutine Threaded Code (STC) Uma definição de alto nível Forth é nada além de uma lista de sub-rotinas a serem executadas. Você não precisa de intérpretes para fazer isso, você pode obter o mesmo efeito simplesmente encadeando uma lista de chamadas de sub-rotinas juntas: Veja a Figura 3. Esta representação de palavras de Forth foi usada como ponto de partida para explicar as técnicas de threading de Forth aos programadores de linguagem de montagem KOG82. STC é uma representação elegante definições de dois pontos e CODE palavras são agora idênticos. QuotDefined wordsquot (VARIABLEs, CONSTANTs e similares) são tratados da mesma forma que no DTC - o campo de código começa com um salto ou chamada para algum código de máquina em outro lugar. A principal desvantagem é que as chamadas de subrotina são geralmente maiores do que endereços simples. No Z80, por exemplo, o tamanho das definições de dois pontos aumenta em 50 - ea maior parte do seu aplicativo é duas definições de dois pontos. Em um 32000 de 68 bits, pode haver nenhum aumento de tamanho, quando os endereços de 4 bytes são substituídos por BSRs de 4 bytes. (Mas se o tamanho do código exceder 64K, alguns desses endereços devem ser substituídos por JSRs de 6 bytes.) O sub-roteiro de sub-rotinas pode ser mais rápido do que o encadeamento direto. Você economiza tempo por não ter um intérprete, mas você perde tempo porque cada referência a uma palavra Forth envolve um empurrão e pop de um endereço de retorno. Em um DTC Forth, somente palavras de alto nível causam atividade na pilha de retorno. No 6809 ou Zilog Super8, DTC é mais rápido do que STC. Há outra vantagem para STC: dispensa o registro de IP. Alguns processadores - como o 8051 - estão desesperadamente curtos de endereçar registradores. Eliminar o IP pode realmente simplificar e acelerar o kernel A única maneira de saber com certeza é escrever código de exemplo. Isso está intimamente envolvido com a seleção do registro, discutida na próxima seção. STC com compilação direta de otimização de expansão em linha Em CPUs mais antigos e de 8 bits, quase todos os primitivos Forth envolvem várias instruções da máquina. Mas em CPUs mais potentes, muitas primitivas Forth são escritas em uma única instrução. Por exemplo, no 68000 de 32 bits, DROP é simplesmente Em um sub-rotina Forth, usando DROP em uma definição de dois pontos resultaria na seqüência ADDQ é uma instrução de dois bytes. Por que escrever uma chamada de sub-rotina de quatro bytes para uma instrução de dois bytes Não importa quantas vezes DROP é usado, não há economias O código é menor e mais rápido se o ADDQ é codificado diretamente no fluxo de BSRs. Alguns compiladores Forth fazer este quotin-line expansionquot de CODE palavras CUR93a. A desvantagem da expansão em linha é que a descompilação de volta ao código fonte original torna-se muito difícil. Contanto que as chamadas de sub-rotina sejam usadas, você ainda tem ponteiros (os endereços de sub-rotina) para as palavras de Forth que compõem o segmento. Com ponteiros para as palavras, você pode obter seus nomes. Mas uma vez que uma palavra é expandida em código em linha, todo o conhecimento de onde esse código veio é perdido. A vantagem da expansão in-line - além da velocidade e tamanho - é o potencial de otimização de código. Por exemplo, a seqüência Forth seria compilada em 68000 STC como mas poderia ser expandida em linha como uma única instrução de máquina Otimizando Forth compiladores é um tópico muito amplo para este artigo. Esta é uma área ativa da pesquisa de linguagem Forth ver, por exemplo, SCO89 e CUR93b. O culminar final de STC otimizado é um Forth que compila para quotpurequot código de máquina, assim como um compilador C ou Fortran. Token Threaded Code (TTC) O DTC eo STC visam melhorar a velocidade dos programas Forth, com algum custo na memória. Agora vamos mover a outra direção do ITC, em direção a algo mais lento, mas menor. A finalidade de um segmento Forth é especificar uma lista de Forth palavras (subrotinas) a ser executada. Suponha que um sistema Forth de 16 bits tivesse apenas um máximo de 256 palavras diferentes. Então, cada palavra poderia ser identificada exclusivamente por um número de 8 bits. Em vez de uma lista de endereços de 16 bits, você teria uma lista de identificadores de 8 bits ou quottokens, quot eo tamanho das definições de dois pontos seria reduzido pela metade Um Forth de thread de token mantém uma tabela de endereços de todas as palavras de Forth, como Mostrado na Figura 4. O valor token é então usado para indexar nesta tabela, para encontrar a Forth palavra correspondente a um token dado. Isso adiciona um nível de indireção ao interpretador Forth, portanto é mais lento que um quotaddress-threadedquot Forth. A principal vantagem do token-threaded Forths é de tamanho pequeno. O TTC é mais comumente visto em computadores portáteis e outras aplicações de tamanho severo. Além disso, a tabela de quotentry pointsquot em todas as palavras Forth pode simplificar linkage de módulos compilados separadamente. A desvantagem de TTC é velocidade: TTC faz o mais lento Forths. Além disso, o compilador TTC é um pouco mais complexo. Se você precisar de mais de 256 palavras Forth, é necessário ter algum esquema de codificação open-ended para misturar tokens de 8 bits e maiores. Eu posso imaginar um Forth de 32 bits usando tokens de 16 bits, mas quantos sistemas de 32 bits são limitados de tamanho Segmento Código Threaded Já que existem tantos 8086 derivados no mundo, segmento segmentação merece uma breve menção. Em vez de usar endereços de bytes quotnormalquot dentro de um segmento de 64 K, endereços de parágrafo são usados. (Um quotparagraphquot é 16 bytes no 8086.) Em seguida, o interpretador pode carregar esses endereços em registros de segmento, em vez de nos registros de endereço usual. Isso permite que um 16-bit modelo Forth para acessar eficientemente o megabyte completo da memória 8086. A principal desvantagem do segmento segmento é o 16-byte quotgranularityquot do espaço de memória. Cada palavra Forth deve ser alinhada com um limite de 16 bytes. Se Forth palavras têm comprimentos aleatórios, uma média de 8 bytes será desperdiçado por palavra Forth. REGISTRAR ATRIBUIÇÃO Ao lado da técnica de rosca, o uso dos registros de CPUs é a decisão de projeto mais crucial. É provavelmente o mais difícil. A disponibilidade de registros de CPU pode determinar qual técnica de rosca pode ser usada e até mesmo o que o mapa de memória será. Os registros clássicos de Forth O modelo clássico de Forth tem cinco registros quotvirtual. Estas são entidades abstratas que são usadas nas operações primitivas de Forth. NEXT, ENTER e EXIT foram definidos anteriormente em termos desses registros abstratos. Cada um deles é uma célula de largura - ou seja, em um 16-bit Forth, estes são 16-bit registradores. (Existem exceções a esta regra, como você verá mais tarde.) Esses não podem ser todos os registradores da CPU. Se a sua CPU não tem registros suficientes, alguns deles podem ser mantidos na memória. Ill descrevê-los na ordem de sua importância, ou seja, o fundo desta lista são os melhores candidatos para serem armazenados na memória. W é o registro de trabalho. Ele é usado para muitas coisas, incluindo a referência de memória, por isso deve ser um registro de endereço, ou seja, você deve ser capaz de buscar e armazenar memória usando o conteúdo de W como o endereço. Você também precisa ser capaz de fazer aritmética em W. (Em DTC Forths, você também deve ser capaz de saltar indiretamente usando W.) W é usado pelo intérprete em cada palavra Forth. Em uma CPU com apenas um registro, você usaria para W e manteria tudo o resto na memória (eo sistema seria incrivelmente lento). IP é o interpretador ponteiro. Isso é usado por cada palavra Forth (através de NEXT, ENTER ou EXIT). IP deve ser um registro de endereço. Você também precisa ser capaz de incrementar o IP. Subrutina threaded Forths não precisa deste registo. PSP é o apontador de parâmetro (ou quotdata stackquot) ponteiro, às vezes chamado simplesmente SP. Eu prefiro PSP porque SP é freqüentemente o nome de um registro de CPU, e eles shouldnt ser confundido. A maioria das palavras CODE usa isso. PSP deve ser um ponteiro de pilha, ou um registro de endereço que pode ser incrementado e diminuído. É também um plus se você pode fazer o endereçamento indexado de PSP. RSP é o ponteiro de pilha de retorno, às vezes chamado simplesmente RP. Isso é usado por definições de dois pontos em ITC e DTC Forths, e por todas as palavras em STC Forths. RSP deve ser um ponteiro de pilha, ou um registro de endereço que pode ser incrementado e diminuído. Se tudo for possível . Colocar W, IP, PSP e RSP em registros. Os registos virtuais que se seguem podem ser mantidos na memória, mas normalmente existe uma vantagem de velocidade para os manter nos registos da CPU. X é um registro de trabalho, não considerado um dos registros quotclassical Quest Forth, embora o clássico ITC Forths precisa dele para a segunda indireção. No ITC você deve ser capaz de saltar indiretamente usando X. X também pode ser usado por algumas palavras CODE para fazer aritmética e tal. Isso é particularmente importante em processadores que não podem usar a memória como um operando. Por exemplo, ADD em um Z80 pode ser (em pseudo-código) Às vezes, outro registro de trabalho, Y, também é definido. UP é o ponteiro do usuário, mantendo o endereço base da área de usuário de tarefas. UP é geralmente adicionado a um deslocamento e usado pelo código Forth de alto nível, portanto, ele pode ser armazenado em algum lugar. Mas se a CPU pode fazer endereçamento indexado a partir do registro UP, as palavras CODE podem acessar as variáveis do usuário com mais facilidade e rapidez. Se você tiver um excesso de registros de endereços, use um para UP. Forths de uma única tarefa não precisa UP. X - se necessário - é mais importante manter-se em registro do que UP. UP é o mais fácil dos registros virtuais Forth para mover na memória. Uso da pilha de hardware A maioria das CPUs tem um ponteiro de pilha como parte de seu hardware, usado por interrupções e chamadas de subrotina. Como é que este mapa para os registros Forth Deve ser o PSP ou o RSP A resposta curta é, depende. Diz-se que o PSP é usado mais do que o RSP em ITC e DTC Forths. Se a CPU tiver poucos registos de endereços e PUSH e POP forem mais rápidos do que referência explícita, utilize a pilha de hardware como a Pilha de Parâmetros. Por outro lado, se sua CPU é rica em modos de endereçamento - e permite endereçamento indexado - há um plus em ter o PSP como um registro de endereço de propósito geral. Nesse caso, use a pilha de hardware como a pilha de retorno. Às vezes você não faz nem A pilha de hardware TMS320C25s é apenas oito células de profundidade - tudo, mas inútil para Forth. Portanto, sua pilha de hardware é usada apenas para interrupções, e tanto o PSP como o RSP são registros de endereços de uso geral. (ANS Forth especifica um mínimo de 32 células de Parameter Stack e 24 células de Return Stack Eu prefiro 64 células de cada). Você ocasionalmente encontrará o dogma que a pilha de hardware deve ser a Parâmetro Stack, ou deve ser a pilha de retorno. Em vez disso, codifique algumas primitivas Forth de exemplo, como e veja qual abordagem é menor ou mais rápida. (DUP e DROP, por sinal, não são nenhum teste - theyre geralmente trivial.) Ocasionalmente você chegar a estranhas conclusões Gary Bergstrom salientou que um 6809 DTC Forth pode ser feito alguns ciclos mais rápido usando o ponteiro de usuário 6809 ponteiro como o IP NEXT se torna um POP. Ele usa um registrador de índice para uma das pilhas de Forths. Top-Of-Stack no registro Forths desempenho pode ser melhorado consideravelmente, mantendo o elemento superior da pilha de parâmetros em um registro muitas palavras Forth (como 0), então não precisa usar a pilha. Outras palavras ainda fazem o mesmo número de push e pops, apenas em um lugar diferente no código. Apenas algumas poucas palavras (DROP e 2DROP) se tornam mais complicadas, já que você não pode mais simplesmente ajustar o ponteiro da pilha - você também precisa atualizar o registro TOS. Há algumas regras ao escrever palavras CODE: Uma palavra que remove itens da pilha deve pop os TOS quotnewquot em seu registro. Uma palavra que adiciona itens à pilha deve empurrar os TOS quotoldquot para a pilha (a menos que, naturalmente, seu consumido pela palavra). Se você tiver pelo menos seis registradores de CPU de tamanho de célula, eu recomendo manter os TOS em um registro. Eu considero TOS mais importante do que UP para ter em registro, mas menos importante do que W, IP, PSP e RSP. (TOS no registro executa muitas das funções do registrador de X.) É útil se este registro pode executar o endereçamento de memória. PDP-11s, Z8s e 68000s são bons candidatos. Nove dos 19 IBM PC Forths estudados por Guy Kelly KEL92 manter TOS em registro. Eu acho que essa inovação tem sido resistida por causa das crenças falsas de que a) ele adiciona instruções, eb) o elemento top stack deve ser acessível como memória. Acontece que mesmo palavras como PICK, ROLL e DEPTH são trivialmente modificadas para TOS-in-register. E quanto a armazenar em buffer dois elementos de pilha em registros Quando você mantém o topo da pilha em um registro, o número total de operações executadas permanece essencialmente o mesmo. Um empurrão continua sendo um empurrão, independentemente de ser antes ou depois da operação que você está executando. Por outro lado, o buffer de dois elementos de pilha em registos adiciona um grande número de instruções - um empurrão torna-se um empurrão seguido de um movimento. Somente os processadores Forth dedicados como o RTX2000 e os compiladores de otimização inteligentes são capazes de se beneficiar do armazenamento em buffer de dois elementos de pilha em registradores. Alguns exemplos Aqui estão as atribuições de registro feitas por Forths para um número de CPUs diferentes. Tente deduzir as decisões de design dos autores desta lista. QuotSPquot refere-se ao ponteiro de pilha de hardware. QuotZpagequot refere-se a valores mantidos na página de memória 6502s zero, que são quase tão úteis como - às vezes mais úteis do que - valores mantidos em registradores, por exemplo. Eles podem ser usados para endereçamento de memória. QuotFixedquot significa que Paynes 8051 Forth tem uma única área de usuário imóvel, e UP é uma constante codificada. Registros estreitos Observe qualquer coisa estranha na lista anterior O 6502 Forth - um modelo de 16 bits - usa ponteiros de 8 bits É possível fazer PSP, RSP e UP menor do que o tamanho da célula do Forth. Isso ocorre porque as pilhas ea área do usuário são áreas relativamente pequenas de memória. Cada pilha pode ser tão pequena quanto 64 células de comprimento, ea área do usuário raramente excede 128 células. Você simplesmente precisa garantir que a) essas áreas de dados estão confinadas a uma pequena área de memória, então um endereço curto pode ser usado, ou b) os bits de endereço alto são fornecidos de alguma outra forma, p. Uma página de memória. No 6502, a pilha de hardware está confinada à página um de RAM (endereços 01xxh) pelo design da CPU. O ponteiro de 8 bits da pilha pode ser usado para a pilha de retorno. A pilha de parâmetros é mantida na página zero de RAM, que pode ser acessada indiretamente pelo registrador de índice de 8 bits X. (Pergunta para o aluno avançado: por que usar o 6502s X, e não Y Dica: veja os modos de endereçamento disponíveis. ) No 8051, você pode usar os registradores de 8 bits R0 e R1 para endereçar a RAM externa, desde que você explicitamente a saída de alta 8 bits de endereço para a porta 2. Isso permite que um quotpage selectquot para duas pilhas. UP é diferente de PSP e RSP: ele simplesmente fornece um endereço base que nunca é incrementado ou diminuído. Portanto, é prático fornecer somente os bits altos desse registro virtual. Os bits baixos devem então ser fornecidos por qualquer técnica de endereçamento indexada. Por exemplo, no 6809, você pode usar o registro DP para manter os 8 bits altos de UP e, em seguida, usar endereçamento de página direta para acessar qualquer um dos 256 locais nesta página. Isso força todas as áreas de usuário para começar em um endereço xx00h, que não é grande dificuldade e limita a área de usuário para 128 células de comprimento. No 8086 você poderia usar um registro de segmento para especificar o endereço base da área do usuário. REFERÊNCIAS CUR93a Curley, Charles, quotLife na FastForth Lane, aguardando publicação em Forth Dimensions. Descrição de um 68000 subroutine-threaded Forth. CUR93b Curley, Charles, quotOptimizing em um BSRJSR Threaded Forth, que aguarda publicação em Forth Dimensions. Otimização de código de passagem única para FastForth, em apenas cinco telas de código Inclui listagem. KEL92 Kelly, Guy M. comparações de Sistemas de Forth, quot Forth Dimensions XIII: 6 (MarApr 1992). Também publicado no 1991 FORML Conference Proceedings. Ambos disponíveis do Forth Interest Group, P. O. Box 2154, Oakland, CA 94621. Ilustra compensações de design de muitos 8086 Forths com fragmentos de código e benchmarks - altamente recomendado KOG82, Peter M. quotAn Architectural Trail para Threaded-Code Systems, IEEE Computer, vol. 15 não. 3 (Mar 1982). Resta a descrição definitiva de várias técnicas de rosqueamento. ROD91 Rodriguez, B. J. b. Y.O. Assembler, quot Parte 1, The Computer Journal 52 (SepOct 1991). Princípios gerais da escrita Forth assemblers. ROD92 Rodriguez, B. J. b. Y.O. Assembler, quot Part 2, The Computer Journal 54 (JanFeb 1992). A 6809 montador em Forth. SCO89 Scott, Andrew, um Otimizador Extensível para Compilar Forth, 1989 FORML Conference Proceedings. Forth Interest Group, P. O. Box 2154, Oakland, CA 94621. Boa descrição de um otimizador 68000 sem código fornecido. CUR86 Curley, Charles, real-Forth para o 68000. Distribuição privada (1986). JAM80 James, John S. fig-Forth para o PDP-11. Forth Interest Group (1980). KUN81 Kuntze, Robert E. MVP-Forth para o Apple II. Mountain View Press (1981). LAX84 Laxen, H. e Perry, M. F83 para o IBM PC. Versão 2.1.0 (1984). Distribuído pelos autores, disponível no Forth Interest Group ou GEnie. LOE81 Loeliger, R. G. Linguagens Interpretativas. Publicações BYTE (1981), ISBN 0-07-038360-X. Pode ser o único livro escrito sobre a criação de um kernel tipo Forth (o exemplo utilizado é o Z80). Vale a pena se você pode encontrar uma cópia. MPE92 MicroProcessor Engenharia Ltd. MPE Z8Super8 PowerForth Target. MPE Ltd. 133 Hill Lane, Shirley, Southampton, S01 5AF, U. K. (Junho 1992). Um produto comercial. PAY90 Payne, William H. Embedded controlador FORTH para a família 8051. Academic Press (1990), ISBN 0-12-547570-5. Este é um quotkitquot completo para um 8051 Forth, incluindo um metacompilador para o IBM PC. Somente arquivos de cópia impressa podem ser baixados da GEnie. Não para o seringue SER90 do novice, Frank, Pygmy Forth para o PC de IBM. Versão 1.3 (1990). Distribuído pelo autor, disponível no Forth Interest Group. Versão 1.4 está agora disponível no GEnie, e vale a pena o esforço extra para obter. TAL80 Talbot, R. J. fig-Forth para o 6809. Forth Interest Group (1980). Nota dos autores para publicação na Web: os arquivos anteriormente disponíveis no serviço on-line da GEnie estão agora disponíveis no servidor FTP do Forth Interest Group, ftp: ftp. forth. orgpubForth. Atualizado: 14 de junho de 2010 Este artigo é parte do meu Linux Kernel Crash Livro. Está disponível para download gratuito em formato PDF Finalmente, o grande momento chegou. Lendo as informações exibidas pela utilidade de travamento, compreendendo o que aquelas linhas curiosas significam e cortando sua maneira com o problema ao outro lado. Aprendemos a configurar nossos sistemas para o despejo de falhas do kernel, usando LKCD e Kdump. Tanto localmente como através da rede. Aprendemos a configurar o mecanismo de despejo de quedas no CentOS e no openSUSE. E nós revisamos as sutis diferenças entre os dois sistemas operacionais. Em seguida, dominamos o uso básico do utilitário de falha, usando-o para abrir o núcleo de memória despejado e processar as informações nele contidas. Mas ainda não aprendemos a interpretar o resultado. Pré-Introdução Hoje, vamos nos concentrar apenas nisso. Leia a análise vmcore, entenda o que as entradas significam, realize uma investigação básica do problema, examine o código-fonte e obtenha uma metodologia eficiente para lidar com problemas de falha do kernel no futuro. Então, se você está com disposição para algum hackology super-sério, por favor, siga-me. Conteúdo Leitura necessária Você DEVE ler os outros artigos em outros para entender completamente como o ruído elétrico funciona. Você pode encontrar a lista detalhada das referências abaixo. Sem dominar os conceitos básicos, incluindo Kdump e funcionalidade de falha, você não poderá seguir este tutorial de forma eficiente. Analisando o relatório de falha - Primeiros passos Depois de iniciar o travamento, você obterá as informações do relatório inicial impressas no console. Este é o lugar onde a análise do acidente começa. Copyright © 2006 by Pearson Education, Inc. Todos os direitos reservados Direitos autorais (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -2006 Hewlett-Packard Co Copyright (C) 2005, 2006 Fujitsu Limited Copyright (C) 2006, 2007 VA Sistemas Linux Japão KK Copyright (C) 1999, 2000, 2001, 2002 Missão Crítica Linux, Inc. Este programa é software livre, coberto pelo Público Geral de GNU Licença, e você está convidado a alterá-lo e / ou distribuir cópias dele sob certas condições. Insira a ajuda de cópia para ver as condições. Este programa não tem nenhuma garantia. Entre na garantia da ajuda para obter detalhes. NOTA: stdin: not a tty GNU gdb 6.1 Copyright 2004 Free Software Foundation, Inc. O GDB é um software livre, coberto pela Licença Pública Geral GNU, e você pode alterá-lo e / ou distribuir cópias dele sob certas condições. Digite show copy para ver as condições. Não há absolutamente nenhuma garantia para o GDB. Digite show warranty para detalhes. Este GDB foi configurado como x8664-unknown-linux-gnu. Bt: não é possível transição de pilha de exceção para pilha de processo atual: ponteiro de pilha de exceção: ffff810107132f20 apontador de pilha de processo: ffff81010712bef0 currentstackbase: ffff8101b509c000 Kernel: usrlibdebuglibmodules2.6.18-164.10.1.el5.centos. plusvmlinux DUMPFILE: vmcore CPUS: 2 DATE: Tue Jan 19 20:21:19 2010 UPTIME: 00:00:00 PRÉMIO DE CARGA: 0.00, 0.04, 0.07 TAREFAS: 134 NODENAME: testhost2localdomain RELEASE: 2.6.18-164.10.1.el5 VERSÃO: 1 SMP Thu Jan 7 19:54: 26 EST 2010 MÁQUINA: x8664 (3000 Mhz) MEMÓRIA: 7.5 GB PANIC: SysRq. Trigger a crashdump PID: 0 COMANDO: swapper TAREFA: ffffffff80300ae0 (1 de 2) THREADINFO: ffffffff803f2000 CPU: 0 ESTADO: TASKRUNNING (ATIVO) Permite percorrer o relatório. A primeira coisa que você vê é algum tipo de erro: bt: não pode transição de pilha de exceção para pilha de processo atual: ponteiro de pilha de exceção: ffff810107132f20 apontador de pilha de processo: ffff81010712bef0 currentstackbase: ffff8101b509c000 A explicação técnica para este erro é um pouco complicada. Citado a partir do utilitário de falha thread de discussão de discussão sobre as alterações no utilitário de bloqueio versão 4.0-8.11, aprendemos as seguintes informações: Se um kdump NMI emitido para uma cpu x8664 não quebrando foi recebido durante a execução em schedule (), após ter definido o Próxima tarefa como atual no cpus runqueue, mas antes de alterar a pilha do kernel para a próxima tarefa, então um backtrace falharia fazer a transição da pilha de exceção NMI para a pilha de processo, com a mensagem de erro bt: can not Transição da pilha de exceções para a pilha de processos atual. Esse patch relatará inconsistências encontradas entre uma tarefa marcada como a tarefa atual em um cpus runqueue ea tarefa encontrada no campo pcurrent x8664pda por-cpu (2.6.29 e anterior) ou a variável currenttask por-cpu (2.6.30 e mais tarde). Se puder ser determinado com segurança que a configuração runqueue (usada por padrão) é prematura, a tarefa ativa interna do per-cpu será alterada para ser a tarefa indicada pelo valor específico da arquitetura apropriada. O que isso significa Seu um aviso que você deve prestar atenção quando analisar o relatório de acidente. Ele nos ajudará a determinar qual estrutura de tarefas precisamos examinar para solucionar o problema de falha. Por enquanto, ignore este erro. Não é importante entender o que o relatório contém. Você pode ou não vê-lo. Agora, vamos examinar o código abaixo deste erro. KERNEL: especifica o kernel em execução no momento da falha. DUMPFILE: é o nome do núcleo de memória despejado. CPUS: é o número de CPUs na sua máquina. DATE: especifica a hora da falha. TAREFAS: indica o número de tarefas na memória no momento da falha. Tarefa é um conjunto de instruções de programa carregado na memória. NODENAME: é o nome do host quebrou. RELEASE: e VERSION: especifique o release e a versão do kernel. MACHINE: especifica a arquitetura da CPU. MEMORY: é o tamanho da memória física na máquina quebrada. E agora vêm os bits interessantes: PANIC: especifica que tipo de acidente ocorreu na máquina. Existem vários tipos que você pode ver. SysRq (System Request) refere-se a Magic Keys, que permitem enviar instruções diretamente para o kernel. Eles podem ser chamados usando uma seqüência de teclado ou ecoando comandos de letra para procsysrq-trigger. Desde que a funcionalidade esteja ativada. Discutimos isso no tutorial do Kdump. Oops é um desvio do comportamento esperado, correto do kernel. Normalmente, os resultados oops no processo ofensivo sendo morto. O sistema pode ou não retomar o seu comportamento normal. Muito provavelmente, o sistema entrará em um estado imprevisível, instável, o que poderia levar ao kernel pânico se alguns dos buggy, mortos recursos são solicitados mais tarde. Por exemplo, no meu Ubuntu Karmic e comentários Fedora Constantine, weve visto provas de kernel falha. No entanto, o sistema continuou funcionando. Essas falhas eram, de fato, oopses. Vamos discutir o caso Fedora mais tarde. O pânico é um estado onde o sistema encontrou um erro fatal e não pode recuperar. O pânico pode ser causado tentando acessar endereços não permitidos, carregamento forçado ou descarregamento de módulos do kernel, ou problemas de hardware. Em nosso primeiro exemplo, o mais benigno, o pânico: string refere-se ao uso de Magic Keys. Nós deliberadamente acionamos um acidente. PANIC: SysRq. Trigger um crashdump PID: é o ID do processo do. Processo que causou a falha. COMMAND: é o nome do processo, neste caso swapper. Swapper Ou PID 0 é o planejador. É o processo que delega o tempo de CPU entre os processos executáveis e se não há outros processos no runqueue, ele assume o controle. Você pode querer se referir a swapper como a tarefa ociosa, por assim dizer. Theres um swapper por CPU, que você vai ver em breve quando começamos a explorar o acidente em maior profundidade. Mas isso não é realmente importante. Vamos encontrar muitos processos com nomes diferentes. TASK: é o endereço na memória para o processo ofensivo. Usaremos essas informações mais tarde. Há uma diferença no endereçamento de memória para arquiteturas de 32 bits e 64 bits. CPU: é o número da CPU (relevante se mais de um) onde o processo ofensivo estava sendo executado no momento da falha. A CPU refere-se a núcleos de CPU e não apenas a CPUs físicas. Se você está executando o Linux com hyperthreading habilitado, então você também estará contando segmentos separados como CPUs. Isso é importante lembrar, porque falhas recorrentes em apenas uma CPU específica pode indicar um problema de CPU. Se você está executando seus processos com afinidade definida para determinadas CPUs (taskset), então você pode ter mais dificuldade em localizar problemas relacionados a CPU ao analisar os relatórios de falha. Você pode examinar o número de CPUs executando proccpuinfo gato. STATE: indica o estado do processo no momento da falha. TASKRUNNING refere-se a processos executáveis, isto é, processos que podem continuar a sua execução. Novamente, falaremos mais sobre isso mais tarde. Ficando mais quentes Já vimos um exemplo benigno até agora. Apenas uma introdução. Vamos dar uma olhada em vários outros exemplos, incluindo casos reais. Por agora, sabemos pouco sobre o acidente, exceto que o processo que causou. Vamos agora examinar mais alguns exemplos e tentar entender o que vemos lá. Exemplo do Fedora Vamos voltar ao caso do Fedora. Dê uma olhada na imagem abaixo. Enquanto a informação é organizada de forma um pouco diferente do que weve visto anteriormente, essencialmente, é a mesma coisa. Mas há uma nova informação: Pid: 0, comm: swapper Não manchado. Vamos focar a corda não contaminada por um momento. O que significa isso significa que o kernel não está executando qualquer módulo que tenha sido carregado com força. Em outras palavras, provavelmente estamos enfrentando um bug de código em algum lugar, em vez de uma violação do kernel. Você pode examinar o seu kernel em execução executando: Até agora, aprendemos um pouco mais de informações. Falaremos disso mais tarde. Outro exemplo, a partir do Livro Branco Dê uma olhada neste: MEMÓRIA: 128MB PANIC: Oops: 0002 (verificar log para obter detalhes) PID: 1696 COMANDO: insmod O que temos aqui Uma nova peça de informação. Oops: 0002. O que isso significa Erro de página do kernel Os quatro dígitos são um código decimal do erro de página do kernel. Leitura de OReillys Noções básicas sobre o kernel do Linux, Capítulo 9: Espaço de endereços de processo, Gerenciador de exceção de falha de página, páginas 376-382, aprendemos as seguintes informações: Se o primeiro bit é nulo (0), a exceção foi causada por um acesso a uma página que Não está presente se o bit estiver definido (1), isto significa direito de acesso inválido. Se o segundo bit está desmarcado (0), a exceção foi causada pelo acesso de leitura ou execução se definido (1), a exceção foi causada por um acesso de escrita. Se o terceiro bit estiver desmarcado (0), a exceção foi causada enquanto o processador estava no modo Kernel, caso contrário, ocorreu no modo Usuário. O quarto bit nos diz se a falha foi uma busca de instrução. Isso é válido somente para arquitetura de 64 bits. Uma vez que a nossa máquina é de 64 bits, o bit tem significado aqui. Isto é bastante interessante. Informações aparentemente incompreensíveis começam a parecer muito lógicas. Oh, você também pode ver os Erros de Página do Kernel no seguinte formato, como uma tabela: Às vezes, acesso inválido também é referido como falha de proteção: Portanto, para entender o que aconteceu, precisamos traduzir o código decimal em binário e, em seguida, examinar Os quatro bits, da direita para a esquerda. Você pode encontrar essas informações em archarchmmfault. c na árvore de origem do kernel: PFPROT (1ltlt0) ou nenhuma página encontrada define PFWRITE (1ltlt1) define PFUSER (1ltlt2) define PFRSVD (1ltlt3) define PFINSTR (1ltlt4) In Nosso caso, o decimal 2 é binário 10. Olhando da direita para a esquerda, o bit 1 é zero, o bit 2 é aceso, o bit 3 e 4 são zero. Observe a contagem binária, começando de zero. 0002 (dec) --gt 0010 (binário) --gt Não instrução fetchKernel modeWriteInvalid access Portanto, temos uma página não encontrada durante uma operação de gravação no modo Kernel, a falha não foi um Instruction Fetch. Claro, é um pouco mais complicado do que isso, mas ainda estavam recebendo uma idéia muito boa do que está acontecendo. Bem, está começando a ficar interessante, não é Olhando para o processo ofensivo, insmod. Isso nos diz um pouco. Tentamos carregar um módulo do kernel. Tentou escrever para uma página que não conseguiu encontrar, ou seja, falha de proteção, que causou o nosso sistema para falhar. Isso pode ser um pedaço de código mal escrito. Status check OK, até agora, weve visto um pouco de informações úteis. Aprendemos sobre os campos de identificador básico no relatório de falha. Aprendemos sobre os diferentes tipos de pânico. Aprendemos sobre a identificação do processo ofensivo, decidindo se o kernel está corrompido e que tipo de problema ocorreu no momento da falha. Mas nós apenas começamos nossa análise. Vamos levar isso para um novo nível. Começ quente No primeiro artigo no ruído elétrico, nós aprendemos sobre alguns comandos básicos. É hora de usá-los bem. O primeiro comando que queremos é bt - backtrace. Queremos ver o histórico de execução do processo ofensivo, ou seja, backtrace. PID: 0 TAREFA: CPU ffffffff80300ae0: 0 comando: swapper 0 ffffffff80440f20 crashnmicallback em ffffffff8007a68e 1 ffffffff80440f40 donmi em ffffffff8006585a 2 ffffffff80440f50 nmi em ffffffff80064ebf RIP exceção: RIP defaultidle61: ffffffff8006b301 RSP: RFLAGS ffffffff803f3f90: 00000246 RAX: 0000000000000000 RBX: RCX ffffffff8006b2d8: 0000000000000000 RDX : 0000000000000000 RSI: 0000000000000001 RDI: RBP ffffffff80302698: 0000000000090000 R8: ffffffff803f2000 R9: R10 000000000000003e: ffff810107154038 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 ORIGRAX: ffffffffffffffff CS: 0010 SS: 0,018 --- ltexception stackgt - - 3 ffffffff803f3f90 defaultidle em ffffffff8006b301 4 ffffffff803f3f90 cpuidle em ffffffff8004943c Temos muitos dados aqui, vamos começar a digeri-lo lentamente. Rastreio de chamada A seqüência de linhas numeradas, começando pelo sinal de hash () é o rastreamento de chamada. É uma lista de funções do kernel executadas imediatamente antes da falha. Isso nos dá uma boa indicação do que aconteceu antes do sistema cair. 0 ffffffff80440f20 crashnmicallback em ffffffff8007a68e 1 ffffffff80440f40 donmi em ffffffff8006585a 2 ffffffff80440f50 nmi em ffffffff80064ebf PIR excepção: PIR defaultidle61: ffffffff8006b301 RSP: RFLAGS ffffffff803f3f90: 00000246 RAX: 0000000000000000 RBX: RCX ffffffff8006b2d8: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000001 RDI: RBP ffffffff80302698: 0000000000090000 R8 : ffffffff803f2000 R9: R10 000000000000003e: ffff810107154038 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 ORIGRAX: ffffffffffffffff CS: 0010 SS: 0,018 --- --- stackgt ltexception 3 ffffffff803f3f90 defaultidle em ffffffff8006b301 4 ffffffff803f3f90 CpuIdle em ffffffff8004943c Discutiremos isso mais adiante. Instrução ponteiro A primeira linha realmente interessante é esta: excepção RIP: defaultidle61 Temos excepção RIP: defaultidle61. O que isso significa Primeiro, vamos discutir RIP. RIP é o ponteiro de instrução. Ele aponta para um endereço de memória, indicando o progresso da execução do programa na memória. No nosso caso, você pode ver o endereço exato na linha logo abaixo da linha de exceção entre colchetes: exception RIP: defaultidle61 RIP: ffffffff8006b301 RSP: ffffffff803f3f90. Por enquanto, o próprio endereço não é importante. Nota: Na arquitetura de 32 bits, o ponteiro de instrução é chamado de EIP. A segunda parte da informação é muito mais útil para nós. Defaultidle é o nome da função do kernel na qual o RIP está. 61 é o deslocamento, no formato decimal, dentro da referida função onde ocorreu a excepção. Este é o pedaço realmente importante que usaremos mais tarde em nossa análise. Código Segmento (CS) O código entre a seqüência entre colchetes até --- ltexception stackgt --- é o despejo de registradores. A maioria não é útil para nós, exceto o registro CS (Segmento de código). Novamente, encontramos uma combinação de quatro dígitos. Para explicar este conceito, preciso desviar um pouco e falar sobre os níveis de Privilégio. Nível de privilégio é o conceito de proteger recursos em uma CPU. Os diferentes threads de execução podem ter diferentes níveis de privilégios, que dão acesso aos recursos do sistema, como regiões de memória, portas IO, etc. Existem quatro níveis, variando de 0 a 3. O Nível 0 é o mais privilegiado, conhecido como modo Kernel. Nível 3 é o menos privilegiado, conhecido como modo de usuário. A maioria dos sistemas operacionais modernos, incluindo o Linux, ignoram os dois níveis intermediários, usando apenas 0 e 3. Os níveis também são conhecidos como Rings. Uma exceção notável do uso de níveis foi o sistema IBM OS2. O registro de Segmento de Código de Nível de Privilégio (CPL) atual é aquele que aponta para um segmento onde as instruções do programa são definidas. Os dois bits menos significativos deste registo especificam o nível de privilégio actual (CPL) da CPU. Dois bits, significando números entre 0 e 3. Descriptor Nível de Privilégio (DPL) amplificador Nível de Privilégio Solicitado (RPL) O Descriptor Nível de Privilégio (DPL) é o nível mais alto de privilégio que pode acessar o recurso e é definido. Esse valor é definido no Descritor de Segmento. O Nível de Privilégio Solicitado (RPL) é definido no Segment Selector, os dois últimos bits. Matematicamente, CPL não é permitido exceder MAX (RPL, DPL), e se o fizer, isso irá causar uma falha de proteção geral. Por exemplo, se você encontrar um caso em que o sistema caiu enquanto o CPL era 3, então isso poderia indicar hardware defeituoso, porque o sistema não deve travar por causa de um problema no modo de usuário . Como alternativa, pode haver um problema com uma chamada de sistema buggy. Apenas alguns exemplos aproximados. Para obter mais informações, considere referir-se a OReillys Compreendendo o Kernel do Linux, Capítulo 2: Endereçamento de Memória, Página 36-39. Você encontrará informações úteis sobre seletores de segmentos, descritores de segmentos, índice de tabela, tabelas de descritores globais e locais e, claro, o nível de privilégio atual (CPL). Voltar ao nosso log de falhas: Como sabemos, os dois bits menos significativos especificam o CPL. Dois bits significa quatro níveis, no entanto, os níveis 1 e 2 são ignorados. Isso nos deixa com 0 e 3, o modo Kernel eo modo User, respectivamente. Traduzido em formato binário, temos 00 e 11. O formato utilizado para apresentar os dados do descritor pode ser confuso, mas é muito simples. Se a figura mais à direita é uniforme, então estavam no modo Kernel se a última figura for ímpar, então estavam no modo User. Assim, vemos que CPL é 0, a tarefa ofensiva que conduziu ao bloqueio estava em execução no modo Kernel. Isso é importante saber. Pode ajudar-nos a compreender a natureza do nosso problema. Apenas para referência, heres um exemplo onde o acidente ocorreu no modo de usuário, coletado em uma máquina SUSE: Mas thats apenas geeky falar. De volta ao nosso exemplo, aprendemos muitos detalhes úteis e importantes. Sabemos o endereço de memória exata onde o ponteiro de instrução foi no momento da falha. Conhecemos o nível de privilégio. Mais importante ainda, sabemos o nome da função do kernel eo deslocamento onde o RIP estava apontando no momento da falha. Para todos os efeitos práticos, só precisamos encontrar o arquivo de origem e examinar o código. Claro, isso pode não ser sempre possível, por várias razões, mas vamos fazer isso, no entanto, como um exercício. Então, sabemos que a função crashnmicallback () foi chamada por donmi (), donmi () foi chamada por nmi (), nmi () foi chamada por defaultidle (), que causou a falha. Podemos examinar essas funções e tentar entender mais profundamente o que elas fazem. Faremos isso em breve. Agora, vamos revisitar nosso exemplo do Fedora mais uma vez. Exemplo do Fedora, novamente Agora que entendemos o que está errado, podemos dar uma olhada no exemplo do Fedora novamente e tentar entender o problema. Temos um acidente em um kernel não contaminado, causado pelo processo swapper. O relatório de falha aponta para a função nativeapicwritedummy. Então, theres também um traço de chamada muito longo. Um pouco de informação útil que deve nos ajudar a resolver o problema. Veremos como podemos usar os relatórios de falhas para ajudar os desenvolvedores a corrigir bugs e produzir um software melhor e mais estável. Agora, vamos focar um pouco mais no acidente e nos comandos básicos. Backtrace para todas as tarefas Por padrão, o crash exibirá o backtrace para a tarefa ativa. Mas você também pode querer ver o backtrace de todas as tarefas. Neste caso, você vai querer executar foreach. Dump mensagem de buffer de mensagem do sistema - dump buffer de mensagem do sistema Este comando despeja o conteúdo do logbuf do kernel em ordem cronológica. O bugger do log do kernel (logbuf) pode conter pistas úteis que precedem a falha, o que pode nos ajudar a localizar o problema mais facilmente e entender por que nosso sistema desceu. O comando de log pode não ser realmente útil se você tiver problemas de hardware intermitentes ou bugs de software, mas definitivamente vale a pena tentar. Heres nosso log de falha, as últimas linhas: ide: falhou o opcode foi: 0xec mtrr: tipo incompatibilidade para f8000000,400000 antigo: uncachable novo: write-combining ISO 9660 Extensões: Microsoft Joliet Nível 3 ISO 9660 Extensões: RRIP1991A SysRq. Trigger um crashdump E há a mensagem SysRq. Útil para saber. Em casos reais, pode haver algo muito mais interessante. Exibir informações sobre o status do processo ps - exibir informações sobre o status do processo Este comando exibe o status do processo selecionado ou todos os processos no sistema. Se nenhum argumento for inserido, os dados do processo serão exibidos para todos os processos. Dê uma olhada no exemplo abaixo. Temos dois processos swapper Como eu disse anteriormente, cada CPU tem seu próprio planejador. A tarefa ativa está marcada com gt. O utilitário de falha pode carregar apontando para uma tarefa que não causou o pânico ou pode não ser capaz de localizar a tarefa de pânico. Não existem garantias. Se você estiver usando máquinas virtuais, incluindo VMware ou Xen, então as coisas podem ficar ainda mais complicado. Neste caso, o ponteiro na saída ps marca o processo errado: Usando backtrace para todos os processos (com foreach) e executando o comando ps, você deve ser capaz de localizar o processo ofensivo e examinar sua tarefa. Outras informações úteis que você pode precisar: Os itens embreados são tópicos do kernel, por exemplo, init e udevd não são. Em seguida, há informações de uso de memória, VSZ e RSS, estado de processo e muito mais. Super geeky stuff Nota: Esta seção é impossivelmente difícil. Muito difícil para a maioria das pessoas. Muito poucas pessoas são qualificados o suficiente para dabble no código do kernel e realmente sabe o que está acontecendo lá dentro. Tentando ser corajoso e enfrentar os possíveis bugs escondidos em núcleos de colisão é uma tentativa nobre, mas você não deve tomar isso de ânimo leve. Eu tenho que admitir que, embora eu possa ler relatórios de acidentes e fontes acompanhantes, ainda tenho um grande negócio para aprender sobre as pequenas coisas e bits. Não espere qualquer milagres. Não há nenhuma solução de prata-bala para crash análise Tempo para obter ultra-grave. Vamos dizer que você pode até querer analisar o código C para a função ofensiva. Escusado será dizer que você deve ter as fontes C disponíveis e ser capaz de lê-los. Isso não é algo que todos deveriam fazer, mas é um exercício mental interessante. Código-fonte Tudo bem, você quer examinar o código. Primeiro, você terá que obter as fontes. Algumas distribuições tornam as fontes prontamente disponíveis. Por exemplo, no openSUSE, basta baixar o pacote kernel-source. Com CentOS, é um pouco mais difícil, mas factível. Você também pode visitar o Arquivo do Kernel do Linux e fazer o download do kernel correspondente ao seu, embora algumas fontes possam ser diferentes das usadas em seu sistema, já que alguns fornecedores fazem suas próprias alterações personalizadas. Depois de ter as fontes, é hora de examiná-los. Exemplo, no openSUSE: Você pode procurar as fontes usando as ferramentas padrão como find e grep, mas isso pode ser bastante tedioso. Em vez disso, por que não deixar o sistema fazer todo o trabalho duro para você. Um utilitário muito bom para navegar código C é chamado cscope. A ferramenta é executada a partir da linha de comando e usa uma interface semelhante a vi. Por padrão, ele irá procurar fontes no diretório atual, mas você pode configurá-lo de qualquer maneira. Cscope está disponível nos repositórios: Agora, no diretório que contém as fontes (por padrão, usrsrclinux), execute cscope: Isso irá pesquisar recursivamente todos os subdiretórios, indexar as fontes e exibir a interface principal. Existem outros usos, bem como tentar a página man ou --help flag. Agora, é hora de colocar a ferramenta para um bom uso e busca de funções desejadas. Começaremos por encontrar este símbolo C. Utilize as teclas do cursor para descer até esta linha e, em seguida, digite o nome da função desejada e pressione Enter. Os resultados serão exibidos: Dependendo do que aconteceu, você pode obter muitos resultados ou nenhum. É muito possível que não haja nenhum código-fonte contendo a função vista no relatório de falha. Se houver muitos resultados, talvez você queira procurar a próxima função no rastreamento de chamada usando a função Localizar chamadas por esta função. Use Tab para saltar entre a seção de entrada e saída. Se você tiver o suporte oficial do fornecedor, este é um bom momento para ativar o comando e deixá-los dirigir. Se você ficar com a investigação, procurando outras funções listadas no rastreamento de chamada pode ajudá-lo a diminuir o arquivo C que você precisa. Mas theres nenhuma garantia e este pode ser um processo longo, tedious. Além disso, sempre que precisar de ajuda, basta pressionar. E você obterá um guia de uso básico: No diretório de origem do kernel, você também pode criar os índices cscope, para pesquisas mais rápidas no futuro, executando make cscope. Desmonte o objeto Assumindo que você encontrou a fonte, é hora de desmontar o objeto compilado a partir desta fonte. Primeiro, se você estiver executando um kernel de depuração, então todos os objetos foram compilados com os símbolos de depuração. Você é sortudo. Você só precisa despejar o objeto e enterrar-se no código de assembly-C misturado. Se não, você terá que recompilar a fonte com símbolos de depuração e, em seguida, engenharia reversa-lo. Esta não é uma tarefa simples ou trivial. Primeiro, se você usar um compilador diferente do usado para compilar o original, seu objeto será diferente do que está no relatório de falha, tornando seus esforços difíceis, se não impossíveis. Exemplo Trivial Eu chamo este exemplo trivial porque não tem nada fazer com o kernel. Ele simplesmente demonstra como compilar objetos e depois desmontá-los. Qualquer fonte fará. Em nosso caso, use bem o MPlayer, um popular reprodutor de mídia de código aberto como nosso bode expiatório. Faça o download do código-fonte do MPlayer, execute. configure, make. Após a criação dos objetos, exclua um deles e, em seguida, recompile-o. Executar make ltobject namegt. Por exemplo: Note que make não tem nenhum significado sem um Makefile, que especifica o que precisa ser feito. Mas temos um Makefile. Ele foi criado depois de executar. configure. Caso contrário, tudo isso não funcionaria. Makefile é muito importante. Em breve veremos um exemplo menos trivial. Se você não remover o objeto existente, então provavelmente você não será capaz de fazê-lo. Faça compara timestamps em fontes eo objeto, portanto, a menos que você altere as fontes, a recompilação do objeto falhará. Agora, heres outro exemplo simples, e observe a diferença no tamanho do objeto criado, uma vez com os símbolos de depuração e uma vez sem: Se você não tem um Makefile, você pode invocar gcc manualmente usando todos os tipos de sinalizadores. Você precisará de cabeçalhos do kernel que correspondam à arquitetura e à versão do kernel que foi usada para criar o kernel onde ocorreu a falha, caso contrário seus objetos recém-compilados serão completamente diferentes dos que você deseja analisar, incluindo funções e deslocamentos. Um utilitário que você deseja usar para desmontagem é objdump. Você provavelmente vai querer usar o utilitário com - S flag, o que significa exibir código fonte misturado com as instruções de montagem. Você também pode querer - s sinalizador, que irá exibir conteúdo de todas as seções, incluindo os vazios. - S implica - d. Que exibe os mnemônicos do montador para as instruções de máquina de objfile esta opção só desmonta as seções que são esperadas para conter instruções. Em alternativa, utilize - D para todas as secções. Assim, o objdump mais inclusivo seria: objdump - D - S ltcompiled o objeto com o debug symbolsgt gt ltoutput filegt Ele será algo assim: E um exemplo ainda melhor, o despejo memhog: Passando para fontes do kernel Aquecimento. Uma vez que você está confiante praticando com código trivial, tempo para mover para o kernel. Certifique-se de que você não apenas exclua qualquer arquivo importante. Por motivos de exercício, mova ou renomeie qualquer objeto de kernel existente que você possa encontrar à espreita. Em seguida, recompilá-los. Você precisará do arquivo. config usado para compilar o kernel. Deve ser incluído com as fontes. Alternativamente, você pode descartá-lo de procconfig. gz. Zcat procconfig. gz gt. config Nas máquinas RedHat, você encontrará os arquivos de configuração também no boot. Certifique-se de usar o que coincide com o kernel quebrado e copiá-lo para o diretório de origem. Se necessário, edite algumas das opções, como CONFIGDEBUGINFO. Mais sobre isso mais tarde. Sem o arquivo. config, você não será capaz de compilar fontes do kernel: Você também pode encontrar um erro onde o Makefile está supostamente ausente, mas está lá. Neste caso, você pode estar enfrentando um problema relativamente simples, com a variável de ambiente ARCH incorreta definida. Por exemplo, i585 versus i686 e x86-64 versus x8664. Preste atenção ao erro e compare a arquitetura com a variável ARCH. No pior caso, talvez seja necessário exportá-lo corretamente. Por exemplo: Como uma solução de longo prazo, você também pode criar links simbólicos sob usrsrclinux da arquitetura would-be ruim para a direita. Isso não está estritamente relacionado à análise de falhas do kernel, mas se e quando você compilar fontes do kernel, você pode encontrar esse problema. Agora, em relação à variável CONFIGDEBUGINFO. Ele deve ser definido como 1 em seu arquivo. config. Se você se lembrar do tutorial do Kdump, este era um pré-requisito que pedimos, para poder solucionar problemas de falhas do kernel com êxito. Isso informa o compilador para criar objetos com símbolos de depuração. Como alternativa, exportar a variável no shell, como CONFIGDEBUGINFO1. Então, dê uma olhada no Makefile. Você deve ver que se essa variável for definida, o objeto será compilado com símbolos de depuração (-g). Isso é o que precisamos. Depois disso, mais uma vez, vamos usar objdump. Agora, Makefile pode realmente estar faltando. Neste caso, você obterá um monte de erros relacionados ao processo de compilação. Mas com o Makefile no lugar, ele deve todo o trabalho lisamente. E então, theres o objeto até à data exemplo novamente. Se você não remover um já existente, não será capaz de compilar um novo, especialmente se você precisar de símbolos de depuração para desmontagem posterior. Finalmente, o objeto desmontado: O que fazemos agora? Bem, você procura a função listada no RIP de exceção e marca o endereço inicial. Em seguida, adicione o deslocamento para este número, traduzido para formato hexadecimal. Em seguida, vá para a linha especificada. Tudo o que resta é tentar entender o que realmente aconteceu. Você terá uma instrução de montagem listada e possivelmente algum código C, dizendo-nos o que poderia ter dado errado. Não é fácil. 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.
Comments
Post a Comment