【问题标题】:Can a program with an empty main() allocate memory?具有空 main() 的程序可以分配内存吗?
【发布时间】:2015-11-22 21:15:15
【问题描述】:

我一直在寻找与-lcairo-lX11 链接的程序中的内存问题。最后,我决定注释掉我的main() 中的所有行,并确保valgrind 是快乐的。令我惊讶的是,它不是:

==7570== Memcheck, a memory error detector
==7570== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7570== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==7570== Command: ./Test
==7570== 
==7570== 
==7570== HEAP SUMMARY:
==7570==     in use at exit: 10,360 bytes in 5 blocks
==7570==   total heap usage: 5 allocs, 0 frees, 10,360 bytes allocated
==7570== 
==7570== 2,072 bytes in 1 blocks are still reachable in loss record 1 of 5
==7570==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7570==    by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FCBACE: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FCD585: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x4010139: call_init.part.0 (dl-init.c:78)
==7570==    by 0x4010222: _dl_init (dl-init.c:36)
==7570==    by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7570== 
==7570== 2,072 bytes in 1 blocks are still reachable in loss record 2 of 5
==7570==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7570==    by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FCA61F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FCD5A0: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x4010139: call_init.part.0 (dl-init.c:78)
==7570==    by 0x4010222: _dl_init (dl-init.c:36)
==7570==    by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7570== 
==7570== 2,072 bytes in 1 blocks are still reachable in loss record 3 of 5
==7570==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7570==    by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FE5A8F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FBC1A5: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FCD5AB: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x4010139: call_init.part.0 (dl-init.c:78)
==7570==    by 0x4010222: _dl_init (dl-init.c:36)
==7570==    by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7570== 
==7570== 2,072 bytes in 1 blocks are still reachable in loss record 4 of 5
==7570==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7570==    by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x60053CF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FCD5AB: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x4010139: call_init.part.0 (dl-init.c:78)
==7570==    by 0x4010222: _dl_init (dl-init.c:36)
==7570==    by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7570== 
==7570== 2,072 bytes in 1 blocks are still reachable in loss record 5 of 5
==7570==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7570==    by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5FCFCBF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7570==    by 0x4010139: call_init.part.0 (dl-init.c:78)
==7570==    by 0x4010222: _dl_init (dl-init.c:36)
==7570==    by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7570== 
==7570== LEAK SUMMARY:
==7570==    definitely lost: 0 bytes in 0 blocks
==7570==    indirectly lost: 0 bytes in 0 blocks
==7570==      possibly lost: 0 bytes in 0 blocks
==7570==    still reachable: 10,360 bytes in 5 blocks
==7570==         suppressed: 0 bytes in 0 blocks
==7570== 
==7570== For counts of detected and suppressed errors, rerun with: -v
==7570== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

带有空main() 的程序可以分配内存并最终得到一些可访问的块吗?有没有办法摆脱这个奇怪的问题?

【问题讨论】:

  • 您要链接的库中可能存在静态对象。你只需要记下这份报告,并在寻找真实代码的漏洞时打折这些条目。
  • 对。在这个特定库的情况下是否有已知的解决方案,即pixman
  • 我不知道。如果它是开源的,您可以尝试自己构建并进行调查。

标签: c++ pixman


【解决方案1】:

是的。这是可能的。

一种方法是您链接的库中可能存在一些静态对象。 @M.M 已经指出了这一点

另一种方法是,如果您要链接到共享库,没有静态对象,并且此类库中的某些函数使用 __attribute__((constructor)) 。该属性使这些函数在 main() 之前执行(仅适用于 gcc),因此您会看到内存分配。如果在您的程序中使用这些函数,则库主要使用这些函数来声明有关其函数的某些属性。有关这些属性的更多详细信息,您可以参考:

http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

【讨论】:

  • 谢谢。这很有启发性。但是,听起来解决问题的唯一方法是深入了解pixman 的源代码,我并不急于这样做。如果实际使用pixman(直接或间接,例如通过链接Cairo)的人能够阐明正确的用法,从而获得全新的结果,我将不胜感激。
  • 虽然我不使用 pixman,但通常删除该属性不会造成很大的损害,因为它主要用于编译器优化。删除 __attribute__((constructor)),通常不会影响结果,只会导致编译器优化较差。如果该库也设计用于非 GCC 编译器,那么您可以在没有 gcc 的情况下使用该库,由于这些属性,这不会导致任何开销。静态对象很难避免,因为它们大多是底层所固有的算法。确切的答案需要深入研究 pixman
猜你喜欢
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
  • 2011-01-07
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多