New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 862699 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner: ----
Closed: Jul 30
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 2
Type: Bug

Blocking:
issue 852111



Sign in to add a comment

mesa driver shared libraries leak memory

Project Member Reported by davidri...@chromium.org, Jul 11

Issue description

Doing a dlopen()/dlclose() of /usr/lib64/dri/swrast_dri.so (or kms_swrast_dri.so or nouveau_dri.so) on amd64-generic results in memory being leaked.

This will cause issues with the virgl fuzzer which needs to tear down and initialize state after runs.

Attached is a test program which does a dlopen() and dlclose() which can be invoked with:
valgrind --leak-check=full /tmp/a.out /usr/lib64/dri/swrast_dri.so

All the leaks appear to happen due to some unknown code being called from dl_init which is getting into some shared library code I'm not familiar with but I'm assuming something in the .init section.

fuzzy / # valgrind --leak-check=full /tmp/a.out /usr/lib64/dri/swrast_dri.so
==30432== Memcheck, a memory error detector
==30432== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==30432== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==30432== Command: /tmp/a.out /usr/lib64/dri/swrast_dri.so
==30432==
opening /usr/lib64/dri/swrast_dri.so
==30432==
==30432== HEAP SUMMARY:
==30432==     in use at exit: 41,494 bytes in 530 blocks
==30432==   total heap usage: 1,053 allocs, 523 frees, 118,303 bytes allocated
==30432==
==30432== 24 bytes in 1 blocks are definitely lost in loss record 6 of 514
==30432==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30432==    by 0x417D8D9: operator new(unsigned long) (in /usr/lib64/libc++.so.1.0)
==30432==    by 0x662DC8D: ???
==30432==    by 0x661EE2E: ???
==30432==    by 0x54224F2: ???
==30432==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30432==    by 0x400FFCB: call_init (dl-init.c:30)
==30432==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30432==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30432==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30432==    by 0x4013F88: _dl_open (dl-open.c:657)
==30432==    by 0x4A27F22: dlopen_doit (dlopen.c:66)
==30432==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30432==
==30432== 56 (16 direct, 40 indirect) bytes in 1 blocks are definitely lost in loss record 476 of 514
==30432==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30432==    by 0x417D8D9: operator new(unsigned long) (in /usr/lib64/libc++.so.1.0)
==30432==    by 0x661EE9F: ???
==30432==    by 0x417D7DC: std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) (in /usr/lib64/libc++.so.1.0)
==30432==    by 0x661EE14: ???
==30432==    by 0x6610143: ???
==30432==    by 0x53F496B: ???
==30432==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30432==    by 0x400FFCB: call_init (dl-init.c:30)
==30432==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30432==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30432==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30432==    by 0x4013F88: _dl_open (dl-open.c:657)
==30432==
==30432== 192 (120 direct, 72 indirect) bytes in 1 blocks are definitely lost in loss record 507 of 514
==30432==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30432==    by 0x417D8D9: operator new(unsigned long) (in /usr/lib64/libc++.so.1.0)
==30432==    by 0x65C090F: ???
==30432==    by 0x661EE2E: ???
==30432==    by 0x65C0311: ???
==30432==    by 0x65BFA99: ???
==30432==    by 0x54205BE: ???
==30432==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30432==    by 0x400FFCB: call_init (dl-init.c:30)
==30432==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30432==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30432==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30432==    by 0x4013F88: _dl_open (dl-open.c:657)
==30432==
==30432== 2,720 (96 direct, 2,624 indirect) bytes in 1 blocks are definitely lost in loss record 511 of 514
==30432==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30432==    by 0x417D8D9: operator new(unsigned long) (in /usr/lib64/libc++.so.1.0)
==30432==    by 0x661855D: ???
==30432==    by 0x661EE2E: ???
==30432==    by 0x66171A1: ???
==30432==    by 0x622334F: ???
==30432==    by 0x54158DA: ???
==30432==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30432==    by 0x400FFCB: call_init (dl-init.c:30)
==30432==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30432==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30432==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30432==    by 0x4013F88: _dl_open (dl-open.c:657)
==30432==
==30432== 32,044 (296 direct, 31,748 indirect) bytes in 1 blocks are definitely lost in loss record 514 of 514
==30432==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30432==    by 0x417D8D9: operator new(unsigned long) (in /usr/lib64/libc++.so.1.0)
==30432==    by 0x6616150: ???
==30432==    by 0x661EE2E: ???
==30432==    by 0x6610143: ???
==30432==    by 0x53F496B: ???
==30432==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30432==    by 0x400FFCB: call_init (dl-init.c:30)
==30432==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30432==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30432==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30432==    by 0x4013F88: _dl_open (dl-open.c:657)
==30432==    by 0x4A27F22: dlopen_doit (dlopen.c:66)
==30432==
==30432== LEAK SUMMARY:
==30432==    definitely lost: 552 bytes in 5 blocks
==30432==    indirectly lost: 34,484 bytes in 505 blocks
==30432==      possibly lost: 0 bytes in 0 blocks
==30432==    still reachable: 6,458 bytes in 20 blocks
==30432==         suppressed: 0 bytes in 0 blocks
==30432== Reachable blocks (those to which a pointer was found) are not shown.
==30432== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==30432==
==30432== For counts of detected and suppressed errors, rerun with: -v
==30432== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)

I believe that this is not spurious because running virgl fuzzer with leak detection off eventually OOMs (exceeds ~2GB) after about 14-15k iterations.

Running the same test program on another library like /usr/lib64/libdrm.so doesn't report any leaks, so it seems to be something specific with the mesa drivers.
 
dl.c
219 bytes View Download
The init code leads to megadriver_stub but. Something is fishy..

(gdb) bt                                                     
#0  megadriver_stub_init () at megadriver_stub.c:76                   
#1  0x000000000400feab in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0xfff000608, env=env@entry=0xfff000618) at dl-init.c:72
#2  0x000000000400ffcc in call_init (env=0xfff000618, argv=0xfff000608, argc=1, l=<optimized out>) at dl-init.c:30
#3  _dl_init (main_map=main_map@entry=0x54f9540, argc=1, argv=0xfff000608, env=0xfff000618) at dl-init.c:120
#4  0x0000000004014aa0 in dl_open_worker (a=a@entry=0xfff000270) at dl-open.c:572
#5  0x000000000400fd18 in _dl_catch_error (objname=objname@entry=0xfff000260, errstring=errstring@entry=0xfff000268, mallocedp=mallocedp@entry=0xfff00025f,
    operate=operate@entry=0x40146c0 <dl_open_worker>, args=args@entry=0xfff000270) at dl-error.c:187
#6  0x0000000004013f89 in _dl_open (file=0x108da2 "/usr/lib64/dri/swrast_dri.so", mode=-2147483390, caller_dlopen=0x108b86 <main+38>, nsid=-2, argc=<optimized out>, argv=<optimized out>,
    env=0xfff000618) at dl-open.c:657                            
#7  0x0000000004a27f23 in dlopen_doit (a=a@entry=0xfff0004d0) at dlopen.c:66
#8  0x000000000400fd18 in _dl_catch_error (objname=0x54f9490, errstring=0x54f9498, mallocedp=0x54f9488, operate=0x4a27ec0 <dlopen_doit>, args=0xfff0004d0) at dl-error.c:187
#9  0x0000000004a2859a in _dlerror_run (operate=operate@entry=0x4a27ec0 <dlopen_doit>, args=args@entry=0xfff0004d0) at dlerror.c:163
#10 0x0000000004a27fc5 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#11 0x0000000000108b86 in main (argc=<optimized out>, argv=<optimized out>) at ../swrast_test.c:133


Putting a for loop around the dlopen and dlclose would generate exactly 552 bytes definitely lost bytes each iteration.
[1 iteration]
==32446== LEAK SUMMARY:                                                                                                                                                                       
==32446==    definitely lost: 552 bytes in 5 blocks                                                                                                                                           
==32446==    indirectly lost: 35,163 bytes in 525 blocks                                                                                                                                      
==32446==      possibly lost: 0 bytes in 0 blocks                                                                                                                                             
==32446==    still reachable: 5,004 bytes in 17 blocks                                                                                                                                        
==32446==         suppressed: 0 bytes in 0 blocks                                                                                                                                             

[10 iterations]
==30587== LEAK SUMMARY:                                                                                                                                                                       
==30587==    definitely lost: 5,520 bytes in 50 blocks                                                                                                                                        
==30587==    indirectly lost: 351,630 bytes in 5,250 blocks                                                                                                                                   
==30587==      possibly lost: 0 bytes in 0 blocks                                                                                                                                             
==30587==    still reachable: 4,908 bytes in 14 blocks                                                                                                                                        
==30587==         suppressed: 0 bytes in 0 blocks


I think it could be LLVM code:
Breakpoint 2, 0x00007ffff7f038b4 in operator new(unsigned long) () from /usr/lib64/libc++.so.1
(gdb) where
#0  0x00007ffff7f038b4 in operator new(unsigned long) () from /usr/lib64/libc++.so.1
#1  0x00007ffff6e2b151 in llvm::object_creator<(anonymous namespace)::CommandLineParser>::call () at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:24
#2  0x00007ffff6e33e2f in llvm::ManagedStaticBase::RegisterManagedStatic (this=0x7ffff77e0708 <GlobalParser>,
    Creator=0x7ffff6e2b140 <llvm::object_creator<(anonymous namespace)::CommandLineParser>::call()>,
    Deleter=0x7ffff6e2b230 <llvm::object_deleter<(anonymous namespace)::CommandLineParser>::call(void*)>) at ../llvm-6.0.0.src/lib/Support/ManagedStatic.cpp:45
#3  0x00007ffff6e25144 in llvm::ManagedStatic<(anonymous namespace)::CommandLineParser, llvm::object_creator<(anonymous namespace)::CommandLineParser>, llvm::object_deleter<(anonymous namespace)::CommandLineParser> >::operator* (this=<optimized out>) at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:67
#4  llvm::ManagedStatic<(anonymous namespace)::CommandLineParser, llvm::object_creator<(anonymous namespace)::CommandLineParser>, llvm::object_deleter<(anonymous namespace)::CommandLineParser> >::operator-> (this=<optimized out>) at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:72
#5  llvm::cl::Option::addArgument (this=0x7ffff77c3060 <EnableBasePointer>) at ../llvm-6.0.0.src/lib/Support/CommandLine.cpp:356
#6  0x00007ffff5c0996c in _GLOBAL__sub_I_X86RegisterInfo.cpp () at ../llvm-6.0.0.src/include/llvm/Support/CommandLine.h:1338
#7  0x00007ffff7de7eab in call_init (l=<optimized out>, argc=argc@entry=2, argv=argv@entry=0x7fffffffe5f8, env=env@entry=0x7fffffffe610) at dl-init.c:72
#8  0x00007ffff7de7fcc in call_init (env=0x7fffffffe610, argv=0x7fffffffe5f8, argc=2, l=<optimized out>) at dl-init.c:30
#9  _dl_init (main_map=main_map@entry=0x602450, argc=2, argv=0x7fffffffe5f8, env=0x7fffffffe610) at dl-init.c:120
#10 0x00007ffff7decaa0 in dl_open_worker (a=a@entry=0x7fffffffe250) at dl-open.c:572
#11 0x00007ffff7de7d18 in _dl_catch_error (objname=objname@entry=0x7fffffffe240, errstring=errstring@entry=0x7fffffffe248, mallocedp=mallocedp@entry=0x7fffffffe23f,
    operate=operate@entry=0x7ffff7dec6c0 <dl_open_worker>, args=args@entry=0x7fffffffe250) at dl-error.c:187
#12 0x00007ffff7debf89 in _dl_open (file=0x7fffffffe824 "/usr/lib64/dri/swrast_dri.so", mode=-2147483647, caller_dlopen=0x400669 <main+99>, nsid=-2,
    argc=<optimized out>, argv=<optimized out>, env=0x7fffffffe610) at dl-open.c:657
#13 0x00007ffff7bd4f23 in dlopen_doit (a=a@entry=0x7fffffffe4b0) at dlopen.c:66
#14 0x00007ffff7de7d18 in _dl_catch_error (objname=0x7ffff7dd7070 <last_result+16>, errstring=0x7ffff7dd7078 <last_result+24>, mallocedp=0x7ffff7dd7068 <last_result+8>,
    operate=0x7ffff7bd4ec0 <dlopen_doit>, args=0x7fffffffe4b0) at dl-error.c:187
#15 0x00007ffff7bd559a in _dlerror_run (operate=operate@entry=0x7ffff7bd4ec0 <dlopen_doit>, args=args@entry=0x7fffffffe4b0) at dlerror.c:163
#16 0x00007ffff7bd4fc5 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#17 0x0000000000400669 in main ()
(gdb) cont
Continuing.

Breakpoint 2, 0x00007ffff7f038b4 in operator new(unsigned long) () from /usr/lib64/libc++.so.1
(gdb) where
#0  0x00007ffff7f038b4 in operator new(unsigned long) () from /usr/lib64/libc++.so.1
#1  0x00007ffff6e2affe in llvm::object_creator<llvm::cl::SubCommand>::call () at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:24
#2  0x00007ffff6e33e2f in llvm::ManagedStaticBase::RegisterManagedStatic (this=0x7ffff77e0740 <llvm::cl::TopLevelSubCommand>,
    Creator=0x7ffff6e2aff0 <llvm::object_creator<llvm::cl::SubCommand>::call()>, Deleter=0x7ffff6e2b090 <llvm::object_deleter<llvm::cl::SubCommand>::call(void*)>)
    at ../llvm-6.0.0.src/lib/Support/ManagedStatic.cpp:45
#3  0x00007ffff6e2b1df in llvm::ManagedStatic<llvm::cl::SubCommand, llvm::object_creator<llvm::cl::SubCommand>, llvm::object_deleter<llvm::cl::SubCommand> >::operator* (
    this=0x7ffff77e0740 <llvm::cl::TopLevelSubCommand>) at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:67
#4  (anonymous namespace)::CommandLineParser::CommandLineParser (this=0x611290) at ../llvm-6.0.0.src/lib/Support/CommandLine.cpp:108
#5  llvm::object_creator<(anonymous namespace)::CommandLineParser>::call () at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:24
#6  0x00007ffff6e33e2f in llvm::ManagedStaticBase::RegisterManagedStatic (this=0x7ffff77e0708 <GlobalParser>,
    Creator=0x7ffff6e2b140 <llvm::object_creator<(anonymous namespace)::CommandLineParser>::call()>,
    Deleter=0x7ffff6e2b230 <llvm::object_deleter<(anonymous namespace)::CommandLineParser>::call(void*)>) at ../llvm-6.0.0.src/lib/Support/ManagedStatic.cpp:45
#7  0x00007ffff6e25144 in llvm::ManagedStatic<(anonymous namespace)::CommandLineParser, llvm::object_creator<(anonymous namespace)::CommandLineParser>, llvm::object_deleter<(anonymous namespace)::CommandLineParser> >::operator* (this=<optimized out>) at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:67
#8  llvm::ManagedStatic<(anonymous namespace)::CommandLineParser, llvm::object_creator<(anonymous namespace)::CommandLineParser>, llvm::object_deleter<(anonymous namespace)::CommandLineParser> >::operator-> (this=<optimized out>) at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:72
#9  llvm::cl::Option::addArgument (this=0x7ffff77c3060 <EnableBasePointer>) at ../llvm-6.0.0.src/lib/Support/CommandLine.cpp:356
#10 0x00007ffff5c0996c in _GLOBAL__sub_I_X86RegisterInfo.cpp () at ../llvm-6.0.0.src/include/llvm/Support/CommandLine.h:1338
#11 0x00007ffff7de7eab in call_init (l=<optimized out>, argc=argc@entry=2, argv=argv@entry=0x7fffffffe5f8, env=env@entry=0x7fffffffe610) at dl-init.c:72
#12 0x00007ffff7de7fcc in call_init (env=0x7fffffffe610, argv=0x7fffffffe5f8, argc=2, l=<optimized out>) at dl-init.c:30
#13 _dl_init (main_map=main_map@entry=0x602450, argc=2, argv=0x7fffffffe5f8, env=0x7fffffffe610) at dl-init.c:120
#14 0x00007ffff7decaa0 in dl_open_worker (a=a@entry=0x7fffffffe250) at dl-open.c:572
#15 0x00007ffff7de7d18 in _dl_catch_error (objname=objname@entry=0x7fffffffe240, errstring=errstring@entry=0x7fffffffe248, mallocedp=mallocedp@entry=0x7fffffffe23f,
    operate=operate@entry=0x7ffff7dec6c0 <dl_open_worker>, args=args@entry=0x7fffffffe250) at dl-error.c:187
#16 0x00007ffff7debf89 in _dl_open (file=0x7fffffffe824 "/usr/lib64/dri/swrast_dri.so", mode=-2147483647, caller_dlopen=0x400669 <main+99>, nsid=-2,
    argc=<optimized out>, argv=<optimized out>, env=0x7fffffffe610) at dl-open.c:657
#17 0x00007ffff7bd4f23 in dlopen_doit (a=a@entry=0x7fffffffe4b0) at dlopen.c:66
#18 0x00007ffff7de7d18 in _dl_catch_error (objname=0x7ffff7dd7070 <last_result+16>, errstring=0x7ffff7dd7078 <last_result+24>, mallocedp=0x7ffff7dd7068 <last_result+8>,
    operate=0x7ffff7bd4ec0 <dlopen_doit>, args=0x7fffffffe4b0) at dl-error.c:187
#19 0x00007ffff7bd559a in _dlerror_run (operate=operate@entry=0x7ffff7bd4ec0 <dlopen_doit>, args=args@entry=0x7fffffffe4b0) at dlerror.c:163
#20 0x00007ffff7bd4fc5 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#21 0x0000000000400669 in main ()
(gdb) cont
Continuing.

Breakpoint 2, 0x00007ffff7f038b4 in operator new(unsigned long) () from /usr/lib64/libc++.so.1
(gdb) where
#0  0x00007ffff7f038b4 in operator new(unsigned long) () from /usr/lib64/libc++.so.1
#1  0x00007ffff6e2affe in llvm::object_creator<llvm::cl::SubCommand>::call () at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:24
#2  0x00007ffff6e33e2f in llvm::ManagedStaticBase::RegisterManagedStatic (this=0x7ffff77e0758 <llvm::cl::AllSubCommands>,
    Creator=0x7ffff6e2aff0 <llvm::object_creator<llvm::cl::SubCommand>::call()>, Deleter=0x7ffff6e2b090 <llvm::object_deleter<llvm::cl::SubCommand>::call(void*)>)
    at ../llvm-6.0.0.src/lib/Support/ManagedStatic.cpp:45
#3  0x00007ffff6e26188 in llvm::ManagedStatic<llvm::cl::SubCommand, llvm::object_creator<llvm::cl::SubCommand>, llvm::object_deleter<llvm::cl::SubCommand> >::operator* (
    this=0x7ffff77e0758 <llvm::cl::AllSubCommands>) at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:67
#4  (anonymous namespace)::CommandLineParser::registerSubCommand (this=0x611290, sub=0x6113c0) at ../llvm-6.0.0.src/lib/Support/CommandLine.cpp:297
#5  0x00007ffff6e2b1ea in (anonymous namespace)::CommandLineParser::CommandLineParser (this=0x611290) at ../llvm-6.0.0.src/lib/Support/CommandLine.cpp:108
#6  llvm::object_creator<(anonymous namespace)::CommandLineParser>::call () at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:24
#7  0x00007ffff6e33e2f in llvm::ManagedStaticBase::RegisterManagedStatic (this=0x7ffff77e0708 <GlobalParser>,
    Creator=0x7ffff6e2b140 <llvm::object_creator<(anonymous namespace)::CommandLineParser>::call()>,
    Deleter=0x7ffff6e2b230 <llvm::object_deleter<(anonymous namespace)::CommandLineParser>::call(void*)>) at ../llvm-6.0.0.src/lib/Support/ManagedStatic.cpp:45
#8  0x00007ffff6e25144 in llvm::ManagedStatic<(anonymous namespace)::CommandLineParser, llvm::object_creator<(anonymous namespace)::CommandLineParser>, llvm::object_deleter<(anonymous namespace)::CommandLineParser> >::operator* (this=<optimized out>) at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:67
#9  llvm::ManagedStatic<(anonymous namespace)::CommandLineParser, llvm::object_creator<(anonymous namespace)::CommandLineParser>, llvm::object_deleter<(anonymous namespace)::CommandLineParser> >::operator-> (this=<optimized out>) at ../llvm-6.0.0.src/include/llvm/Support/ManagedStatic.h:72
#10 llvm::cl::Option::addArgument (this=0x7ffff77c3060 <EnableBasePointer>) at ../llvm-6.0.0.src/lib/Support/CommandLine.cpp:356
#11 0x00007ffff5c0996c in _GLOBAL__sub_I_X86RegisterInfo.cpp () at ../llvm-6.0.0.src/include/llvm/Support/CommandLine.h:1338
#12 0x00007ffff7de7eab in call_init (l=<optimized out>, argc=argc@entry=2, argv=argv@entry=0x7fffffffe5f8, env=env@entry=0x7fffffffe610) at dl-init.c:72
#13 0x00007ffff7de7fcc in call_init (env=0x7fffffffe610, argv=0x7fffffffe5f8, argc=2, l=<optimized out>) at dl-init.c:30
#14 _dl_init (main_map=main_map@entry=0x602450, argc=2, argv=0x7fffffffe5f8, env=0x7fffffffe610) at dl-init.c:120
#15 0x00007ffff7decaa0 in dl_open_worker (a=a@entry=0x7fffffffe250) at dl-open.c:572
#16 0x00007ffff7de7d18 in _dl_catch_error (objname=objname@entry=0x7fffffffe240, errstring=errstring@entry=0x7fffffffe248, mallocedp=mallocedp@entry=0x7fffffffe23f,
    operate=operate@entry=0x7ffff7dec6c0 <dl_open_worker>, args=args@entry=0x7fffffffe250) at dl-error.c:187
#17 0x00007ffff7debf89 in _dl_open (file=0x7fffffffe824 "/usr/lib64/dri/swrast_dri.so", mode=-2147483647, caller_dlopen=0x400669 <main+99>, nsid=-2,
    argc=<optimized out>, argv=<optimized out>, env=0x7fffffffe610) at dl-open.c:657
#18 0x00007ffff7bd4f23 in dlopen_doit (a=a@entry=0x7fffffffe4b0) at dlopen.c:66
#19 0x00007ffff7de7d18 in _dl_catch_error (objname=0x7ffff7dd7070 <last_result+16>, errstring=0x7ffff7dd7078 <last_result+24>, mallocedp=0x7ffff7dd7068 <last_result+8>,
    operate=0x7ffff7bd4ec0 <dlopen_doit>, args=0x7fffffffe4b0) at dl-error.c:187
#20 0x00007ffff7bd559a in _dlerror_run (operate=operate@entry=0x7ffff7bd4ec0 <dlopen_doit>, args=args@entry=0x7fffffffe4b0) at dlerror.c:163
#21 0x00007ffff7bd4fc5 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#22 0x0000000000400669 in main ()
(gdb) cont
Continuing.
Cc: manojgupta@chromium.org
+manojgupta for guidance on LLVM potentially leaking memory.

I manually stepped through every occurrence of operator new and they all showed up in llvm.

I can't see any issues with the megadriver_stub_init from inspection.


This leaking llvm is the one used by mesa IIUC, not the host llvm used for building.
I recall from my GPU days that ManagedStatics and dlopen/dlclose didn't interact very well with each other.

The solution used to be to call llvm_shutdown() before doing dlclose().
Can you try that?
Cc: tutankhamen@chromium.org
Re c#4:

Correct, this is the mesa llvm, not the host toolchain.

By llvm_shutdown, I assume mean one that's in the shared library, but I don't see any definitions of it either via nm or dlsym().
If llvm_shutdown can't be called at dlclose location, can the library itself call llvm_shutdown by adding a destructor function like this:

void __attribute__((destructor)) function_shutdown()
{
    llvm_shutdown();
}
It's better if llvm_shutdown() is called.  I added it to src/gallium/auxiliary/gallivm/lp_bld_misc.cpp and then re-ran my test program:
==29646== LEAK SUMMARY:
==29646==    definitely lost: 16 bytes in 1 blocks
==29646==    indirectly lost: 40 bytes in 1 blocks
==29646==      possibly lost: 0 bytes in 0 blocks
==29646==    still reachable: 6,458 bytes in 20 blocks
==29646==         suppressed: 0 bytes in 0 blocks
==29646==
==29646== For counts of detected and suppressed errors, rerun with: -v
==29646== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Here's without calling llvm_shutdown for reference:
==30004== LEAK SUMMARY:
==30004==    definitely lost: 552 bytes in 5 blocks
==30004==    indirectly lost: 34,484 bytes in 505 blocks
==30004==      possibly lost: 0 bytes in 0 blocks
==30004==    still reachable: 6,458 bytes in 20 blocks
==30004==         suppressed: 0 bytes in 0 blocks
==30004==
==30004== For counts of detected and suppressed errors, rerun with: -v
==30004== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)

There's still what appears to be two allocations from llvm:
==30541== 40 bytes in 1 blocks are indirectly lost in loss record 1 of 7
==30541==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30541==    by 0x664AF02: ???
==30541==    by 0x661EFBF: ???
==30541==    by 0x417D7DC: std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) (in /usr/lib64/libc++.so.1.0)
==30541==    by 0x661EE64: ???
==30541==    by 0x6610193: ???
==30541==    by 0x53F496B: ???
==30541==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30541==    by 0x400FFCB: call_init (dl-init.c:30)
==30541==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30541==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4013F88: _dl_open (dl-open.c:657)
==30541==
==30541== 56 (16 direct, 40 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 7
==30541==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30541==    by 0x417D8D9: operator new(unsigned long) (in /usr/lib64/libc++.so.1.0)
==30541==    by 0x661EFAF: ???
==30541==    by 0x417D7DC: std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) (in /usr/lib64/libc++.so.1.0)
==30541==    by 0x661EE64: ???
==30541==    by 0x6610193: ???
==30541==    by 0x53F496B: ???
==30541==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30541==    by 0x400FFCB: call_init (dl-init.c:30)
==30541==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30541==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4013F88: _dl_open (dl-open.c:657)

Then there seem to be a number related to the dynamic library dependencies, including some leaked from the dlclose():
==30541== 90 bytes in 4 blocks are still reachable in loss record 3 of 7
==30541==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30541==    by 0x4007506: open_path (dl-load.c:1904)
==30541==    by 0x4009260: _dl_map_object (dl-load.c:2177)
==30541==    by 0x400D6B9: openaux (dl-deps.c:63)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x400D92A: _dl_map_object_deps (dl-deps.c:254)
==30541==    by 0x40147E3: dl_open_worker (dl-open.c:269)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4013F88: _dl_open (dl-open.c:657)
==30541==    by 0x4A27F22: dlopen_doit (dlopen.c:66)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4A28599: _dlerror_run (dlerror.c:163)
==30541==
==30541== 90 bytes in 4 blocks are still reachable in loss record 4 of 7
==30541==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30541==    by 0x400BB6F: _dl_new_object (dl-object.c:165)
==30541==    by 0x4005A60: _dl_map_object_from_fd (dl-load.c:1023)
==30541==    by 0x4008CD8: _dl_map_object (dl-load.c:2256)
==30541==    by 0x400D6B9: openaux (dl-deps.c:63)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x400D92A: _dl_map_object_deps (dl-deps.c:254)
==30541==    by 0x40147E3: dl_open_worker (dl-open.c:269)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4013F88: _dl_open (dl-open.c:657)
==30541==    by 0x4A27F22: dlopen_doit (dlopen.c:66)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==
==30541== 128 bytes in 4 blocks are still reachable in loss record 5 of 7
==30541==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30541==    by 0x4015B42: _dl_close_worker.part.0 (dl-close.c:393)
==30541==    by 0x4016419: _dl_close_worker (dl-close.c:125)
==30541==    by 0x4016419: _dl_close (dl-close.c:822)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4A28599: _dlerror_run (dlerror.c:163)
==30541==    by 0x4A2802E: dlclose (dlclose.c:46)
==30541==    by 0x400723: main (in /tmp/a.out)
==30541==
==30541== 1,296 bytes in 4 blocks are still reachable in loss record 6 of 7
==30541==    at 0x402FB71: calloc (vg_replace_malloc.c:711)
==30541==    by 0x4011812: _dl_check_map_versions (dl-version.c:293)
==30541==    by 0x4014CA8: dl_open_worker (dl-open.c:275)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4013F88: _dl_open (dl-open.c:657)
==30541==    by 0x4A27F22: dlopen_doit (dlopen.c:66)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4A28599: _dlerror_run (dlerror.c:163)
==30541==    by 0x4A27FC4: dlopen@@GLIBC_2.2.5 (dlopen.c:87)
==30541==    by 0x4006C8: main (in /tmp/a.out)
==30541==
==30541== 4,854 bytes in 4 blocks are still reachable in loss record 7 of 7
==30541==    at 0x402FB71: calloc (vg_replace_malloc.c:711)
==30541==    by 0x400B869: _dl_new_object (dl-object.c:75)
==30541==    by 0x4005A60: _dl_map_object_from_fd (dl-load.c:1023)
==30541==    by 0x4008CD8: _dl_map_object (dl-load.c:2256)
==30541==    by 0x400D6B9: openaux (dl-deps.c:63)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x400D92A: _dl_map_object_deps (dl-deps.c:254)
==30541==    by 0x40147E3: dl_open_worker (dl-open.c:269)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30541==    by 0x4013F88: _dl_open (dl-open.c:657)
==30541==    by 0x4A27F22: dlopen_doit (dlopen.c:66)
==30541==    by 0x400FD17: _dl_catch_error (dl-error.c:187)

For comparison, here's what happens if I do 10x dlopen/dlclose:

w/ llvm_shutdown
==30666== LEAK SUMMARY:
==30666==    definitely lost: 160 bytes in 10 blocks
==30666==    indirectly lost: 400 bytes in 10 blocks
==30666==      possibly lost: 0 bytes in 0 blocks
==30666==    still reachable: 6,330 bytes in 16 blocks
==30666==         suppressed: 0 bytes in 0 blocks

w/o:
==30665== LEAK SUMMARY:
==30665==    definitely lost: 5,520 bytes in 50 blocks
==30665==    indirectly lost: 344,840 bytes in 5,050 blocks
==30665==      possibly lost: 0 bytes in 0 blocks
==30665==    still reachable: 6,330 bytes in 16 blocks
==30665==         suppressed: 0 bytes in 0 blocks

Not ideal still, but 56 bytes per dlopen()/dlclose9) should be manageable and not cause OOMs.  The still reachable looks like a one-time hit.
The 16/40 byte leaks I think is from the following mutex:
==30712== 16 bytes in 1 blocks are still reachable in loss record 1 of 9
==30712==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30712==    by 0x417D8D9: operator new(unsigned long) (in /usr/lib64/libc++.so.1.0)
==30712==    by 0x661EFAF: initializeMutex() (ManagedStatic.cpp:27)
==30712==    by 0x417D7DC: std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) (in /usr/lib64/libc++.so.1.0)
==30712==    by 0x661EE64: call_once<void (&)()> (mutex:585)
==30712==    by 0x661EE64: call_once<void (&)()> (Threading.h:101)
==30712==    by 0x661EE64: getManagedStaticMutex (ManagedStatic.cpp:34)
==30712==    by 0x661EE64: llvm::ManagedStaticBase::RegisterManagedStatic(void* (*)(), void (*)(void*)) const (ManagedStatic.cpp:42)
==30712==    by 0x6610193: operator* (ManagedStatic.h:67)
==30712==    by 0x6610193: operator-> (ManagedStatic.h:72)
==30712==    by 0x6610193: llvm::cl::Option::addArgument() (CommandLine.cpp:356)
==30712==    by 0x53F496B: done (CommandLine.h:1338)
==30712==    by 0x53F496B: opt<char [21], llvm::cl::OptionHidden, llvm::cl::initializer<bool>, llvm::cl::desc> (CommandLine.h:1361)
==30712==    by 0x53F496B: __cxx_global_var_init (X86RegisterInfo.cpp:42)
==30712==    by 0x53F496B: _GLOBAL__sub_I_X86RegisterInfo.cpp (X86RegisterInfo.cpp:0)
==30712==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30712==    by 0x400FFCB: call_init (dl-init.c:30)
==30712==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30712==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30712==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30712==    by 0x4013F88: _dl_open (dl-open.c:657)

==30712== 40 bytes in 1 blocks are still reachable in loss record 4 of 9
==30712==    at 0x402C9F4: malloc (vg_replace_malloc.c:299)
==30712==    by 0x664AF02: llvm::sys::MutexImpl::MutexImpl(bool) (Mutex.cpp:50)
==30712==    by 0x661EFBF: SmartMutex (Mutex.h:97)
==30712==    by 0x661EFBF: initializeMutex() (ManagedStatic.cpp:27)
==30712==    by 0x417D7DC: std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) (in /usr/lib64/libc++.so.1.0)
==30712==    by 0x661EE64: call_once<void (&)()> (mutex:585)
==30712==    by 0x661EE64: call_once<void (&)()> (Threading.h:101)
==30712==    by 0x661EE64: getManagedStaticMutex (ManagedStatic.cpp:34)
==30712==    by 0x661EE64: llvm::ManagedStaticBase::RegisterManagedStatic(void* (*)(), void (*)(void*)) const (ManagedStatic.cpp:42)
==30712==    by 0x6610193: operator* (ManagedStatic.h:67)
==30712==    by 0x6610193: operator-> (ManagedStatic.h:72)
==30712==    by 0x6610193: llvm::cl::Option::addArgument() (CommandLine.cpp:356)
==30712==    by 0x53F496B: done (CommandLine.h:1338)
==30712==    by 0x53F496B: opt<char [21], llvm::cl::OptionHidden, llvm::cl::initializer<bool>, llvm::cl::desc> (CommandLine.h:1361)
==30712==    by 0x53F496B: __cxx_global_var_init (X86RegisterInfo.cpp:42)
==30712==    by 0x53F496B: _GLOBAL__sub_I_X86RegisterInfo.cpp (X86RegisterInfo.cpp:0)
==30712==    by 0x400FEAA: call_init.part.0 (dl-init.c:72)
==30712==    by 0x400FFCB: call_init (dl-init.c:30)
==30712==    by 0x400FFCB: _dl_init (dl-init.c:120)
==30712==    by 0x4014A9F: dl_open_worker (dl-open.c:572)
==30712==    by 0x400FD17: _dl_catch_error (dl-error.c:187)
==30712==    by 0x4013F88: _dl_open (dl-open.c:657)
There is a static global Mutex used.

static sys::Mutex *ManagedStaticMutex = nullptr;
http://llvm.org/doxygen/ManagedStatic_8cpp_source.html#l00023

Try adding a call to delete it after llvm_shutdown.
Re c#10: That is a static in llvm so unless I'm missing something that will need llvm changes due to no external visibility to that mutex.

In addition, I ran out of memory after ~28k iterations when I left the fuzzer running over night with:
LSAN_OPTIONS=suppressions=/tmp/suppr.txt ASAN_OPTIONS="halt_on_error=false:log_path=stderr" /usr/libexec/fuzzers/virgl_fuzzer -runs=100000 CORPUS -jobs=100

Live Heap Allocations: 1311140065 bytes in 1288980 chunks; quarantined: 254111732 bytes in 37033 chunks; 12846 other chunks; total chunks: 1338859; showing top 95% (at most 8 unique contexts)
952534960 byte(s) (72%) in 915899 allocation(s)
    #0 0x564477c027ca in calloc (/usr/libexec/fuzzers/virgl_fuzzer+0xf47ca)
    #1 0x7fe32c6d2eeb in __new_exitfn /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:101
    #2 0x7fe32c6d2fd1 in __internal_atexit /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:35
    #3 0x7fe32c6d2fd1 in __cxa_atexit /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:58
    #4 0x564477beedc7 in __cxa_atexit (/usr/libexec/fuzzers/virgl_fuzzer+0xe0dc7)
    #5 0x7fe32d6dceaa in call_init /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-init.c:72
    #6 0x7fe32d6dcfcb in call_init /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-init.c:30
    #7 0x7fe32d6dcfcb in _dl_init /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-init.c:120
    #8 0x7fe32d6e1a9f in dl_open_worker /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-open.c:572
    #9 0x7fe32d6dcd17 in _dl_catch_error /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-error.c:187
    #10 0x7fe32d6e0f88 in _dl_open /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-open.c:657
    #11 0x7fe32ca46f22 in __asprintf /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlopen.c:66
    #12 0x7fe32d6dcd17 in _dl_catch_error /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-error.c:187
    #13 0x7fe32ca47599 in _dlerror_run /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlerror.c:163
    #14 0x7fe32ca46fc4 in dlopen /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlopen.c:87
    #15 0x564477bd12e7 in dlopen (/usr/libexec/fuzzers/virgl_fuzzer+0xc32e7)
    #16 0x7fe3299d6ac5 in dri2_open_driver /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:540:29
    #17 0x7fe3299d6e32 in dri2_load_driver_swrast /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:625:17
    #18 0x7fe3299da6d4 in surfaceless_probe_device /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/platform_surfaceless.c:333:11
    #19 0x7fe3299da2ed in dri2_initialize_surfaceless /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/platform_surfaceless.c:369:27
    #20 0x7fe3299d88eb in dri2_initialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:929:13
    #21 0x7fe3299d4b9e in _eglMatchAndInitialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/main/egldriver.c:69:11
    #22 0x7fe3299d4b9e in _eglMatchDriver /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/main/egldriver.c:90
    #23 0x7fe3299cb035 in eglInitialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/util/./texcompress_rgtc_tmp.h:300:32
    #24 0x564477c2ff40 in initialize_environment /build/amd64-generic/tmp/portage/media-libs/virglrenderer-0.6.0_p20180615/work/virglrenderer-2ec172f4c53bbdd6640b852c8002cd057f6ee108/tests/fuzzer/virgl_fuzzer.c:106:7
    #25 0x564477c2fc74 in LLVMFuzzerTestOneInput /build/amd64-generic/tmp/portage/media-libs/virglrenderer-0.6.0_p20180615/work/virglrenderer-2ec172f4c53bbdd6640b852c8002cd057f6ee108/tests/fuzzer/virgl_fuzzer.c:158:22
    #26 0x564477b3ac7c in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2cc7c)
    #27 0x564477b3a5f5 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2c5f5)
    #28 0x564477b3c353 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2e353)
    #29 0x564477b3cd15 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2ed15)
    #30 0x564477b316d0 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x236d0)
    #31 0x564477b5bca2  (/usr/libexec/fuzzers/virgl_fuzzer+0x4dca2)
    #32 0x7fe32c6bb735 in __libc_start_main /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/csu/../csu/libc-start.c:289

249764320 byte(s) (19%) in 240158 allocation(s)
    #0 0x564477c027ca in calloc (/usr/libexec/fuzzers/virgl_fuzzer+0xf47ca)
    #1 0x7fe32c6d2eeb in __new_exitfn /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:101
    #2 0x7fe32c6d2fd1 in __internal_atexit /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:35
    #3 0x7fe32c6d2fd1 in __cxa_atexit /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:58
    #4 0x564477beedc7 in __cxa_atexit (/usr/libexec/fuzzers/virgl_fuzzer+0xe0dc7)
    #5 0x7fe32d6dcfcb in call_init /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-init.c:30
    #6 0x7fe32d6dcfcb in _dl_init /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-init.c:120
    #7 0x7fe32d6e1a9f in dl_open_worker /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-open.c:572
    #8 0x7fe32d6dcd17 in _dl_catch_error /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-error.c:187
    #9 0x7fe32d6e0f88 in _dl_open /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-open.c:657
    #10 0x7fe32ca46f22 in __asprintf /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlopen.c:66
    #11 0x7fe32d6dcd17 in _dl_catch_error /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-error.c:187
    #12 0x7fe32ca47599 in _dlerror_run /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlerror.c:163
    #13 0x7fe32ca46fc4 in dlopen /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlopen.c:87
    #14 0x564477bd12e7 in dlopen (/usr/libexec/fuzzers/virgl_fuzzer+0xc32e7)
    #15 0x7fe3299d6ac5 in dri2_open_driver /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:540:29
    #16 0x7fe3299d6e32 in dri2_load_driver_swrast /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:625:17
    #17 0x7fe3299da6d4 in surfaceless_probe_device /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/platform_surfaceless.c:333:11
    #18 0x7fe3299da2ed in dri2_initialize_surfaceless /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/platform_surfaceless.c:369:27
    #19 0x7fe3299d88eb in dri2_initialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:929:13
    #20 0x7fe3299d4b9e in _eglMatchAndInitialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/main/egldriver.c:69:11
    #21 0x7fe3299d4b9e in _eglMatchDriver /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/main/egldriver.c:90
    #22 0x7fe3299cb035 in eglInitialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/util/./texcompress_rgtc_tmp.h:300:32
    #23 0x564477c2ff40 in initialize_environment /build/amd64-generic/tmp/portage/media-libs/virglrenderer-0.6.0_p20180615/work/virglrenderer-2ec172f4c53bbdd6640b852c8002cd057f6ee108/tests/fuzzer/virgl_fuzzer.c:106:7
    #24 0x564477c2fc74 in LLVMFuzzerTestOneInput /build/amd64-generic/tmp/portage/media-libs/virglrenderer-0.6.0_p20180615/work/virglrenderer-2ec172f4c53bbdd6640b852c8002cd057f6ee108/tests/fuzzer/virgl_fuzzer.c:158:22
    #25 0x564477b3ac7c in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2cc7c)
    #26 0x564477b3a5f5 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2c5f5)
    #27 0x564477b3c353 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2e353)
    #28 0x564477b3cd15 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2ed15)
    #29 0x564477b316d0 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x236d0)
    #30 0x564477b5bca2  (/usr/libexec/fuzzers/virgl_fuzzer+0x4dca2)
    #31 0x7fe32c6bb735 in __libc_start_main /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/csu/../csu/libc-start.c:289
    #32 0x564477b2ac78 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x1cc78)

35998560 byte(s) (2%) in 34614 allocation(s)
    #0 0x564477c027ca in calloc (/usr/libexec/fuzzers/virgl_fuzzer+0xf47ca)
    #1 0x7fe32c6d2eeb in __new_exitfn /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:101
    #2 0x7fe32c6d2fd1 in __internal_atexit /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:35
    #3 0x7fe32c6d2fd1 in __cxa_atexit /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/stdlib/cxa_atexit.c:58
    #4 0x564477beedc7 in __cxa_atexit (/usr/libexec/fuzzers/virgl_fuzzer+0xe0dc7)
    #5 0x7fe32d6dceaa in call_init /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-init.c:72
    #6 0x7fe32d6dcfcb in call_init /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-init.c:30
    #7 0x7fe32d6dcfcb in _dl_init /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-init.c:120
    #8 0x7fe32d6e1a9f in dl_open_worker /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-open.c:572
    #9 0x7fe32d6dcd17 in _dl_catch_error /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-error.c:187
    #10 0x7fe32d6e0f88 in _dl_open /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-open.c:657
    #11 0x7fe32ca46f22 in __asprintf /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlopen.c:66
    #12 0x7fe32d6dcd17 in _dl_catch_error /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/elf/dl-error.c:187
    #13 0x7fe32ca47599 in _dlerror_run /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlerror.c:163
    #14 0x7fe32ca46fc4 in dlopen /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/dlfcn/dlopen.c:87
    #15 0x564477bd12e7 in dlopen (/usr/libexec/fuzzers/virgl_fuzzer+0xc32e7)
    #16 0x7fe3299d6ac5 in dri2_open_driver /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:540:29
    #17 0x7fe3299d6e32 in dri2_load_driver_swrast /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:625:17
    #18 0x7fe3299da6d4 in surfaceless_probe_device /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/platform_surfaceless.c:333:11
    #19 0x7fe3299da2ed in dri2_initialize_surfaceless /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/platform_surfaceless.c:369:27
    #20 0x7fe3299d88eb in dri2_initialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/drivers/dri2/egl_dri2.c:929:13
    #21 0x7fe3299d4b9e in _eglMatchAndInitialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/main/egldriver.c:69:11
    #22 0x7fe3299d4b9e in _eglMatchDriver /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/egl/main/egldriver.c:90
    #23 0x7fe3299cb035 in eglInitialize /build/amd64-generic/tmp/portage/media-libs/mesa-9999/work/mesa-9999/src/util/./texcompress_rgtc_tmp.h:300:32
    #24 0x564477c2ff40 in initialize_environment /build/amd64-generic/tmp/portage/media-libs/virglrenderer-0.6.0_p20180615/work/virglrenderer-2ec172f4c53bbdd6640b852c8002cd057f6ee108/tests/fuzzer/virgl_fuzzer.c:106:7
    #25 0x564477c2fc74 in LLVMFuzzerTestOneInput /build/amd64-generic/tmp/portage/media-libs/virglrenderer-0.6.0_p20180615/work/virglrenderer-2ec172f4c53bbdd6640b852c8002cd057f6ee108/tests/fuzzer/virgl_fuzzer.c:158:22
    #26 0x564477b3ac7c in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2cc7c)
    #27 0x564477b3c055 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2e055)
    #28 0x564477b3c366 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2e366)
    #29 0x564477b3cd15 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x2ed15)
    #30 0x564477b316d0 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x236d0)
    #31 0x564477b5bca2  (/usr/libexec/fuzzers/virgl_fuzzer+0x4dca2)
    #32 0x7fe32c6bb735 in __libc_start_main /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/csu/../csu/libc-start.c:289

25166048 byte(s) (1%) in 1 allocation(s)
    #0 0x564477c025e3 in malloc (/usr/libexec/fuzzers/virgl_fuzzer+0xf45e3)
    #1 0x7fe32d8b08d9 in operator new(unsigned long) (/usr/lib64/libc++.so.1+0x8f8d9)
    #2 0x564477b30c2c in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x22c2c)
    #3 0x564477b5bca2  (/usr/libexec/fuzzers/virgl_fuzzer+0x4dca2)
    #4 0x7fe32c6bb735 in __libc_start_main /var/tmp/portage/cross-x86_64-cros-linux-gnu/glibc-2.23-r18/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x564477b2ac78 in _init (/usr/libexec/fuzzers/virgl_fuzzer+0x1cc78)

Try if declaring it as extern in mesa works : extern llvm::sys::Mutex *ManagedStaticMutex?

You may have to include "llvm/Support/Mutex.h"
That does not work.  It's a file static so there's going to be no external visibility.  For example, consider if two different .o's declare the same named static, which would that refer to.
Yeah, thats right. Probably trying patching llvm's ManagedStatic.h/.cpp to add a function that would delete this variable and call it after llvm_shutdown() ?
Do I need to do anything special to deploy special versions of llvm or just add a patch called by the ebuild and re-emerge llvm?
I think re-emerging llvm should be enough but I don't know much about the mesa driver builds.
llvm is linked statically into mesa, so re-emerge llvm, then re-emerge mesa.
https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1135771 is a patch for the LLVM used on targets to add an llvm_shutdown_final() API.
Project Member

Comment 19 by bugdroid1@chromium.org, Jul 19

The following revision refers to this bug:
  https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/48d2654595d328f63173a7ae1cbbbb8f5deeb903

commit 48d2654595d328f63173a7ae1cbbbb8f5deeb903
Author: David Riley <davidriley@chromium.org>
Date: Thu Jul 19 19:13:44 2018

virglrenderer: Update fuzzer to reinitialize context with each input.

Resources were being leaked if virgl_renderer_submit_cmd is just
called repeatedly.  At the other extreme, eglInitialize()/eglTerminate()
with each input results in memory leaks from repeated dlopen()/dlclose()
of the mesa swrast_dri.so driver file.

BUG= chromium:862699 
TEST=echo "leak:eglInitialize" >/tmp/suppr.txt; LSAN_OPTIONS=suppressions=/tmp/suppr.txt ASAN_OPTIONS="halt_on_error=false:log_path=stderr" /usr/libexec/fuzzers/virgl_fuzzer -runs=10000

Change-Id: I5be8c07bf587cb5b8767869f4f57494cca9649c7
Reviewed-on: https://chromium-review.googlesource.com/1140741
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: David Riley <davidriley@chromium.org>
Reviewed-by: Pohsien Wang <pwang@chromium.org>

[modify] https://crrev.com/48d2654595d328f63173a7ae1cbbbb8f5deeb903/media-libs/virglrenderer/files/virglrenderer-0.6.0-fuzzer.patch

Project Member

Comment 20 by bugdroid1@chromium.org, Jul 19

The following revision refers to this bug:
  https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/0272f31d5f40bbbee9782e37985977493af52cce

commit 0272f31d5f40bbbee9782e37985977493af52cce
Author: David Riley <davidriley@chromium.org>
Date: Thu Jul 19 19:13:46 2018

virglrenderer: Add fuzzer suppressions for eglInitialize leaks.

eglTerminate is explicitly not called due to leaks associated with
repeatedly calling dlopen()/dlclose() on the mesa driver.

BUG= chromium:862699 
TEST=ASAN_OPTIONS="log_path=stderr" /usr/libexec/fuzzers/virgl_fuzzer

Change-Id: Ib3a352c9a62462e83767b7486b458db9e733ce0a
Reviewed-on: https://chromium-review.googlesource.com/1140907
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: David Riley <davidriley@chromium.org>
Reviewed-by: Pohsien Wang <pwang@chromium.org>

[modify] https://crrev.com/0272f31d5f40bbbee9782e37985977493af52cce/media-libs/virglrenderer/files/virglrenderer-0.6.0-fuzzer.patch
[rename] https://crrev.com/0272f31d5f40bbbee9782e37985977493af52cce/media-libs/virglrenderer/virglrenderer-0.6.0_p20180716-r2.ebuild

Project Member

Comment 21 by bugdroid1@chromium.org, Jul 28

The following revision refers to this bug:
  https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/02c8bd18a6cecea1cb0b8acff9dba529454f89d0

commit 02c8bd18a6cecea1cb0b8acff9dba529454f89d0
Author: David Riley <davidriley@chromium.org>
Date: Sat Jul 28 05:33:19 2018

virglrenderer: Update to upstream, remove local fuzzer patch.

From: 0fb73b11e4cdadced885e52848002b2e9c79e3f5
To: 9c420d224d86215d408dff8dea599ed9414a24d6

9c420d2 vrend, caps: Move GL only caps into newly created function
f4ac4c6 vrend, caps: Move the sanity checks up in the call hierarchy
60521af vrend, caps: Split GL/GLES version checking and move caps set check up
97ddb62 vrend: remove superfluous initializations
c2e457e vrend: correct the stride if the client sends it
cd14ff1 renderer: Protect glSampleMaski and GL_SAMPLE_MASK.
519a091 shader_buffers: fix macros and use in decode.
42e2a4c vrend: use the row-stride when directly reading back to an IOV
34809ef vrend: Set scissor_state_dirty correctly.
58e521c get rid of yet another bind-flag set
2e84388 discourage using legacy-definitions
dc1bc1e get rid of diplicate definition of VREND_RES_BIND-flags
5ff40d5 add VIRGL_BIND_*-flags from mesa
9eaf2c8 features: disallow ssbos if we don't have the feature (v2)
6a6f3c4 features: add ubo feature (v2)
7958225 features: add transform_feedback feature (v2)
4145714 features: add multisample texture feature.
dd2f62b features: add cube map array feature.
c8d3c59 features: add texture array feature
4593bef features: add conditional render inverted.
0dc96e9 features: add transform feedback overflow query
ea7f3c1 features: add geometry shader feature
e8eeea7 features: add dual src blend support
1497dd9 features: add viewport array feature
4ed679c features: use correct extensions for tbo size
2704d81 features: add independent blend function feature.
c402e82 features: add indirect draw feature.
35356ec features: add independent blend enable feature
36ac335 features: add base instance feature.
7c23f33 features: add draw_instance feature.
c8269ae renderer: get return value from draw vbo.
31049f6 features: move existing features to a table init (v2)
87d8671 features: add transform_feedback3 feature
6ff41a3 features: move some caps to use has_feature flags
edd2478 Fix create_shader buf boundary check
fe7a1ef gles: report maximum vertex-attrib stride to guest
e898b8f Avoid needless repetition
2c0d096 use short-hand state accessors
7a37a36 Fix NULL dereference in vrend_draw_bind_samplers_shader
87b346a fuzzer: Add a libFuzzer based fuzzer.
5057fb9 tests: Fix virgl_init_cbs_wrong_ver test
79479ac blitter, GL blit fallback: clean up framebuffer after use
eb9555c features: convert current feature list to an array (v2)
cdf8860 renderer: fix ambiguous else warning
97b9df0 add a cap for TGSI precise modifiers
47387e4 emit precise keyword
ef70cef tgsi/text: parse _PRECISE modifier
46d2cf8 tgsi: populate precise
654647c protect calls to glPrimitiveRestart on GLES 3.1
39add38 protect gl{Begin, End}ConditionalRendering calls
4349893 protect call to glDeleteSamplers
89f7995 protect call to glPrimitiveRestartIndex
ec454b9 renderer: fix ssbo != -1 comparison.
df7322e ssbo: reorder var assignment
083d97f renderer: add shader_storage_buffer_object support. (v4)
1800bd4 shader: add basic shader_storage_buffer_object parsing. (v4)
4013fbc gallium: import MAX_SHADER_BUFFERS from mesa
dfa1e8c u_math: bring over u_bit_scan_consecutive_range.
7f96206 shader: drop unused sviews_used
249fb00 shader: pass sinfo/dinfo into translate_tex
a04a63e virgl-caps: Report support for GL_ARB_copy_image to the guest
8ad0201 vrend_formats: Replace RGB(8|16) formats with RGBX(8|16)
2846dcf vrend: If available use glCopyImageSubData to execute memcopy like blits
be3b107 vrend: Remove bad sRGB warning on GLES
cae96e1 shader: drop unused function.
e387116 report maximum vertex-attrib stride to host
6a4ef6d renderer: swizzle sampler border color channel if we emulate alpha format

BUG= chromium:852111 , chromium:864689 , chromium:862699 , chromium:864695 , chromium:864792 
TEST=ASAN_OPTIONS="log_path=stderr" /usr/libexec/fuzzers/virgl_fuzzer

Change-Id: I6e9b40675053dc1f18af6dfd888a145caecf13b7
Reviewed-on: https://chromium-review.googlesource.com/1153607
Commit-Ready: Manoj Gupta <manojgupta@chromium.org>
Tested-by: Manoj Gupta <manojgupta@chromium.org>
Reviewed-by: Pohsien Wang <pwang@chromium.org>

[delete] https://crrev.com/6c1c4a5360e6a3a124cc64ebdc22943fbeb8211a/media-libs/virglrenderer/files/virglrenderer-0.6.0-fuzzer.patch
[delete] https://crrev.com/6c1c4a5360e6a3a124cc64ebdc22943fbeb8211a/media-libs/virglrenderer/virglrenderer-0.6.0_p20180716-r2.ebuild
[modify] https://crrev.com/02c8bd18a6cecea1cb0b8acff9dba529454f89d0/media-libs/virglrenderer/Manifest
[rename] https://crrev.com/02c8bd18a6cecea1cb0b8acff9dba529454f89d0/media-libs/virglrenderer/virglrenderer-0.6.0_p20180727.ebuild

Status: Fixed (was: Untriaged)

Sign in to add a comment