Post em Destaque

The FreeBSD Laptop Compatibility List

Para aqueles que querem comprar um notebook compatível com FreeBSD ou descobrir se o seu notebook é compatível. Esse site aqui é excelente para isso. Foi através dele que descobri porque meu notebook trava na BIOS quando tento instalar o FreeBSD 8. Esse site pode evitar muitas compras indesejadas....

Leia mais...

FreeBSD participando do Google Summer of Code program.

Posted by gondim | Posted in FreeBSD, Software Livre, Tecnologia | Posted on 22-04-2013

Tags:,

0

O Google Summer of Code é uma iniciativa do Google em apoiar o software Open Source apoiando programadores à desenvolverem código nas suas férias de verão.  🙂 As instituições participantes ganharão até US$5.000,00 sendo US$500,00 por aluno orientado. É uma troca de conhecimento e incentivo.

O FreeBSD vem anunciar que estará partipando do evento e com muito orgulho.  🙂 Abaixo o anuncio oficial feito pelo Gavin:

Hi all,

FreeBSD is pleased to announce that once again we have been selected to 
participate in the Google Summer of Code program.  This gives University 
students the opportunity to earn a $5000 USD stipend in exchange for 
working on Open Source software over their Summer break.  Students have 
around 12 weeks to work on their project, and will be mentored by existing 
FreeBSD committers.  Participating organisations will earn $500 USD per 
student mentored.

FreeBSD's organisation page may be found at 
http://www.google-melange.com/gsoc/org/google/gsoc2013/freebsd and a list 
of possible project ideas may be found at 
https://wiki.freebsd.org/IdeasPage .  Please note that projects do not 
have to come from the ideas list, and indeed students are encouraged to 
produce their own project ideas - the majority of past projects have been 
thought up by the particpants themselves.

Students are also encouraged to visit http://www.google-melange.com/ to 
view more details of the program, including eligibility requirements, and 
a list of other participating organisations.

Thanks,

Gavin

Share Button

Depurando programas no FreeBSD

Posted by Otacílio | Posted in Dicas | Posted on 15-04-2013

5

Introdução

 

Ao escrever um programa que esteja um pouco além do tradicional “Hello World!” o desenvolvedor precisa saber utilizar as ferramentas de depuração disponíveis no sistema. Sem elas, depurar um aplicativo que não seja básico é algo trabalhoso. Se programas básicos são trabalhosos de depurar, programas que utilizam apontadores podem tornar-se um verdadeiro suplício.

No FreeBSD estão disponíveis várias ferramentas de depuração, das quais, algumas serão abordadas.  São elas DDD, Valgrind e o recurso de cobertura de código do GCC.

 

Depurando programas com o DDD

 

O Data Display Debugger, ou DDD, é uma interface para o gdb, tornando o uso deste último bem mais amigável para o usuário. Para usar o DDD obviamente é necessário que o mesmo esteja presente no sistema. Para instalá-lo o usuário pode utilizar o ports do FreeBSD. Assim, pode-se executar os seguintes comandos para realizar a instalação:

# (cd /usr/ports/devel/ddd && make install clean)

 

Escrevendo o programa exemplo

 

Depois de instalar o DDD escreva o seguinte programa exemplo em C que implementa uma pilha, para em seguida depurá-lo.

#include <stdio.h>
#include <stdlib.h>

typedef struct no_s{
    int         payload;
    struct no_s    *next;
}no_t;

void push(no_t **pilha, int elemento){
    no_t    *aux;

    aux = malloc(sizeof(no_t));
    aux->payload = elemento;    
    aux->next = *pilha;    
    *pilha = aux;
}

int pop(no_t **pilha){
    no_t    *aux;
    
    aux = *pilha;   
    *pilha = (*pilha)->next;
    return aux->payload;
}

int main(int argc, char **argv){
    no_t    *pilha;
    int     elemento;

    printf(“Informe um elemento maior que 0 para empilhar e menor que 0 para desempilhar todos\n”);
    do{        
        scanf(“%u”, &elemento);
        if(elemento >= 0){
            push(&pilha, elemento);
        }
    }while(elemento >=0);    

    printf(“============================\n”);

    while(pilha != NULL){
        printf(“%u\n”, pop(&pilha));
    }
    
    return 0;
}

Salve este programa como pilha.c e compile o mesmo com o comando:

$ gcc -Wall -o pilha pilha.c

Atenção! Ao copiar o texto do browser, as aspas que o browser exibe não são as reconhecidas pelo compilador C, então você deve substitui-las manualmente.

O programa deve compilar sem nenhum erro.

Execute o programa e forneça as entradas 1, 2, 3, -1. O programa imprime as saídas 3, 2 e 1 e depois apresenta um erro.

$ ./pilha
Informe um elemento maior que 0 para empilhar e menor que 0 para desempilhar todos
1
2
3
-1
============================
3
2
1
Segmentation fault: 11 (imagem do núcleo gravada)

Para encontrar a causa da falha de segmento compile novamente o programa adicionando o parâmetro -g para que o GCC adicione os símbolos de depuração no executável.

$ gcc -Wall -g -o pilha pilha.c

Execute novamente o programa com os mesmos parâmetros de entrada: 1, 2, 3 e -1.

O programa termina novamente com um erro, sendo que dessa vez uma imagem de memória com os símbolos necessários para depuração foi criada. O arquivo com a imagem é o pilha.core.

 

Depurando o arquivo pilha.core

 

Execute o ddd informando o programa que será depurado.

$ ddd pilha

Em seguida abra o arquivo pilha.core utilizando as opções de menu “File->Open Core Dump…”

O DDD mostra exatamente a linha que causou o problema adicionando uma seta vermelha à mesma. Uma outra informação bastante útil é a pilha de chamadas de rotinas. Esta mostra o caminho que o programa seguiu até o momento em que executou a operação ilegal. Para visualizar a pilha de chamadas usa-se a opção de menu “Status->Backtrace…”.

backtrace_de_chamadas

 

 

 

 

 

 

A janela exibe a sequência de chamadas de todas as rotinas até o ponto em que o problema ocorreu, inclusive com a linha da rotina .

 

Adicionando um ponto de parada

 

Para adicionar o ponto de parada procure a linha com a seta vermelha do lado dela.  Clique com o botão direito e selecione “Set Breakpoint”. Execute novamente o programa teclando em F3, sendo que o cursor deve estar na janela de mensagens do DDD.

Dica: Eu gosto de executar o programa com a seguinte opção marcada: “Program->Run in Execution Window”.  Dessa forma o ddd sempre executa o programa em um terminal próprio impedindo a poluição que normalmente ocorre quando a entrada e saída de dados é feita diretamente na janela.

Durante a execução, o DDD vai pará-lo exatamente no ponto onde está configurado o breakpoint. Neste, pode-se iniciar a execução passo-a-passo. Para executar o programa linha por linha sem entrar nas chamadas de sub-rotina usa-se a tecla F5, para “entrar” nas chamadas de sub-rotina a tecla a ser usada é a F6. Para continuar a execução normalmente usa-se a tecla F9.

 

Visualizando o conteúdo de variáveis

 

Executar o programa passo a passo observando os valores das variáveis pode ajudar muito a encontrar o erro.  Para isto, neste programa, adiciona-se um ponto de parada na linha correspondente ao segundo while (linha 40). Para isso clique com o botão direito e selecione “Set Breakpoint” na inha 40 e remova o da linha 22 clicando com o botão direito na mesma e escolhendo a opção de menu “Disable Breakpoint” para desabilitar ou “Delete Breakpoint” para remover. Execute novamente  programa pressionando F3 (com o cursor na janela de mensagens do DDD) e entre com os valores 1, 2, 3, -1. O programa deve parar no local da placa de “STOP”.

Muito bem, para examinar o estado da lista encadeada utilizada na implementação da pilha, clique com o botão direito sobre a variável “pilha” e selecione “Display pilha”. A variável deve ser exibida na área destinada a exibição de variáveis. Nesta região, clique novamente com o botão direito sobre o quadro onde é exibida a variável “pilha” e selecione “Display *()”. Clique agora sobre o campo “next” do quadro apontado por “pilha” e selecione “Display *()”. Repita a operação sobre os quadros que vão surgindo inclusive para o quadro com o payload = 1. Sua tela deve estar como na imagem abaixo:

Captura_de_tela

 

 

 

 

 

Observe que o último campo “next” aponta para uma posição inválida diferente de NULL (0x0). Este é o erro então. O laço iterage até que o valor NULL seja encontrado, mas este nunca o é porque a variável não foi inicializada como tal. Para consertar o bug procure a linha 31 onde a variável “*pilha” é declara e substitua a linha por:

no_t    *pilha=NULL;

Compile o programa. Abra-o novamente no DDD usando a opção “File->Open Program…”  e execute-o com F3,  informando os mesmos valores de entrada. Quando o programa parar na placa “STOP” aperte F9 para continuar a execução. O erro não deverá ocorrer mais.

 

 Conclusões

 

Neste post foi tratado o básico da depuração de um programa C utilizando o software de interface gráfica para o gdb, o DDD. Com este, foi possível encontrar o erro que fazia com o que o programa pilha.c abortasse. Além disso, visualizou-se a lista encadeada utilizada na representação da pilha permitindo a fácil compreensão de como os dados estavam organizados na memória.  Isto é particularmente útil quando se está trabalhando com estruturas de dados que utilizam listas encadeadas.

 

Share Button