Je suis tombé sur un bug plutôt charmant que j'essaye d'enrouler ma tête autour. J'ai l'impression d'avoir déjà vu ça auparavant, mais cette fois je veux comprendre pourquoi cela se passe.Pourquoi ma valeur n'augmentera-t-elle pas? Mémoire piétinant/pépin de pile?
I ont:
int i;
int debug = 0;
for(i = 0; i < buf_end; i++) {
do_some_buffer_work();
if(something_is_true()) {
do_something_important();
printf("debug is %i, i is %i", debug++, i);
}
}
printf ("fin \ n");
et je reçois en sortie:
debug is 1, i is 55
debug is 2, i is 55
donc il y avait un point où la boucle a été exécuté deux fois avec la même valeur pour i. rien que je fais dans la boucle touche directement i. De plus, je doute que ce soit la mémoire traditionnelle qui piétine, car la valeur est toujours la même. Je me doutais bien qu'il avait quelque chose à l'origine du compteur de programme pour se déplacer (car parfois avec le mauvais vous reliant obtenir des bugs similaires,) jusqu'à ce que je l'ai fait le test suivant:
int i;
static int debug;
for(i = 0; i < buf_end; i++) {
do_some_buffer_work();
if(something_is_true()) {
do_something_important();
printf("debug is %i, i is %i\n", debug++, i++);
printf("debug is %i, i is %i\n", debug++, i++);
printf("debug is %i, i is %i\n", debug++, i++);
}
}
printf("end\n");
et je suis cette sortie intéressante:
debug is 0, i is 55
debug is 1, i is 56
debug is 2, i is 57
debug is 3, i is 55
debug is 4, i is 56
debug is 5, i is 57
end
Donc ici il est évident que deux itérations complètes avec le même j'ai exécuté, mais la variable de débogage n'a pas été affectée. Il semblerait que la valeur soit mise en cache et restaurée pour une raison quelconque. J'ai eu un pressentiment et changé la variable de débogage à la non-statique et obtenu ceci:
int i;
int debug = 0;
for(i = 0; i < buf_end; i++) {
do_some_buffer_work();
if(something_is_true()) {
do_something_important();
printf("debug is %i, i is %i\n", debug++, i++);
printf("debug is %i, i is %i\n", debug++, i++);
printf("debug is %i, i is %i\n", debug++, i++);
}
}
printf("end\n");
et je suis cette sortie intéressante:
debug is 0, i is 55
debug is 1, i is 56
debug is 2, i is 57
debug is 0, i is 55
debug is 1, i is 56
debug is 2, i is 57
end
Il semble donc que les variables qui vivent sur la pile sont réinitialisé au début de la 55e itération. Je suis sûr que le bug est dans un de ces appels do_something_important() - qui traitent de la lecture du tampon - mais ce bug a pris un caractère qui lui est propre et je pense que je dois un peu de respect pour en savoir plus sur sa nature avant de l'écraser. Donc, s'il vous plaît plutôt que d'essayer de m'aider à le réparer, faites-moi savoir si vous avez une idée de la raison pour laquelle cela se produit. Plus précisément, que peut-on changer dans l'état du programme pour «réinitialiser» des valeurs comme celle-ci? Edit: Je suis désolé si les gens sont agacés que j'ai laissé de côté les fonctions. Ils sont assez volumineux et ont des références à d'autres fonctions, mais la principale raison pour laquelle je l'ai laissée de côté est que je ne me soucie pas de résoudre ce problème; Je veux savoir comment je pourrais le recréer le plus simplement possible. 2e édition: Voici la fonction immédiate où les bleus se produisent. Y compris la fonction référencée et toutes les sous-fonctions et définitions est probablement autour de 500 lignes donc je ne le fais pas ici.
static int find_headers_search(FCALParseContext *fpc, uint8_t *buf, int buf_size,
int search_start)
{
FCALFrameInfo fi;
int end_offset = -1, size = 0, i;
uint8_t *header_buf;
int debug = 0;
for (i = 0; i < buf_size - 1; i++) {
if ((AV_RB16(buf + i) & 0xFFFE) == 0xFFF8) {
av_log(NULL,AV_LOG_DEBUG,"predebug%i i %i\n",debug, i);
header_buf = fcal_fifo_read_wrap(fpc, search_start + i,
MAX_FRAME_HEADER_SIZE,
&fpc->wrap_buf,
&fpc->wrap_buf_allocated_size);
if (frame_header_is_valid(header_buf, &fi)) {
av_log(NULL,AV_LOG_DEBUG,"frame num %u bufstart %u, size %u, end %u i %i\n", (unsigned int)fi.frame_or_sample_num,
search_start, buf_size, search_start + buf_size -1, i);
FCALHeaderMarker **end_handle = &fpc->headers;
size = 0;
while (*end_handle) {
end_offset = (*end_handle)->offset;
end_handle = &(*end_handle)->next;
size++;
}
*end_handle = av_mallocz(sizeof(FCALHeaderMarker));
if (!*end_handle) {
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't allocate FCALHeaderMarker\n");
return AVERROR(ENOMEM);
}
(*end_handle)->fi = fi;
(*end_handle)->offset = search_start + i;
/* The actual size of the linked list is now size + 1 */
update_sequences(fpc, size - FCAL_MAX_SEQUENTIAL_HEADERS,
FFMIN(size, FCAL_MAX_SEQUENTIAL_HEADERS),
*end_handle);
fpc->nb_headers_found++;
size++;
av_log(NULL,AV_LOG_DEBUG,"debug%i i %i\n",debug++, i++);
size = 0;
while (*end_handle) {
end_offset = (*end_handle)->offset;
end_handle = &(*end_handle)->next;
size++;
}
*end_handle = av_mallocz(sizeof(FCALHeaderMarker));
if (!*end_handle) {
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't allocate FCALHeaderMarker\n");
return AVERROR(ENOMEM);
}
(*end_handle)->fi = fi;
(*end_handle)->offset = search_start + i;
/* The actual size of the linked list is now size + 1 */
update_sequences(fpc, size - FCAL_MAX_SEQUENTIAL_HEADERS,
FFMIN(size, FCAL_MAX_SEQUENTIAL_HEADERS),
*end_handle);
fpc->nb_headers_found++;
size++;
av_log(NULL,AV_LOG_DEBUG,"debug%i i %i\n",debug++, i++);
av_log(NULL,AV_LOG_DEBUG,"debug%i i %i\n",debug++, i++);
av_log(NULL,AV_LOG_DEBUG,"debug%i i %i\n",debug++, i++);
}
}
}
return size;
}
Eh bien, vous êtes presque certainement en train de jeter la pile dans l'une de vos fonctions appelées. Sans vrai code, il n'est plus possible d'en dire plus. Le conseil serait d'utiliser un débogueur pour regarder 'debug', et ensuite de passer à travers jusqu'à ce qu'il change de façon inattendue. –
Merci. Je devrais préciser que je veux juste savoir comment battre la pile comme ça. Que dois-je faire pour obtenir un résultat similaire? –
@fsmc: Déclare un tableau sur la pile et écris la fin. –