ASSERT os.c:9179 iter->vm_start == executable_start
After software updates on a particular Linux machine, every time I launch DR in gdb it hits this assert:
<Application <mydir>/build_x64_dbg_tests/suite/tests/bin/linux.rseq (150023). Internal Error: DynamoRIO debug check failure: <mydir>/src/core/unix/os.c:9179 iter->vm_start == executable_start
#6 0x00000000710dbbf2 in d_r_internal_error (file=0x71387e80 "<mydir>/src/core/unix/os.c", line=9179,
expr=0x7138c3e8 "iter->vm_start == executable_start") at <mydir>/src/core/utils.c:176
#7 0x00000000712c8700 in os_walk_address_space (iter=0x7fffffffc320, add_modules=true) at <mydir>/src/core/unix/os.c:9179
#8 0x00000000712c8af8 in find_executable_vm_areas () at <mydir>/src/core/unix/os.c:9255
#9 0x00000000711904bb in vm_areas_init () at <mydir>/src/core/vmareas.c:1668
#10 0x000000007105292d in dynamorio_app_init () at <mydir>/src/core/dynamo.c:646
#11 0x00000000712ead6a in privload_early_inject (sp=0x7fffffffdd80, old_libdr_base=0x7ffff7b86000 <error: Cannot access memory at address 0x7ffff7b86000>,
old_libdr_size=4689920) at <mydir>/src/core/unix/loader.c:1975
I tracked the problem down to the kernel marking DR's .bss as "[heap]":
<dynamorio_lib_gap_empty: not empty @ 0x00007ffff7fa9000 vs dr 0x00007ffff7b85000-0x00007ffff7fff000
$ cat /proc/156485/maps
7ffff7b7a000-7ffff7b80000 r--p 00000000 fe:01 8916978 <mybuild>/suite/tests/bin/linux.rseq
7ffff7b80000-7ffff7b83000 r--p 00000000 00:00 0 [vvar]
7ffff7b83000-7ffff7b85000 r-xp 00000000 00:00 0 [vdso]
7ffff7b85000-7ffff7bc6000 r--p 00000000 fe:01 7605858 <mybuild>/lib64/debug/libdynamorio.so
7ffff7bc6000-7ffff7e86000 r-xp 00041000 fe:01 7605858 <mybuild>/lib64/debug/libdynamorio.so
7ffff7e86000-7ffff7f44000 r--p 00301000 fe:01 7605858 <mybuild>/lib64/debug/libdynamorio.so
7ffff7f44000-7ffff7f45000 ---p 00000000 00:00 0
7ffff7f45000-7ffff7fa9000 rw-p 003bf000 fe:01 7605858 <mybuild>/lib64/debug/libdynamorio.so
7ffff7fa9000-7ffff7fff000 rw-p 00000000 00:00 0 [heap]
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
This triggers a reload of DR, and we have a failure on that path to free the initial mapping of the executable done in elf_loader_read_headers.
So two bugs:
- False obstacle in the "gap"
- Failure to unmap on reload