.:: Jorge Pereira ::.

"UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity."

Good explanations to have successful with GIT branching model.

git-model@2x

The Infamous Windows “Hello World” Program (A good and archaeological post by Petzold)

ProgRefPg13

seven years!

No comments

Even through times of high and low with the published post… here we are!! today, is a birthday of my blog, we seven years of life!! =]

Aconteceu no último dia 25 de maio o 10° Encontro de Programadores de C & C++, o evento foi muito bacana e contou com uma grade de palestras bem diversificada. abaixo segue lista completa de todas as palestras e os devidos artigos e materiais utilizados pelos palestrantes!

C/C++ Brasil

Explorando Windows 32 em Windows 64 — Fernando Roberto da Silva
Um sistema operacional Windows de 64 bits é capaz de executar programas de 32 bits de forma completamente transparente, mas para alguns, isso pode gerar comportamentos inesperados. Este artigo descreve de maneira prática como o Windows é capaz de realizar essa tarefa de forma a permitir que programas de 32 bits possam coexistir com programas de 64 bits, explicando tais estranhezas e justificando-as. Como drivers de kernel se encaixam nessa história e quais os possíveis problemas podem ser observados na migração de drivers 32 bits para 64 bits.
  
Programação em GPU utilizando OpenCL — André Tupinambá
O OpenCL é um padrão aberto, definido pelo Khronos Group, para programação em dispositivo genérico. Hoje ele é suportado pelos principais fornecedores de GPUs (Nvidia, AMD e, recentemente, Intel) e CPUs (Intel, AMD e IBM); e espera-se que outros processadores tenham suporte em breve, pois já existem chips para celulares homologados, como o CPU ARMv7 com Mali-T604 GPU, e outros chips, como o FPGA da empresa Altera, em desenvolvimento. O framework OpenCL é composto por uma linguagem, uma API, bibliotecas e um sistema de suporte para o desenvolvimento. A linguagem é baseada no padrão C99 com algumas extensões para suportar os modelos de memória e execução do OpenCL. Este artigo descreve o que é programação para GPU e apresenta a plataforma OpenCL, com um estudo de caso.

Interoperando C++ e Java usando meta-programação em C++ — Felipe Magno de Almeida
Construção de middlewares baseados na tecnologia Java exigem por muitas vezes a interação com recursos específicos da plataforma, interagindo normalmente com interfaces em linguagem C ou C++. Essas interações com código nativo precisam ser feitas através da Java Native Interface na implementação OpenJDK do Java, que trás diversas dificuldades para o programador e tornam a tarefa de desenvolvimento desnecessariamente árdua, e o resultado dificilmente livre de bugs. Abordarei sobre o uso e construção de uma biblioteca que ajudará o usuário a mitigar os problemas decorrentes do uso direto da Java Native Interface e será feita uma comparação dessa biblioteca com outras soluções de binding como as bibliotecas luabind e Boost.Python, assim como suas diferenças intrínsecas por conta da tipagem estática da linguagem Java.

Kernel Insecurity Vectors — Carlos Carvalho e Alan Silva
O estudo das falhas de segurança pode ser tão geral quanto um buffer overflow em qualquer programa ou tão específico quanto defeitos na implementação do módulo X na versão Y da máquina virtual Z do fabricante W. Neste trabalho demonstramos falhas de segurança e métodos de exploração no kernel do Linux, mostrando a arquitetura e revisando algumas técnicas já conhecidas, para com isso tentar encontrar um caminho que resulte em novos métodos para explorar essas falhas, que chamamos vetores de exploração.

Durante esses dias discutindo com um amigo sobre o acesso a memoria de forma atômica, e durante alguns testes e provas de conceito surgiram alguns problemas devido ao esquema de synchronize ser um recurso dependente da plataforma e compilador.

Como a chamada __sync_synchronize() e nativa no compilador, e dependendo da versão não vai estar disponivel. segue abaixo uma solução:

Contornando o Problema

#include <stdio.h>

#ifdef NO_SYNC_SYNCHRONIZE
#warning "Ops! Don't have native __sync_synchronize(), using the asm hardcode."
#    define __sync_synchronize() __asm__ __volatile__ ( "rep;nop": : :"memory" );
#endif

#define my__sync_synchronize() __sync_synchronize()

int
main ()
{
    int foo = 0;

    printf ("Trecho abaixo será atômico!\n");
    foo = 0xd34db33f;
    my__sync_synchronize ();

    return 0;
}

* Levando em consideração o uso sobre a plataforma x86.

Mais sobre o assunto.

Seja Elegante

Talvez possa ser algo que passe despercebido por vários desenvolvedores, porém dúvido quem nunca tenha se deparado com mensagens de “log” vagas ou sem nenhum nexo ou bem pior, como mensagens idênticas replicadas por várias partes do código! :shock:
A algum tempo atrás estava trabalhando em um projeto em que um respectivo desenvolvedor da equipe possuia o costume de espalhar ou replicar centenas de printf() pelo código com mensagens tipo!

printf(“!!! FULANO – Aqui!!!”);

ou

printf(“!!! FULANO – Arquivo.cpp:  Aqui!!!\n”);

Precisa falar que isto e pessímo? Certo que e preciso um bom senso com o uso de mensagens de depuração pois dependendo ao invés de ajudar podem só atrapalhar. principalmente quando você necessita ter controle sobre tais mensagens, como por exemplo obter a localização da mensagem através do nome da função, arquivo e linha.

Lembrando que dependendo da situação e contexto eu sou a favor de utilizar o pragma no compilador ativando o “poison” desativando dentre várias funções o printf (), evitando de ter espalhada pelo sistema! Futuramente um post sobre o poison.

O pré-processador do GCC oferece (*) várias macros, as que irei utilizar em questão são:

  • __FILE__ : Substituída pelo nome do arquivo.
  • __PRETTY_FUNCTION__ : Substituídas pelo nome nome da função.
  • __LINE__ : Substituída pelo número da linha de código.

(*) Mais detalhes sobre as macros do GCC.

A utilização dessas macros irá facilitar a localização das mensagens de depuração, Abaixo um simples exemplo demonstrado em debug1.c.

/**
 * By Jorge Pereira <jpereiran@gmail.com>
 * Date: Tue Jun 29 02:51:44 BRT 2010
 */

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

// Macro condicional
#ifdef DEBUG
#	warning "Debug is enabled"
#	define TRACE_DEBUG(fmt, ...) \
	fprintf(stderr, " ** DEBUG: %s:%d %s(): "fmt"\n", \
	__FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)
#else
#	warning "Debug is disabled"
#	define TRACE_DEBUG(fmt, ...)
#endif

#define MAX_STRING 5 /* tamanho maximo de uma string */

// Função simples de exemplo...
void
show_name (const char* name,
		   size_t len)
{
	size_t offset = len;

	// Verificação qualquer...
	if (len > MAX_STRING)
	{
		// Abaixo mensagem de depuração, perceba que ela será ativada apenas
                // quando em tempo de compilação você ativar a macro "DEBUG"
		TRACE_DEBUG ("Ooops! Tamanho da string(%d) e excedeu o limite(%d)...",
			len, MAX_STRING);
		offset = MAX_STRING;
	}

	// Manipulação qualquer...
	write (STDOUT_FILENO, name, offset);
	write (STDOUT_FILENO, "\n", 1);
}

int
main (int argc, char* argv[])
{
	if (argc < 2)
	{
		printf ("Usage: %s <string>\n", argv[0]);
		exit (1);
	}

	show_name (argv[1], strlen (argv[1]));

	return 0;
}

Com este exemplo básico em mãos, vamos compilar e executar.

[jpereira@miracleworld Codes]$ gcc -Wall -o debug1 debug1.c
debug1.c:18:3: warning: #warning "Debug is disabled"
[jpereira@miracleworld Codes]$ ./debug1 "Jorge"
Jorge
[jpereira@miracleworld Codes]$ ./debug1 "Jorge Pereira"
Jorge
[jpereira@miracleworld Codes]$

Imagine que seu sistema possui inúmeros arquivos e você precisa em determinados pontos obter o máximo de informação sobre as mensagens de depuração, talvez seja interessante ter além de uma mensagem objetiva obter juntamente o nome da função, arquivo e linha de onde foi invocada tal mensagem.

[jpereira@miracleworld Codes]$ gcc -Wall -DDEBUG -o debug1 debug1.c
debug1.c:13:3: warning: #warning "Debug is enabled"
[jpereira@miracleworld Codes]$ ./debug1 "Jorge"
Jorge
[jpereira@miracleworld Codes]$ ./debug1 "Jorge Pereira"
 ** DEBUG: debug1.c:36 show_name(): Ooops! Tamanho da string(13) e excedeu o limite(5)...
Jorge
[jpereira@miracleworld Codes]$

Agora veja situação que você está trabalhando em um sistema com várias checagens complexas de cenários “nada convencionais” em que você não tem certeza se vai acontecer sempre ou não.
Sem falar que torna-se um atrativo a possibilidade de você poder ativar/desativar o simples mecanismo, como por exemplo poder criar macros para depuração de componentes específicos (ex.: relacionadas a sockets, I/O, sgdb, …), isto poderá facilitar a identificação e remoção de bugs.

Lembrando que este e o primeiro post entre vários que pretendo publicar relacionados a sugestões e técnicas de depuração. Fique de olho na segunda parte desta saga em que irei explicar uma mais dinâmica do mesmo assunto abordado neste post associando ao uso de variáveis de ambiente.
Dúvidas e Sugestões, são sempre bem vindas! ;)

Autor: Jorge Pereira