Comment peut malloc() à cause d'un SIGSEGV?
J'ai un drôle de bug dans mon programme, il me semble que la fonction malloc() est à l'origine d'un SIGSEGV, qui, autant que ma compréhension va n'a pas de sens. Je suis l'aide d'une bibliothèque appelée simclist pour les listes dynamiques.
Ici est une structure qui est référencé plus tard:
typedef struct {
int msgid;
int status;
void* udata;
list_t queue;
} msg_t;
Et voici le code:
msg_t* msg = (msg_t*) malloc( sizeof( msg_t ) );
msg->msgid = msgid;
msg->status = MSG_STAT_NEW;
msg->udata = udata;
list_init( &msg->queue );
list_init
est où le programme ne parvient pas, voici le code pour list_init:
/* list initialization */
int list_init(list_t *restrict l) {
if (l == NULL) return -1;
srandom((unsigned long)time(NULL));
l->numels = 0;
/* head/tail sentinels and mid pointer */
l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
l->head_sentinel->next = l->tail_sentinel;
l->tail_sentinel->prev = l->head_sentinel;
l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL;
l->head_sentinel->data = l->tail_sentinel->data = NULL;
/* iteration attributes */
l->iter_active = 0;
l->iter_pos = 0;
l->iter_curentry = NULL;
/* free-list attributes */
l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *));
l->spareelsnum = 0;
#ifdef SIMCLIST_WITH_THREADS
l->threadcount = 0;
#endif
list_attributes_setdefaults(l);
assert(list_repOk(l));
assert(list_attrOk(l));
return 0;
}
la ligne l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS *
est où le SIGSEGV est causée en fonction de la trace de la pile. Je suis à l'aide de gdb/nemiver pour le débogage, mais je suis à une perte. La première fois que cette fonction est appelée, elle fonctionne très bien mais il échoue toujours la deuxième fois. Comment peut malloc() à cause d'un SIGSEGV?
C'est la trace de la pile:
#0 ?? () at :0
#1 malloc () at :0
#2 list_init (l=0x104f290) at src/simclist.c:205
#3 msg_new (msg_switch=0x1050dc0, msgid=8, udata=0x0) at src/msg_switch.c:218
#4 exread (sockfd=8, conn_info=0x104e0e0) at src/zimr-proxy/main.c:504
#5 zfd_select (tv_sec=0) at src/zfildes.c:124
#6 main (argc=3, argv=0x7fffcabe44f8) at src/zimr-proxy/main.c:210
Toute aide ou idée est très apprécié!
list_t
déclaré?Comme une note côté, l'appel de
srandom()
plus d'une fois n'est pas recommandé. Pour éviter à l'avenir de bugs, même dans list_init()
est connu pour être appelé qu'une seule fois, vous devez déplacer que le semis à la même place, c'est plus évidemment exécutée une fois comme près de la haut de main()
.OriginalL'auteur user19745 | 2009-09-17
Vous devez vous connecter pour publier un commentaire.
malloc
erreur de segmentation peut par exemple lorsque le segment est endommagé. Vérifiez que vous n'êtes pas écrire n'importe quoi au-delà des limites de toute allocation précédente.J'ai été faire un sigsegv lors de l'appel à free(). J'ai couru le code sous valgrind et il a montré que j'avais écrit au-delà d'un tampon et corrompu le tas.
OriginalL'auteur laalto
Probablement violation de mémoire se produit dans d'autres partie de votre code. Si vous êtes sous Linux, vous devriez certainement essayer valgrind. Je n'aurais jamais confiance à mes propres programmes en C, sauf si il passe valgrind.
EDIT: un autre outil utile est Clôture électrique. La Glibc fournit également la MALLOC_CHECK_ variable d'environnement pour aider à résoudre les problèmes de mémoire. Ces deux méthodes n'ont pas d'incidence sur la vitesse de course autant que valgrind.
OriginalL'auteur user172818
Vous avez probablement corrompu tas quelque part avant cet appel par un dépassement de tampon ou en appelant
free
avec un pointeur qui n'a pas été affecté parmalloc
(ou qui a déjà été libéré).Si les structures de données internes utilisées par malloc corrompus de cette façon, la fonction malloc est à l'aide de données non valides et peut se bloquer.
OriginalL'auteur sth
Il y a une myriade de façons de déclencher un core dump de
malloc()
(etrealloc()
etcalloc()
). Elles comprennent:malloc()
a été de garder là-bas).malloc()
a été de garder là-bas).malloc()
. Dans un mélange de C et de C++ programme, qui comprennent la libération de la mémoire allouée en C++ parnew
.malloc()
- qui est un cas particulier du cas précédent.À l'aide d'un diagnostic version de
malloc()
ou permettant des diagnostics dans votre système de la version standard, peut vous aider à identifier certains de ces problèmes. Par exemple, il peut être en mesure de détecter les petites underflows et les débordements (parce qu'il alloue de l'espace supplémentaire pour fournir une zone tampon autour de l'espace que vous avez demandé), et il peut sans doute de détecter les tentatives pour libérer de la mémoire qui n'a pas attribué ou qui a déjà été libéré ou des pointeurs de la partie chemin à travers l'espace alloué - parce qu'il va stocker les informations séparément à partir de l'espace alloué. Le coût est que la version de débogage prend plus d'espace. Vraiment une bonne allocation sera capable d'enregistrer la trace de la pile et les numéros de ligne de vous dire où l'allocation est produite dans votre code, ou là où la première s'est produite.OriginalL'auteur Jonathan Leffler
Vous devriez essayer de déboguer ce code dans l'isolement, pour voir si le problème est en fait situé à l'endroit où l'erreur est généré. (Je soupçonne qu'il ne l'est pas).
Cela signifie:
#1: Compiler le code avec -O0, assurez-vous que gdb est de numérotation de ligne de l'information.
#2: Écrire un test unitaire qui appelle cette partie du code.
Ma conjecture est que le code fonctionne correctement lorsqu'ils sont utilisés séparément. Vous pouvez ensuite tester votre autres modules de la même manière, jusqu'à ce que vous trouver ce qui provoque le bug.
Utilisation de Valgrind, comme d'autres l'ont suggéré, est aussi une très bonne idée.
OriginalL'auteur Jørgen Fogh
Le code est problématique. Si la fonction malloc renvoie la valeur NULL, ce cas n'est pas pris en charge correctement dans votre code. Il vous suffit de supposer que la mémoire a été allouée pour vous quand il fait n'a pas été. Cela peut provoquer une corruption de mémoire.
OriginalL'auteur steve