我遇到了一只非常迷人的虫子,我想把我的头绕起来。
我觉得我以前见过这种情况,但这次我想知道为什么会发生这种情况。
我有:
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(“结束\n”);
我得到输出:
debug is 1, i is 55
debug is 2, i is 55
所以有一个点,循环被执行了两次,其中i的值相同。
我在循环中所做的任何事情都不会直接接触到我,而且我怀疑这是传统的内存跺脚,因为它的值总是相同的。我怀疑这是导致程序计数器移动的原因(因为有时链接不好会导致类似的错误),直到我执行以下测试:
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");
我得到了这个有趣的输出:
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
很明显,我已经执行了两次相同的完整迭代,但是调试变量没有受到影响。由于某种原因,值似乎正在被缓存和还原。我有预感,把调试变量改成了非静态的,得到了:
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");
我得到了这个有趣的输出:
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
所以看起来栈中的变量被重置为第55个变量的开头。
迭代。
我确信这个bug在其中一个do-something _-important()调用中——处理缓冲区读取——但是这个bug有它自己的特点,我想在我压扁它之前我应该先了解它的本质。
所以,请不要试图帮助我解决它,如果你有一些线索,告诉我它发生的原因。更具体地说,在程序状态中什么可以更改为“重置”值?
编辑:如果有人因为我遗漏了这些功能而感到恼火,我很抱歉。它们非常大,并且引用了其他函数,但是我之所以不考虑它,主要是因为我不关心如何解决这个问题;我想知道如何以最简单的方式重新创建它。
第二次编辑:这是蓝调发生的直接功能。包括引用的函数以及所有子函数和定义,大概有500行左右,所以我不在这里做。
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;
}