Pergunta

Eu estou tomando minha primeira rachadura em escrever algum código do kernel do Linux, e eu estou batendo um kernel panic estranho.

Eu tenho uma lista ligada estou mantendo com o kernel built-in macros (include / linux / list.h). Se a lista estiver vazia, eu alocar uma instância da seguinte estrutura:

struct time_span
{
   struct timeval start;
   struct timeval end;
};

e apontar para ele com um ponteiro chamado "tmp". Acrescento tmp para a lista Eu estou mantendo com list_add_tail ().

Mais tarde, se a lista não está vazia (Eu estou tentando de teste com um item da lista para simplificar a depuração), que apontam para o primeiro item na lista com tmp e tente imprimir o conteúdo de tmp-> final .tv_sec. Infelizmente, isso faz com que um kernel panic.

tmp não é NULL (eu verificar em tempo de execução) e nem é "fim tmp->" (eu sou capaz de imprimir ambos). É só quando tentar acessar um dos campos no "fim" que eu recebo um kernel panic. Eu nunca vi algo assim antes? - Alguém tem alguma idéia

Obrigado por qualquer ajuda!

------- EDIT ------

Exemplo de código (este vidas em uma função que será chamada repetidamente):

// .........
struct timeval now_tv;
do_gettimeofday(&now_tv);
if(!list_empty(&(my_list.time_list)))
    {
        tmp = list_first_entry(&(my_list.time_list), struct time_span, time_list);
        if(tmp != NULL)
        {
                    tmp->end.tv_sec = now_tv.tv_sec; // THIS BREAKS
                                                     // Attempting to print "tmp->end.tv_sec" also breaks.
            tmp->end.tv_usec = now_tv.tv_usec;
        }
    }

        // .........

    if(list_empty(&(my_list.time_list)))
        {
        new_time_span = (struct time_span *) kmalloc(sizeof(struct time_span), GFP_KERNEL);
        INIT_LIST_HEAD(&(new_time_span->time_list));
        list_add_tail(&(new_time_span->time_list), &(my_list.time_list));
            do_gettimeofday(&(new_time_span->start));
    }

    // ........
Foi útil?

Solução

Você está perdendo alguns fundamentos sobre listas Linux vinculados. O seguinte deve mudar:

struct time_span
{
   struct timeval start;
   struct timeval end;
};

Para:

struct time_span
{
   struct timeval start;
   struct timeval end;
   struct list_head time_list;
}

Ao usar Linux ligada listas que você deve colocar o list_head struct dentro de sua estrutura que você quer uma lista de.
No código abaixo, você está alocando um tipo struct time_span e referenciando uma variável chamada time_list dentro do new_time_span variável alocada ... mas você não ter acrescentado que a sua estrutura acima.

// .........
struct timeval now_tv;
do_gettimeofday(&now_tv);
if(!list_empty(&(my_list.time_list)))
    {
        tmp = list_first_entry(&(my_list.time_list), struct time_span, time_list);
        if(tmp != NULL)
        {
                    tmp->end.tv_sec = now_tv.tv_sec; // THIS BREAKS
                                                     // Attempting to print "tmp->end.tv_sec" also breaks.
                tmp->end.tv_usec = now_tv.tv_usec;
        }
    }

Com base nas informações que você forneceu, eu não sei por que as quebras acima. Talvez seja apenas que tmp é um ponteiro apontando para o lixo e é por isso que deixa de funcionar? Se você tem uma configuração depurador de kernel é fácil de verificar.

        // .........

    if(list_empty(&(my_list.time_list)))
        {
        new_time_span = (struct time_span *) kmalloc(sizeof(struct time_span), GFP_KERNEL);
        INIT_LIST_HEAD(&(new_time_span->time_list));
        list_add_tail(&(new_time_span->time_list), &(my_list.time_list));
            do_gettimeofday(&(new_time_span->start));
    }

    // ........

Aqui estão alguns bons artigos que devem ajudar:
http://kernelnewbies.org/FAQ/LinkedLists
http://sumanadak.blogspot.com/2006/09/ linux-kernel-linked-list.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top