dlopen failed: empty/missing DT_HASH in "libx.so" (built with --hash-style=gnu?)

本文详细介绍了如何解决Android设备在运行应用时出现的崩溃日志错误,具体为java.lang.UnsatisfiedLinkError,原因是动态链接库在加载时遇到了空/缺失DT_HASH问题。通过分析日志信息,我们了解到该错误可能是由于尝试加载的库是在使用Wl,hash-style=gnu风格构建的,而Android对此支持较晚。为了解决这个问题,我们需要在Android.mk文件中添加LOCAL_LDFLAGS配置项,将其设置为-Wl,--hash-style=sysv。文章还通过对比修改前后的动态节变化,展示了配置更改后的良好效果。
崩溃日志内容:
java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH in "libxxxx.so" (built with --hash-style=gnu?)
 at java.lang.Runtime.loadLibrary(Runtime.java:371)
 at java.lang.System.loadLibrary(System.java:989)

崩溃设备信息:
{
    "STARTTIME": "1970-01-01 08:00:00",
    "CRASHTIME": "2015-08-14 01:47:28",
    "DEVICEID": "6aa3a6d0cbcb3251",
    "DEVICE": "hlte",
    "FINGERPRINT": "samsung/h3gduosctc/hlte:5.0/LRX21V/N9009KEU2GOF1:user/release-keys",
    "MODEL": "SM-N9009",
    "OSVERSION": "5.0",
    "CPU_ABI": "armeabi-v7a",
    "IMEI": "A00000443A46BD",
    "CPU_ABI2": "armeabi",
……
}

解决方案:
http://stackoverflow.com/questions/28638809/android-ndk-unsatisfiedlinkerror-dlopen-failed-empty-missing-dt-hash

The library you are trying to load was most likely built with Wl,hash-style=gnu. This was not supported on Android until recently (afaik this isn't even in L). You need to build your libraries with  -Wl,-hash-style=sysv.

How did you build cpplibrary.so? If you didn't do anything to manually switch to the gnu hash style, it could be a bug in the NDK.

One option is to add "LOCAL_LDFLAGS := -Wl,--hash-style=sysv" at screenrecord Android.mk though I am sure there is a less hacky method of doing so..

总结了一下是需要在Android.mk中添加链接选项:
LOCAL_LDFLAGS := Wl,-hash-style=sysv
libsysv-hash-table-library_ldflags := Wl,-hash-style=sysv

于是在修改前后查看了一下so节的变化:
readelf.exe -d libxxxx.so
Dynamic section at offset 0xed14 contains 27 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0xfee0
0x00000002 (PLTRELSZ) 552 (bytes)
0x00000017 (JMPREL) 0x46fc
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x39c4
0x00000012 (RELSZ) 3384 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 420
0x00000006 (SYMTAB) 0x148
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x1918
0x0000000a (STRSZ) 5780 (bytes)
0x00000004 (HASH) 0x2fac
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x0000000e (SONAME) Library soname: [libbugrpt.so]
0x0000001a (FINI_ARRAY) 0xf590
0x0000001c (FINI_ARRAYSZ) 8 (bytes)
0x00000019 (INIT_ARRAY) 0xf598
0x0000001b (INIT_ARRAYSZ) 16 (bytes)
0x00000010 (SYMBOLIC) 0x0
0x0000001e (FLAGS) SYMBOLIC BIND_NOW
0x6ffffffb (FLAGS_1) Flags: NOW
0x00000000 (NULL) 0x0

readelf.exe -d libxxxx.so
Dynamic section at offset 0xed14 contains 27 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0xfee0
0x00000002 (PLTRELSZ) 552 (bytes)
0x00000017 (JMPREL) 0x46fc
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x39c4
0x00000012 (RELSZ) 3384 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 420
0x00000006 (SYMTAB) 0x148
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x1918
0x0000000a (STRSZ) 5780 (bytes)
0x00000004 (HASH) 0x2fac
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x0000000e (SONAME) Library soname: [libbugrpt.so]
0x0000001a (FINI_ARRAY) 0xf590
0x0000001c (FINI_ARRAYSZ) 8 (bytes)
0x00000019 (INIT_ARRAY) 0xf598
0x0000001b (INIT_ARRAYSZ) 16 (bytes)
0x00000010 (SYMBOLIC) 0x0
0x0000001e (FLAGS) SYMBOLIC BIND_NOW
0x6ffffffb (FLAGS_1) Flags: NOW
0x00000000 (NULL) 0x0
修改前后的节并没有什么变化,然并卵啊!


==44230== ==44230== 496 bytes in 1 blocks are possibly lost in loss record 15,841 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0x6B13867: QThread::start(QThread::Priority) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Core.so.5.12.10) ==44230== by 0x4537B0: DiselGeneratorTcp::start(_TCP_DEVINFO const&, QList<QMap<QString, QVariant> > const&) (diselgeneratortcp.cpp:26) ==44230== by 0x4128F6: BackgroundInit::deviceGatherClass() (backgroundinit.cpp:506) ==44230== by 0x40EE9A: BackgroundInit::initClass() (backgroundinit.cpp:171) ==44230== by 0x416B91: BackgroundInit::start() (backgroundinit.cpp:911) ==44230== by 0x4DC6E7: main (main.cpp:19) ==44230== ==44230== 496 bytes in 1 blocks are possibly lost in loss record 15,842 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0x6B13867: QThread::start(QThread::Priority) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Core.so.5.12.10) ==44230== by 0x45E214: LoadAatyMertrTcp::start(_TCP_DEVINFO const&, QList<QMap<QString, QVariant> > const&) (loadaatymertrtcp.cpp:24) ==44230== by 0x4129D6: BackgroundInit::deviceGatherClass() (backgroundinit.cpp:510) ==44230== by 0x40EE9A: BackgroundInit::initClass() (backgroundinit.cpp:171) ==44230== by 0x416B91: BackgroundInit::start() (backgroundinit.cpp:911) ==44230== by 0x4DC6E7: main (main.cpp:19) ==44230== ==44230== 496 bytes in 1 blocks are possibly lost in loss record 15,843 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0x6B13867: QThread::start(QThread::Priority) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Core.so.5.12.10) ==44230== by 0x40896B: SaveHistoryData::start() (savehistorydata.cpp:40) ==44230== by 0x412BD2: BackgroundInit::deviceGatherClass() (backgroundinit.cpp:533) ==44230== by 0x40EE9A: BackgroundInit::initClass() (backgroundinit.cpp:171) ==44230== by 0x416B91: BackgroundInit::start() (backgroundinit.cpp:911) ==44230== by 0x4DC6E7: main (main.cpp:19) ==44230== ==44230== 496 bytes in 1 blocks are possibly lost in loss record 15,844 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0x6B13867: QThread::start(QThread::Priority) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Core.so.5.12.10) ==44230== by 0x3DB2B8: FaultRecordWave::start(_UDP_DEVINFO const&) (faultrecordwave.cpp:31) ==44230== by 0x412C5E: BackgroundInit::deviceGatherClass() (backgroundinit.cpp:541) ==44230== by 0x40EE9A: BackgroundInit::initClass() (backgroundinit.cpp:171) ==44230== by 0x416B91: BackgroundInit::start() (backgroundinit.cpp:911) ==44230== by 0x4DC6E7: main (main.cpp:19) ==44230== ==44230== 512 bytes in 7 blocks are possibly lost in loss record 15,923 of 18,266 ==44230== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xCE5A174: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE5A598: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD4285CE: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE43768: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0x4011B89: call_init.part.0 (dl-init.c:72) ==44230== by 0x4011C90: call_init (dl-init.c:30) ==44230== by 0x4011C90: _dl_init (dl-init.c:119) ==44230== by 0x76DD914: _dl_catch_exception (dl-error-skeleton.c:182) ==44230== by 0x401642C: dl_open_worker (dl-open.c:758) ==44230== by 0x76DD8B7: _dl_catch_exception (dl-error-skeleton.c:208) ==44230== by 0x40155F9: _dl_open (dl-open.c:837) ==44230== by 0x7A6534B: dlopen_doit (dlopen.c:66) ==44230== ==44230== 544 bytes in 1 blocks are possibly lost in loss record 15,959 of 18,266 ==44230== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xCE5A174: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE5A23D: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE546A9: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD54261B: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD54290B: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD543DF6: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEADBEC: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE515BF: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD42FFC4: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xC9D146E: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== by 0xC9CEDF5: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== ==44230== 624 bytes in 1 blocks are possibly lost in loss record 16,074 of 18,266 ==44230== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xCE5A174: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE5A23D: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD428577: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE437DE: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0x4011B89: call_init.part.0 (dl-init.c:72) ==44230== by 0x4011C90: call_init (dl-init.c:30) ==44230== by 0x4011C90: _dl_init (dl-init.c:119) ==44230== by 0x76DD914: _dl_catch_exception (dl-error-skeleton.c:182) ==44230== by 0x401642C: dl_open_worker (dl-open.c:758) ==44230== by 0x76DD8B7: _dl_catch_exception (dl-error-skeleton.c:208) ==44230== by 0x40155F9: _dl_open (dl-open.c:837) ==44230== by 0x7A6534B: dlopen_doit (dlopen.c:66) ==44230== ==44230== 816 bytes in 12 blocks are possibly lost in loss record 16,388 of 18,266 ==44230== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xCE5A174: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE5A598: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD4285CE: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE437DE: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0x4011B89: call_init.part.0 (dl-init.c:72) ==44230== by 0x4011C90: call_init (dl-init.c:30) ==44230== by 0x4011C90: _dl_init (dl-init.c:119) ==44230== by 0x76DD914: _dl_catch_exception (dl-error-skeleton.c:182) ==44230== by 0x401642C: dl_open_worker (dl-open.c:758) ==44230== by 0x76DD8B7: _dl_catch_exception (dl-error-skeleton.c:208) ==44230== by 0x40155F9: _dl_open (dl-open.c:837) ==44230== by 0x7A6534B: dlopen_doit (dlopen.c:66) ==44230== ==44230== 864 bytes in 27 blocks are definitely lost in loss record 16,412 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xB434E56: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0) ==44230== by 0xB435119: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0) ==44230== by 0xB43BB4A: FcFreeTypeCharSet (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0) ==44230== by 0xB43DDCB: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0) ==44230== by 0xB15A69F: QFontconfigDatabase::addApplicationFont(QByteArray const&, QString const&) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5XcbQpa.so.5.12.10) ==44230== by 0x59F95E3: initializeDb() (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Gui.so.5.12.10) ==44230== by 0x59FA63D: QFontDatabase::families(QFontDatabase::WritingSystem) const (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Gui.so.5.12.10) ==44230== by 0x27ECF3: IconHelper::IconHelper(QString const&, QString const&, QObject*) (iconhelper.cpp:159) ==44230== by 0x27E1C5: IconHelper::initFont() (iconhelper.cpp:28) ==44230== by 0x27E56F: IconHelper::getIconHelper(int) (iconhelper.cpp:70) ==44230== by 0x27E695: IconHelper::setIcon(QLabel*, int, unsigned int) (iconhelper.cpp:102) ==44230== ==44230== 992 bytes in 2 blocks are possibly lost in loss record 16,514 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0xD546F76: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD5477A4: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD5428DA: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD543DF6: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEADBEC: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE515BF: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD42FFC4: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xC9D146E: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== by 0xC9CEDF5: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== ==44230== 992 bytes in 2 blocks are possibly lost in loss record 16,515 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0xD5442E6: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD5443BB: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD5428F1: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD543DF6: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEADBEC: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE515BF: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD42FFC4: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xC9D146E: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== by 0xC9CEDF5: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== ==44230== 992 bytes in 2 blocks are possibly lost in loss record 16,516 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0x6B13867: QThread::start(QThread::Priority) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Core.so.5.12.10) ==44230== by 0x4062BD: DataTableBackendProcessing::start() (datatablebackendprocessing.cpp:42) ==44230== by 0x410124: BackgroundInit::backendDataClass() (backgroundinit.cpp:289) ==44230== by 0x40EE82: BackgroundInit::initClass() (backgroundinit.cpp:169) ==44230== by 0x416B91: BackgroundInit::start() (backgroundinit.cpp:911) ==44230== by 0x4DC6E7: main (main.cpp:19) ==44230== ==44230== 992 bytes in 2 blocks are possibly lost in loss record 16,517 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0x6B13867: QThread::start(QThread::Priority) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Core.so.5.12.10) ==44230== by 0x4050E1: DataQueueBackendProcessing::start() (dataqueuebackendprocessing.cpp:92) ==44230== by 0x410207: BackgroundInit::backendDataClass() (backgroundinit.cpp:296) ==44230== by 0x40EE82: BackgroundInit::initClass() (backgroundinit.cpp:169) ==44230== by 0x416B91: BackgroundInit::start() (backgroundinit.cpp:911) ==44230== by 0x4DC6E7: main (main.cpp:19) ==44230== ==44230== 992 bytes in 2 blocks are possibly lost in loss record 16,518 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x40149CA: allocate_dtv (dl-tls.c:286) ==44230== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532) ==44230== by 0x7215322: allocate_stack (allocatestack.c:622) ==44230== by 0x7215322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==44230== by 0x6B13867: QThread::start(QThread::Priority) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Core.so.5.12.10) ==44230== by 0x606522F: QNetworkAccessManagerPrivate::createThread() (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Network.so.5.12.10) ==44230== by 0x60CD25B: QNetworkReplyHttpImplPrivate::postRequest(QNetworkRequest const&) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Network.so.5.12.10) ==44230== by 0x60CEBEF: QNetworkReplyHttpImplPrivate::start(QNetworkRequest const&) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Network.so.5.12.10) ==44230== by 0x60CEE4A: QNetworkReplyHttpImplPrivate::_q_startOperation() (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Network.so.5.12.10) ==44230== by 0x616BAB8: QNetworkReplyHttpImpl::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Network.so.5.12.10) ==44230== by 0x6D0FF00: QObject::event(QEvent*) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Core.so.5.12.10) ==44230== by 0x50E38FB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Widgets.so.5.12.10) ==44230== by 0x50EAA1F: QApplication::notify(QObject*, QEvent*) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Widgets.so.5.12.10) ==44230== ==44230== 1,472 bytes in 1 blocks are possibly lost in loss record 16,805 of 18,266 ==44230== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xCE5A174: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE5A23D: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEE9283: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD040E2A: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCF40F7F: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEC72E0: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEADC3C: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE515BF: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD42FFC4: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xC9D146E: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== by 0xC9CEDF5: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== ==44230== 1,536 bytes in 1 blocks are possibly lost in loss record 16,827 of 18,266 ==44230== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xCE5BBFC: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE54869: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD54261B: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD54290B: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD543DF6: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEADBEC: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE515BF: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD42FFC4: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xC9D146E: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== by 0xC9CEDF5: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== by 0x9FB14FB: ??? (in /usr/lib/x86_64-linux-gnu/libGLX.so.0.0.0) ==44230== ==44230== 1,600 bytes in 1 blocks are possibly lost in loss record 16,838 of 18,266 ==44230== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xCE5A174: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE5A23D: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEE925E: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD040E0C: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCF40F7F: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEC72E0: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCEADC3C: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xCE515BF: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xD42FFC4: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so) ==44230== by 0xC9D146E: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== by 0xC9CEDF5: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0) ==44230== ==44230== 4,104 bytes in 1 blocks are possibly lost in loss record 17,136 of 18,266 ==44230== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x18665393: sqlite3MemMalloc (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/plugins/sqldrivers/libqsqlite.so) ==44230== by 0x18652DD7: sqlite3Malloc (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/plugins/sqldrivers/libqsqlite.so) ==44230== by 0x18653556: pcache1Alloc (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/plugins/sqldrivers/libqsqlite.so) ==44230== by 0x18666793: btreeCursor (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/plugins/sqldrivers/libqsqlite.so) ==44230== by 0x186BF006: sqlite3VdbeExec (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/plugins/sqldrivers/libqsqlite.so) ==44230== by 0x186C8ACF: sqlite3_step (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/plugins/sqldrivers/libqsqlite.so) ==44230== by 0x1863A198: QSQLiteResultPrivate::fetchNext(QVector<QVariant>&, int, bool) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/plugins/sqldrivers/libqsqlite.so) ==44230== by 0x1863B4A5: QSQLiteResult::exec() (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/plugins/sqldrivers/libqsqlite.so) ==44230== by 0x63DE2D7: QSqlQuery::exec(QString const&) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Sql.so.5.12.10) ==44230== by 0x3AA808: SqliteService::InsertExec(QString const&) (sqliteservice.cpp:167) ==44230== by 0x3AA7CA: SqliteService::setSqlVoid(QString const&) (sqliteservice.cpp:159) ==44230== ==44230== 5,277 (16 direct, 5,261 indirect) bytes in 1 blocks are definitely lost in loss record 17,251 of 18,266 ==44230== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0x27C26D: FunctionHelper::startApp(QString const&) (functionhelper.cpp:504) ==44230== by 0x285E97: QtHelper::startApp(QString const&) (qthelper.cpp:534) ==44230== by 0x2AC28E: AppInit::initApplication() (appinit.cpp:796) ==44230== by 0x29EEA7: AppInit::start(QApplication*) (appinit.cpp:113) ==44230== by 0x4DC6DA: main (main.cpp:18) ==44230== ==44230== 7,095 (2,560 direct, 4,535 indirect) bytes in 5 blocks are definitely lost in loss record 17,348 of 18,266 ==44230== at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==44230== by 0xB4463A0: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0) ==44230== by 0xB4469B8: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0) ==44230== by 0xB43DBB6: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0) ==44230== by 0xB15A69F: QFontconfigDatabase::addApplicationFont(QByteArray const&, QString const&) (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5XcbQpa.so.5.12.10) ==44230== by 0x59F95E3: initializeDb() (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Gui.so.5.12.10) ==44230== by 0x59FA63D: QFontDatabase::families(QFontDatabase::WritingSystem) const (in /home/Kylin/Qt5.12.10/5.12.10/gcc_64/lib/libQt5Gui.so.5.12.10) ==44230== by 0x27ECF3: IconHelper::IconHelper(QString const&, QString const&, QObject*) (iconhelper.cpp:159) ==44230== by 0x27E1C5: IconHelper::initFont() (iconhelper.cpp:28) ==44230== by 0x27E56F: IconHelper::getIconHelper(int) (iconhelper.cpp:70) ==44230== by 0x27E695: IconHelper::setIcon(QLabel*, int, unsigned int) (iconhelper.cpp:102) ==44230== by 0x3B7ABE: FrmMain::initForm() (frmmain.cpp:70) ==44230== ==44230== LEAK SUMMARY: ==44230== definitely lost: 4,056 bytes in 44 blocks ==44230== indirectly lost: 9,828 bytes in 185 blocks ==44230== possibly lost: 69,704 bytes in 592 blocks ==44230== still reachable: 241,705,992 bytes in 1,420,166 blocks ==44230== of which reachable via heuristic: ==44230== length64 : 161,048 bytes in 276 blocks ==44230== newarray : 560 bytes in 14 blocks ==44230== multipleinheritance: 6,320 bytes in 9 blocks ==44230== suppressed: 0 bytes in 0 blocks ==44230== Reachable blocks (those to which a pointer was found) are not shown. ==44230== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==44230== ==44230== For lists of detected and suppressed errors, rerun with: -s ==44230== ERROR SUMMARY: 793 errors from 595 contexts (suppressed: 2 from 2)
最新发布
07-29
<think>我们面对的是Valgrind检测到的内存泄漏问题。根据引用[1][2][4][5],Valgrind的memcheck工具是检测内存泄漏的强大工具。用户已经运行了Valgrind,并得到了内存泄漏的报告,现在需要分析定位并解决。 步骤1:理解Valgrind内存泄漏报告 在Valgrind的输出中,内存泄漏分为几种类型: - 肯定泄漏(definitely lost):程序中没有指针指向该内存块,无法释放。 - 间接泄漏(indirectly lost):由于肯定泄漏导致的其他内存泄漏(例如,结构体中包含指针,该结构体泄漏则指针指向的内存也泄漏)。 - 可能泄漏(possibly lost):存在指针指向内存块的起始位置或中间位置,但无法确定是否指向了起始位置(可能由于指针运算导致)。 - 仍可访问(still reachable):程序结束时仍有指针指向该内存,但未释放(通常是全局变量或静态变量,有时是故意的,但有时是疏忽)。 步骤2:运行Valgrind获取详细报告 根据引用[1][5],我们需要使用以下命令获取详细的内存泄漏报告: valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./your_program 其中: --leak-check=full:显示每个泄漏的详细信息。 --show-leak-kinds=all:显示所有类型的泄漏(包括肯定泄漏、间接泄漏、可能泄漏和仍可访问)。 --track-origins=yes:追踪未初始化值的来源,对内存泄漏定位也有帮助。 步骤3:分析报告中的泄漏信息 在报告中,每个泄漏都会有一个堆栈跟踪,显示分配内存的位置(即调用malloc、calloc、new等的地方)。例如: ==12345== 40 bytes in 1 blocks are definitely lost in loss record 1 of 10 ==12345== at 0x4C2A025: malloc (vg_replace_malloc.c:381) ==12345== by 0x4005B6: create_leak (example.c:10) ==12345== by 0x4005E1: main (example.c:20) 这里,在example.c文件的第10行分配的内存发生了泄漏,该函数在main函数的第20行被调用。 步骤4:定位并修复泄漏 根据堆栈信息,找到对应的代码位置,检查为什么没有释放内存。常见原因包括: - 忘记调用free/delete。 - 在释放前提前返回(如条件判断中return)。 - 在释放前抛出异常(C++中,可以使用智能指针避免)。 - 指针被覆盖(例如,在释放前将指针指向了别处,导致原内存块无法释放)。 步骤5:修复泄漏后重新验证 修复后,重新编译(确保有-g选项)并运行Valgrind,直到没有肯定泄漏和可能泄漏(仍可访问的泄漏根据情况判断是否可接受)。 示例解决方案: 假设在代码中: void create_leak() { int *ptr = (int*)malloc(10 * sizeof(int)); // 使用ptr // 忘记free(ptr); } 修复:在函数返回前添加free(ptr)。 对于C++,优先使用智能指针(如std::unique_ptr, std::shared_ptr)和容器(如std::vector)来自动管理内存。 步骤6:处理“仍可访问”(still reachable)的内存 如果程序在退出时仍有全局变量或静态变量持有内存,这可能是设计使然(例如缓存),但也要确认是否应该释放。可以在程序退出前释放这些资源。 注意事项: - 如果泄漏发生在第三方库中,可能需要联系库的开发者或查找库的文档。 - 有些泄漏可能是由于程序异常终止导致的资源未释放,需要检查异常处理路径。 引用[4]提到,内存泄露不会立即导致系统异常,但长时间运行后会导致系统内存不足。因此,解决内存泄漏问题对于长期运行的程序尤为重要。 根据以上步骤,用户可以逐步定位并解决内存泄漏问题。 生成相关问题: §§相关问题§§ 1. 如何区分Valgrind报告中的“肯定泄漏”和“可能泄漏”? 2. 在C++中,如何使用智能指针避免内存泄漏? 3. Valgrind检测到第三方库的内存泄漏,该如何处理? 4. 如何让Valgrind只检测特定类型的内存泄漏?</think>### Valgrind内存泄漏分析指南 以下是系统化定位和解决内存泄漏问题的步骤,结合Valgrind工具的使用技巧: --- #### 一、获取详细泄漏报告 运行以下命令生成完整诊断报告: ```bash valgrind --leak-check=full \ # 完整泄漏检查 --show-leak-kinds=all \ # 显示所有泄漏类型 --track-origins=yes \ # 追踪未初始化内存来源 --log-file=valgrind.log \ # 输出到文件 ./your_program # 目标程序 ``` 关键参数说明: - `--track-origins=yes`:可精确定位未初始化变量的来源 - `--show-leak-kinds=all`:显示所有泄漏类型(包括间接泄漏)[^2][^5] --- #### 二、解读泄漏报告关键信息 在`valgrind.log`中重点关注以下部分: 1. **泄漏类型分类** ```log ==PID== 24 bytes in 1 blocks are definitely lost ==PID== at 0x...: malloc (vg_replace_malloc.c:381) ==PID== by 0x...: createResource() (ResourceManager.cpp:42) ``` - **肯定泄漏(definitely lost)**:无指针指向的内存块(必须修复) - **可能泄漏(possibly lost)**:指针指向内存块中间位置(可能因指针运算导致) - **仍可访问(still reachable)**:程序结束时仍有指针指向(全局变量常见)[^4] 2. **堆栈追踪关键元素** ```log by 0x...: createResource() (ResourceManager.cpp:42) # 分配位置 by 0x...: initSystem() (Main.cpp:15) # 调用路径 ``` --- #### 三、定位泄漏代码位置 1. **直接泄漏点定位** 查找报告中首次出现的分配函数调用: - `malloc/calloc/realloc` → C语言分配 - `operator new` → C++分配 - `g_malloc` → GLib分配 2. **间接泄漏分析技巧** 当出现以下模式时,表示存在资源所有权管理问题: ```log indirectly lost: 80 bytes in 2 blocks # 通常伴随结构体内存泄漏 ``` --- #### 四、常见泄漏场景与修复方案 | 泄漏模式 | 典型代码示例 | 修复方案 | |-------------------------|----------------------------------|-----------------------------------| | 未配对释放 | `malloc()`后无`free()` | 添加资源释放逻辑 | | 异常路径未释放 | `return`前漏掉`delete` | 使用RAII对象或`finally`块 | | 容器元素未释放 | `vector<Object*>`未清理 | 改用智能指针或手动遍历删除 | | 循环引用 | `shared_ptr`双向持有 | 改用`weak_ptr`打破引用环 | | 全局缓存未清除 | 静态`map`存储动态对象 | 添加程序退出时的清理函数 | --- #### 五、验证修复效果 1. 修复后重新运行Valgrind: ```bash valgrind --leak-check=full ./your_program ``` 2. 检查输出中是否还有`definitely lost` 3. 可接受残留类型: - `still reachable` < 1KB(通常为库初始化开销) - `possibly lost` = 0(确保无指针运算错误)[^4] --- #### 六、高级调试技巧 1. **抑制系统库误报**: ```bash valgrind --suppressions=/path/to/glibc.supp ./your_program ``` 创建抑制文件参考Valgrind文档[^2] 2. **结合GDB实时调试**: ```bash valgrind --vgdb=yes --vgdb-error=0 ./your_program ``` 在GDB中连接后使用`monitor leak_check full reachable any`命令 > **最佳实践**:在持续集成(CI)流程中加入Valgrind检查,每次构建自动检测内存问题[^1][^5]。
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

asmcvc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值