Recolher e interpretar dados de erro

Os dados de eventos e erros são carregados diariamente para o Serviço de Segurança do Azure Sphere. Qualquer pessoa que tenha acesso a um catálogo específico pode transferir os dados desse catálogo. O relatório abrange todos os dispositivos no catálogo.

Cada relatório contém um máximo de 1000 eventos ou 14 dias de dados, o que for atingido primeiro. Os dados podem ser escritos num ficheiro ou direcionados para um script ou aplicação. A CLI só pode devolver 1000 eventos. Utilize a API Pública do Azure Sphere para especificar o número máximo de eventos devolvidos na página.

Pode transferir dados sobre os erros e outros eventos que afetam os seus dispositivos das seguintes formas:

  • Ao utilizar o comando az sphere catalog download-error-report . É transferido um ficheiro CSV que contém informações sobre erros e eventos comunicados por dispositivos no catálogo atual.

  • Ao utilizar a API Pública do Azure Sphere para relatório de erros. O ponto final da API devolve um objeto JSON que pode analisar de acordo com as suas necessidades.

Não são recolhidos dados de relatórios de erros a partir do RTApps. Se quiser registar erros do RTApps, terá de implementar comunicações entre núcleos para comunicar erros do RTApps à aplicação de alto nível, a partir da qual os dados de erro podem ser registados nos serviços de rede.

Tipos de dados disponíveis

Os dados devolvidos para cada erro ou evento incluem o seguinte:

Dados Descrição
ID do Dispositivo ID do dispositivo que encontrou o evento.
Tipo de Evento Se o evento foi planeado ou não planeado. As atualizações do SO e da aplicação são consideradas eventos planeados, enquanto os erros são eventos não planeados.
Classe de Eventos Componente de software que encontrou o evento: SO ou aplicação.
Contagem de Eventos Número de vezes que o evento ocorreu no período delimitado por StartTime e EndTime.
Descrição Informações sobre o evento. Este campo é genérico e varia consoante o evento e a respetiva origem. Para aplicações, pode conter o código de saída, o estado do sinal e o código de sinal, mas os conteúdos exatos do campo não são fixos. Isto contém informações sobre o evento e é proveniente da primeira ocorrência do evento na janela de tempo.
Hora de Início Data e hora (em UTC) em que a janela do evento começou.
Hora de Fim Data e hora (em UTC) em que a janela do evento terminou.

A Hora de Início e a Hora de Fim definem uma janela de tempo durante a qual os dados do evento são agregados. A janela para qualquer grupo agregado de eventos pode ser até 24 horas e o máximo é de 8 ocorrências por período de tempo.

Eventos da aplicação

Os eventos da aplicação incluem atualizações de aplicações carregadas na cloud, juntamente com falhas, saídas e outros tipos de falhas de aplicações.

As atualizações da aplicação são eventos planeados. Para um evento AppUpdate, o campo Descrição contém AppUpdate.

Falhas de aplicações, saídas, falhas de arranque e eventos semelhantes são eventos não planeados. Para um evento não planeado, os conteúdos do campo Descrição dependem da aplicação que encontrou o evento. A tabela seguinte lista os campos que podem estar presentes no campo Descrição de um evento não planeado.

Dados Descrição
exit_status ou exit_code Estado de saída ou código comunicado pela aplicação.
signal_status Número inteiro que descreve a razão de alto nível para a falha, devolvida pelo SO. Pode encontrar uma lista de estados na documentação do Man 7 ou noutros recursos do Linux.
signal_code Número inteiro que indica o estado de falha detalhado no estado do sinal principal. Veja a documentação do Man 7 ou outros recursos do Linux para obter detalhes.
component_id GUID do componente de software que falhou.
image_id GUID da imagem que estava em execução no momento do erro.

As informações específicas numa descrição do AppCrash dependem da origem da falha. Para a maioria das falhas, a descrição tem um aspeto semelhante ao seguinte:

AppCrash (exit_status=11; signal_status=11; signal_code=3; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; image_id=7053e7b3-d2bb-431f-8d3a-173f52db9675)

Em alguns casos, uma falha aciona dados de erro adicionais, como o seguinte, que complementa os dados no exemplo anterior:

AppCrash (pc=BEEED2EE; lr=BEEED2E5; sp=BEFFDE58; signo=11; errno=0; code=0; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; pc_modulename+offset=appname+80000; lr_modulename+offset=app+100CC)

Dados Descrição
pc Contador de Programas. Aponta para o endereço da instrução que acionou a falha.
lr Registo de Ligações. Possivelmente aponta para o endereço devolvido na função de chamada.
sp Ponteiro de Pilha. Aponta para a parte superior da pilha de chamadas.
signo Sinal POSIX. Indica o tipo de erro.
errno POSIX errno. Indica um erro.
código Indica o estado de falha detalhado no estado do sinal principal.
component_id GUID do componente de software que falhou.
pc_modulename+desvio Nome do módulo e desvio para o módulo que contém o código onde ocorreu a falha.
lr_modulename+desvio Nome do módulo e desvio para o módulo que pode ter sido a função de chamada.

Interpretar AppCrashes

Pode encontrar a maioria das informações sobre um AppCrash no signal_status e signal_code. Siga estes passos:

  1. Utilizando a documentação do Man 7 para signal_status, veja primeiro a tabela com o nome "Numeração de Sinais para Sinais Padrão". Na coluna x86/ARM, procure o valor atribuído ao signal_status no relatório de erros csv. Uma vez encontrado, tenha em atenção o nome do Sinal correspondente na coluna mais à esquerda.
  2. Desloque-se para cima até à tabela com o nome "Sinais Padrão". Corresponda ao Nome do sinal anteriormente determinado e utilize a tabela para recolher mais informações sobre o que o sinal indica.
  3. Na documentação do Man 7 para signal_code e o Nome do sinal que encontrou anteriormente, localize a lista correspondente de si_codes.
  4. Utilize o valor atribuído ao signal_code no ficheiro de relatório csv de erros para determinar que código corresponde à mensagem de erro.

Por exemplo, considere a seguinte descrição do AppCrash:

AppCrash (exit_status=11; signal_status=11; signal_code=3; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; image_id=7053e7b3-d2bb-431f-8d3a-173f52db9675)

Com a documentação do Man 7, pode descobrir as seguintes informações adicionais sobre o AppCrash:

  1. Os sinais são descritos na décima secção da descrição da página Homem do sinal. Um signal_status do valor 11 corresponde a um sinal SIGSEGV.
  2. SIGSEGV indica que ocorreu uma referência de memória inválida (geralmente, pode ser um ponteiro nulo).
  3. SI_Codes são descritos na 3ª secção da descrição da página SigAction man para cada signal_status. Embora a página não liste um número de índice para cada si_code, pode contar a partir de cada signal_status categoria a partir do índice 1. Ao observar a lista de si_codes para SIGSEGV (a partir do índice 1), pode ver que o terceiro corresponde a um SEGV_BNDERR.
  4. SEGV_BNDERR indica que ocorreu uma verificação com limite de endereços falhada.

Nota

Um AppCrash comumente encontrado inclui um valor de signal_status de 9, que é um sinal SIGKILL, juntamente com o SEND_SIG_PRIV si_code. Este estado indica que o SO matou a aplicação porque excedeu o limite de utilização da memória. Para saber mais sobre os limites de memória da aplicação, veja Utilização da memória em aplicações de alto nível.

Interpretar AppExits

Quando uma aplicação sai sem erro, os campos signal_status e signal_code não estão presentes e, em vez de uma exit_status, a Descrição contém um código de saída:

AppExit (exit_code=0; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; image_id=0a7cc3a2-f7c2-4478-8b02-723c1c6a85cd)

Os AppExits podem ocorrer por vários motivos, como uma atualização da aplicação, um dispositivo que está a ser desligado da corrente ou a utilização da API de ligar/desligar, entre outros. É importante implementar códigos de saída para que possa obter informações sobre os motivos de um AppExit.

Para interpretar AppExits, utilize o valor exit_code no campo Descrição do relatório de erros. Se a aplicação devolver um código de saída, pode utilizar o valor da exit_code no relatório de erros para determinar onde ou quando ocorreu o erro. Com este valor, pesquise no código da aplicação para ver que mensagem de código de saída corresponde ao valor fornecido no relatório de erros. Em seguida, procure a função na aplicação que devolveu a mensagem de código de saída e por que motivo o fez. Ao ver a instrução return e o respetivo contexto, poderá conseguir descobrir o motivo do erro.

Eventos do SO

Os dados de erro também incluem eventos de hardware e SO subjacentes que podem afetar a sua aplicação, fazendo com que falhe ou reinicie. Estes eventos podem incluir o seguinte:

  • Reinícios de dispositivos não planeados causados por erros de kernel
  • Atualizações do SO na Cloud
  • Problemas de hardware transitórios

Os eventos do SO são incluídos nos dados para o ajudar a determinar se os erros da aplicação são o resultado de um problema de SO ou hardware ou se refletem problemas com a própria aplicação. Se os dados do evento mostrarem que um dispositivo arrancou para o Modo de Segurança, as suas aplicações poderão não conseguir iniciar.

Explorar dados de erro

Se planear desenvolver scripts ou ferramentas para analisar dados de erros, mas não tiver um grande número de dispositivos disponíveis para comunicar erros, pode utilizar as aplicações de exemplo do Azure Sphere para gerar esses dados para teste. O exemplo Tutorials/ErrorReporting no repositório de exemplos do Azure Sphere explica como analisar erros comunicados quando a aplicação falha. Siga as instruções no readme para criar o exemplo com o Visual Studio, o Visual Studio Code ou a linha de comandos.

Quando implementa a aplicação a partir da linha de comandos sem um depurador, o SO reinicia-a sempre que falhar. Eventos semelhantes são agregados para que um dispositivo com falhas frequentes não disfarça erros de outras pessoas e o máximo seja de oito ocorrências por período de tempo. Pode implementar o exemplo a partir da linha de comandos sem depuração, da seguinte forma:

az sphere device sideload deploy --image-package <path to image package for the app>

Gerar e transferir o relatório de erros

Os dados de eventos e erros são carregados diariamente para o Serviço de Segurança do Azure Sphere. Certifique-se de que o dispositivo do Azure Sphere está ligado à Internet através de Wi-Fi ou Ethernet para comunicar com o Serviço de Segurança do Azure Sphere.

  1. Execute o seguinte comando para transferir o relatório para um ficheiro CSV:

    az sphere catalog download-error-report --destination error.csv
    
  2. Abra o ficheiro CSV transferido e procure o ID do componente. Deverá ver uma descrição de erro semelhante à seguinte:

    AppExit (exit_code=0; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; image_id=6d2646aa-c0ce-4e55-b7d6-7c206a7a6363)

Também pode utilizar a API Pública do Azure Sphere para o relatório de erros.

Nota

  • Pode demorar até 24 horas para que os eventos comunicados recentemente estejam disponíveis para transferência.
  • Se ocorrer um evento ou erro antes de o dispositivo se ligar a um servidor NTP, o carimbo de data/hora do evento contido na telemetria carregada para AS3 poderá estar incorreto. Isto será refletido numa entrada incorreta na coluna StartTime no relatório subsequente transferido do AS3. Nesta situação, utilize o campo EndTime do relatório para ajudar a estimar quando o evento ocorreu. Este campo contém a hora em que os serviços cloud receberam a telemetria carregada e terá sempre uma data válida.

Formatar dados de erro

Os carimbos de data/hora e as colunas de dados no ficheiro de relatório de erros são formatados de forma diferente de um ficheiro CSV típico. Se quiser ver os resultados no Excel, pode reformatar os dados ao criar novas colunas e adicionar fórmulas personalizadas.

Para formatar os carimbos de data/hora no ficheiro CSV exportado para trabalhar com o Excel:

  1. Crie uma nova coluna carimbo de data/hora e crie um formato personalizado para a mesma:

    yyyy/mm/dd hh:mm:ss

  2. Adicione a seguinte fórmula às células na nova coluna Carimbo de Data/Hora, alterando o valor da célula F2 para corresponder à sua coluna e linha:

    =(DATEVALUE(LEFT(RawErrorReport!F2,10))+TIMEVALUE(RIGHT(RawErrorReport!F2,8)))

Para dividir o campo Descrição em colunas separadas, siga estes passos, alterando o valor da célula F2 para corresponder à sua coluna e linha:

  1. Crie uma nova coluna com o nome Nome Abreviado ou algo semelhante e adicione a seguinte fórmula às células:

    =TRIM(LEFT(F2,FIND("(",F2)-1))

  2. Crie colunas nas quais os cabeçalhos da linha1 têm os mesmos nomes que os valores dos parâmetros e adicione a seguinte fórmula às células em cada uma das colunas:

    =IF(ISERROR(FIND("; " & H$1 & "=", SUBSTITUTE($F2,"(","; "))), "", MID($F2, FIND("; " & H$1 & "=", SUBSTITUTE($F2,"(","; ")) + (LEN(H$1) + 2), FIND("; ", SUBSTITUTE($F2,")","; "), FIND("; " & H$1 & "=", SUBSTITUTE($F2,"(","; "))) - FIND("; " & H$1 & "=", SUBSTITUTE($F2,"(","; ")) - (LEN(H$1) + 2)))