工具链(编译器/调试器)中的错误?

发布于 2024-12-04 06:37:01 字数 905 浏览 0 评论 0原文

gdb、gcc 或两者都有严重错误,我不知道是什么。我创建了一个 POC 来在 gcc (GCC) 4.6.1 20110819(预发布)GNU gdb (GDB) 7.3.50.20110908-cvs 上重现它 - 是的,这个是CVS版本,因为我遇到了这个问题http://sourceware.org/bugzilla/show_bug.cgi?id=12435,但是我还使用 GNU gdb (GDB) 7.3.1 进行了测试,其行为是相同的。

现在到 POC:https://gist.github.com/1211017 可以在线观察问题33

在我看来,*c->foos[i] 应该求值为第 i 个 foo 的地址,如第 21 行所示。但是可执行文件崩溃了,如您在输出。

有谁知道出了什么问题吗?欢迎 ASM 级别或 GCC 内部的解释。

附录

  1. 数据结构不允许更改 - 它们不属于我的代码,我必须与它们进行互操作。
  2. 代码 *c->foos[i] 用于与旧版本的 gcc 一起使用。
  3. dump_container 必须有一个 container* 作为参数 - 这个函数也不属于我的代码

另外值得一提的是:*c->foos[i]< /code> 曾经工作过。

There is something terribly wrong with either gdb, gcc or both, and I don't know what. I've created a POC to reproduce it on gcc (GCC) 4.6.1 20110819 (prerelease) and GNU gdb (GDB) 7.3.50.20110908-cvs - yes, this is the CVS version, because I was running into this issue http://sourceware.org/bugzilla/show_bug.cgi?id=12435, however I've also tested with GNU gdb (GDB) 7.3.1 and it behaves the same.

Now to the POC: https://gist.github.com/1211017 the problem can be observed on line 33

In my opinion, *c->foos[i] should evaluate to the address of the i-th foo, as displayed by line 21. But the executable crashes, as you can see in the output.

Does anyone know what is wrong? An explanation at either the ASM level or GCC internals would be welcome.

Addendum:

  1. The data structures are not allowed to change - they don't belong to my code, I have to interoperate with them.
  2. The code *c->foos[i] used to work with older versions of gcc.
  3. dump_container must have as parameter a container* - this function doesn't belong to my code either

Also worth mentioning: *c->foos[i] used to work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

日裸衫吸 2024-12-11 06:37:01

通过永远有用的 valgrind 运行你的代码说:

==16066== Use of uninitialised value of size 8
==16066==    at 0x40061B: dump_container (bug.c:33)
==16066==    by 0x400726: main (bug.c:49)
==16066== 
==16066== Invalid read of size 4
==16066==    at 0x400620: dump_container (stdio2.h:105)
==16066==    by 0x400726: main (bug.c:49)
==16066==  Address 0x89485ed18949ed39 is not stack'd, malloc'd or (recently) free'd
==16066== 
==16066== 
==16066== Process terminating with default action of signal 11 (SIGSEGV)
==16066==  General Protection Fault
==16066==    at 0x400620: dump_container (stdio2.h:105)
==16066==    by 0x400726: main (bug.c:49)
==16066== 

我的猜测是你会在你自己的代码中而不是编译器或调试器中找到错误。

编辑或者既然你想让我为你拼写出来,请将第 33 行更改为

printf("foo[%d]=%d at %p\n", i, (*c->foos)[i]->i, (void*) (*c->foos)[i]);

Running your code through the ever helpful valgrind says:

==16066== Use of uninitialised value of size 8
==16066==    at 0x40061B: dump_container (bug.c:33)
==16066==    by 0x400726: main (bug.c:49)
==16066== 
==16066== Invalid read of size 4
==16066==    at 0x400620: dump_container (stdio2.h:105)
==16066==    by 0x400726: main (bug.c:49)
==16066==  Address 0x89485ed18949ed39 is not stack'd, malloc'd or (recently) free'd
==16066== 
==16066== 
==16066== Process terminating with default action of signal 11 (SIGSEGV)
==16066==  General Protection Fault
==16066==    at 0x400620: dump_container (stdio2.h:105)
==16066==    by 0x400726: main (bug.c:49)
==16066== 

My guess is that you'll find the bug in your own code rather than the compiler or debugger.

EDIT Or since you want me to spell it out for you, change line 33 to

printf("foo[%d]=%d at %p\n", i, (*c->foos)[i]->i, (void*) (*c->foos)[i]);
无语# 2024-12-11 06:37:01

我不明白 *c->foos[i] 是如何工作的,c->foos 给出了一个指向数组的指针(指向指针块的指针)(指针的指针) ),根据第 43 行,在执行 c->foos[i] 时,您没有访问数组的元素。 (*c->foos)[i] 应该可以...

看看 C 运算符优先级表

I don't understand how *c->foos[i] would have ever worked, c->foos gives a pointer to an array (a pointer to a bloc of pointers) (of pointers), according to line 43, when doing c->foos[i] you're not accessing to an element of the array. (*c->foos)[i] should work...

Take a look at the C Operator Precedence Table.

疯了 2024-12-11 06:37:01

在我看来, *c->foos[i] 应该评估为第 i 个地址
foo,如第 21 行所示。

不。如果这就是您的意思,您应该使用 &c->foos[i]。您的版本取消引用了第 i 个 foo,这很容易导致

但是可执行文件崩溃了,正如您在输出中看到的那样。

In my opinion, *c->foos[i] should evaluate to the address of the i-th
foo, as displayed by line 21.

No. If that is what you mean, you should use &c->foos[i]. Your version dereferences the i-th foo, what easily can lead to

But the executable crashes, as you can see in the output.

.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文