Archives pour la catégorie ‘C’

Glib : utiliser valgrind pour détecter les memory leaks

Une petite note pour détecter les problèmes mémoire d’un programme utilisant la Glib avec Valgrind.

Les options à fournir sont les suivantes :

bhuisgen@debian:~/projects/sample/$ G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=full --leak-resolution=high --num-callers=20 ./program

Malgré la désactivation des optimisations de la Glib, notamment les pools mémoires, Valgrind détecte encore de nombreux problèmes. Dans un tel cas, seul un fichier de suppression permet de désactiver les erreurs n’ayant aucun rapport avec votre code. Le projet GNOME.supp a pour but de regrouper un ensemble de fichiers prêts à l’emploi. L’utilisation est alors aisée :

bhuisgen@debian:~/projects$ git clone https://github.com/dtrebbien/GNOME.supp
bhuisgen@debian:~/projects/GNOME.supp$ cd GNOME.supp
bhuisgen@debian:~/projects/GNOME.supp$ make

On indique ensuite le fichier de suppression à Valgrind :

bhuisgen@debian:~/projects/sample/$ G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=full --leak-resolution=high --num-callers=20 --suppressions=../GNOME.supp/glib.supp ./program

Inotify : monitorer les actions effectuées dans un répertoire

Exemple en langage C pour détecter la création de sous-répertoires grâce à inotify :

#include <sys/inotify.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

int fd;
int wd;

void
sigint_handler(int signum)
{
	(void) signum;

	if (inotify_rm_watch(fd, wd))
	{
		perror("inotify_rm_watch");
		exit(EXIT_FAILURE);
	}

	if (close(fd) < 0)
	{
		perror("close");
		exit(EXIT_FAILURE);
	}

	exit(EXIT_SUCCESS);
}

int
is_directory(char *path)
{
	if (path == NULL)
		return -1;

	struct stat s;

	if (stat(path, &s) < 0)
	{
		perror("stat");

		return -1;
	}

	if (s.st_mode & S_IFDIR)
		return 1;

	return 0;
}

int
main(int argc, char* argv[])
{
	fd_set fds;
	size_t r;
	char buf[8192], buf2[8192];
	struct inotify_event *event;

	if (argc != 2)
	{
		fprintf(stderr, "usage: %s <DIR>\n", argv[0]);

		return EXIT_FAILURE;
	}

	fd = inotify_init();
	if (fd < 0)
	{
		perror("inotify_init");

		return EXIT_FAILURE;
	}

	wd = inotify_add_watch(fd, argv[1], IN_CREATE);
	if (wd < 0)
	{
		perror("inotify_add_watch");

		return EXIT_FAILURE;
	}

	printf("Directory watched: %s\n", argv[1]);

	signal(SIGINT, sigint_handler);

	while (1)
	{
		FD_ZERO(&fds);
		FD_SET(fd, &fds);

		if (select(fd + 1, &fds, NULL, NULL, 0) <= 0)
		{
			continue;
		}

		r = read(fd, buf, sizeof(buf));
		if (r <= 0)
		{
			perror("read");

			return EXIT_FAILURE;
		}

		event = (struct inotify_event *)buf;
		if (!(event->mask & IN_CREATE) || (event->len < 0))
			continue;

		snprintf(buf2, sizeof(buf2), "%s%s", argv[1], event->name);

		if (is_directory(buf2) < 0)
			continue;

		printf("New directory created %s\n", event->name);
	}

	return EXIT_FAILURE;
}
Haut de page