public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
* dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
@ 2020-11-20  6:52 Wendeborn, Jonathan
  2020-11-20  7:17 ` Konstantin Kharlamov
  2020-11-20 11:33 ` Florian Weimer
  0 siblings, 2 replies; 11+ messages in thread
From: Wendeborn, Jonathan @ 2020-11-20  6:52 UTC (permalink / raw)
  To: libc-help

Hi,

I am a C++ developer but usually programming and debugging on Windows (so please excuse any wrong terms). Now I'm compiling my program on Linux (gcc 9.3.0 on Debian Bullseye with Boost 1.70) for the first time and get a Segfault in my unit tests.
Luckily I was able to write a reproducer and boil it down to my code overwriting the .so file after having it loaded (and unloaded):

#include <boost/filesystem/operations.hpp>
#include <boost/dll/shared_library.hpp>
#include <iostream>

void doit() {
    boost::filesystem::copy_file("~/project/target/references/bin/libSomething.so", "~/project/build/bin/ linux-x86_64-gcc9-debug/ libSomething.so", boost::filesystem::copy_option::overwrite_if_exists);

    boost::dll::shared_library l;
    std::cout << "pre load" << std::endl;
    l.load("./libSomething.so");
    std::cout << "loaded" << std::endl;
}
int main() {
    doit();
    doit();
    return 0;
}

Output :


The destructor ~shared_library() calls dlclose(), but I suspect the library stays loaded. Overwriting the file creates a new file node and my program wants to load the same library again (at the same location but with a different file node/handle).
This works on Windows because the library is really unloaded after ~shared_library() (otherwise copy_file() would fail as Windows does not support overwriting files in use anyway).

I did debug into dlopen() and think the error gets visible in dl_lookup_x(): In there the strtab and symtab pointers don't have valid pointers the second time, i.e. they have the quite small value from the beginning of elf_get_dynamic_info() (l.51), the l_addr offset from the second part of elf_get_dynamic_info() wasn't added (l.104).
Sure I'm going to rewrite my tests (I'm going to not copy the files at all anymore) but I thought this could be of interest for you.

Best regards,
Jonathan


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20  6:52 dlopen: Segfault due to overwriting .so file after it was loaded and loading it again Wendeborn, Jonathan
@ 2020-11-20  7:17 ` Konstantin Kharlamov
  2020-11-20  8:01   ` AW: " Wendeborn, Jonathan
  2020-11-20 11:33 ` Florian Weimer
  1 sibling, 1 reply; 11+ messages in thread
From: Konstantin Kharlamov @ 2020-11-20  7:17 UTC (permalink / raw)
  To: Wendeborn, Jonathan, libc-help

On Fri, 2020-11-20 at 06:52 +0000, Wendeborn, Jonathan via Libc-help wrote:
> Hi,
>
> I am a C++ developer but usually programming and debugging on Windows (so
> please excuse any wrong terms). Now I'm compiling my program on Linux (gcc
> 9.3.0 on Debian Bullseye with Boost 1.70) for the first time and get a
> Segfault in my unit tests.
> Luckily I was able to write a reproducer and boil it down to my code
> overwriting the .so file after having it loaded (and unloaded):

I can't seem to reproduce it. I modified paths in your testcase as fololows:

    #include <boost/filesystem/operations.hpp>
    #include <boost/dll/shared_library.hpp>
    #include <iostream>

    void doit() {
        boost::filesystem::copy_file("/tmp/libSomething.so", "/tmp/libSomething2.so", boost::filesystem::copy_option::overwrite_if_exists);

        boost::dll::shared_library l;
        std::cout << "pre load" << std::endl;
        l.load("/tmp/libSomething2.so");
        std::cout << "loaded" << std::endl;
    }
    int main() {
        doit();
        doit();
        return 0;
    }

And I build it with

    g++ test.cpp -o a -g3 -O0 -Wall -Wextra -Wsign-conversion -std=c++17 -fsanitize=address -ldl -lboost_filesystem -lboost_system

Running it I get no segfault, just output:

    λ ./a
    pre load
    loaded
    pre load
    loaded

Please try placing the lib into `/tmp/libSomething` and running the app, do you still see crash?



^ permalink raw reply	[flat|nested] 11+ messages in thread

* AW: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20  7:17 ` Konstantin Kharlamov
@ 2020-11-20  8:01   ` Wendeborn, Jonathan
  2020-11-20  8:15     ` Konstantin Kharlamov
  0 siblings, 1 reply; 11+ messages in thread
From: Wendeborn, Jonathan @ 2020-11-20  8:01 UTC (permalink / raw)
  To: Konstantin Kharlamov, libc-help

Hi,

Thank you for your quick answer!
I don't have Boost installed globally, so I had to adjust the command:
g++9 -g3 -O0 -Wall -Wextra -Wsign-conversion -std=c++17 -fsanitize=address  -o test2 test.cpp  -I/home/Jonathan.Wendeborn/.boost/1.70/include/  -L/home/Jonathan.Wendeborn/.boost/1.70/bin/boost/linux-x86_64-gcc9-debug  -Wl,-Bstatic -lboost_filesystem -lboost_system  -Wl,-Bdynamic -ldl

This is the output:
./test2
pre load
loaded
pre load
loaded
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2872455==ERROR: AddressSanitizer: SEGV on unknown address 0x000000657726 (pc 0x000000657726 bp 0x000000000000 sp 0x7ffc91e7d0a8 T0)
==2872455==The signal is caused by a READ memory access.
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer: nested bug in the same thread, aborting.

I didn't test my program with a different .so before, so I copied libboost_regex.so to libSomething.so and get a Segfault, too:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2872492==ERROR: AddressSanitizer: SEGV on unknown address 0x000000019bd0 (pc 0x000000019bd0 bp 0x7ffe22f7b9f0 sp 0x7ffe22f7b938 T0)
==2872492==The signal is caused by a READ memory access.

It doesn't crash when doing this with libboost_system.so, though.

Best regards,
Jonathan


-----Ursprüngliche Nachricht-----
Von: Konstantin Kharlamov <hi-angel@yandex.ru> 
Gesendet: Freitag, 20. November 2020 08:18
An: Wendeborn, Jonathan <Jonathan.Wendeborn@bruker.com>; libc-help@sourceware.org
Betreff: Re: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again

**EXTERNAL EMAIL**

On Fri, 2020-11-20 at 06:52 +0000, Wendeborn, Jonathan via Libc-help wrote:
> Hi,
>
> I am a C++ developer but usually programming and debugging on Windows 
> (so please excuse any wrong terms). Now I'm compiling my program on 
> Linux (gcc
> 9.3.0 on Debian Bullseye with Boost 1.70) for the first time and get a 
> Segfault in my unit tests.
> Luckily I was able to write a reproducer and boil it down to my code 
> overwriting the .so file after having it loaded (and unloaded):

I can't seem to reproduce it. I modified paths in your testcase as fololows:

    #include <boost/filesystem/operations.hpp>
    #include <boost/dll/shared_library.hpp>
    #include <iostream>

    void doit() {
        boost::filesystem::copy_file("/tmp/libSomething.so", "/tmp/libSomething2.so", boost::filesystem::copy_option::overwrite_if_exists);

        boost::dll::shared_library l;
        std::cout << "pre load" << std::endl;
        l.load("/tmp/libSomething2.so");
        std::cout << "loaded" << std::endl;
    }
    int main() {
        doit();
        doit();
        return 0;
    }

And I build it with

    g++ test.cpp -o a -g3 -O0 -Wall -Wextra -Wsign-conversion -std=c++17 -fsanitize=address -ldl -lboost_filesystem -lboost_system

Running it I get no segfault, just output:

    λ ./a
    pre load
    loaded
    pre load
    loaded

Please try placing the lib into `/tmp/libSomething` and running the app, do you still see crash?



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: AW: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20  8:01   ` AW: " Wendeborn, Jonathan
@ 2020-11-20  8:15     ` Konstantin Kharlamov
  2020-11-20  9:47       ` AW: " Wendeborn, Jonathan
  0 siblings, 1 reply; 11+ messages in thread
From: Konstantin Kharlamov @ 2020-11-20  8:15 UTC (permalink / raw)
  To: Wendeborn, Jonathan, libc-help

On Fri, 2020-11-20 at 08:01 +0000, Wendeborn, Jonathan wrote:
> Hi,
> 
> Thank you for your quick answer!
> I don't have Boost installed globally, so I had to adjust the command:
> g++9 -g3 -O0 -Wall -Wextra -Wsign-conversion -std=c++17 -fsanitize=address  -o
> test2 test.cpp  -I/home/Jonathan.Wendeborn/.boost/1.70/include/  -
> L/home/Jonathan.Wendeborn/.boost/1.70/bin/boost/linux-x86_64-gcc9-debug  -Wl,-
> Bstatic -lboost_filesystem -lboost_system  -Wl,-Bdynamic -ldl
> 
> This is the output:
> ./test2
> pre load
> loaded
> pre load
> loaded
> AddressSanitizer:DEADLYSIGNAL
> =================================================================
> ==2872455==ERROR: AddressSanitizer: SEGV on unknown address 0x000000657726 (pc
> 0x000000657726 bp 0x000000000000 sp 0x7ffc91e7d0a8 T0)
> ==2872455==The signal is caused by a READ memory access.
> AddressSanitizer:DEADLYSIGNAL
> AddressSanitizer: nested bug in the same thread, aborting.
> 
> I didn't test my program with a different .so before, so I copied
> libboost_regex.so to libSomething.so and get a Segfault, too:
> AddressSanitizer:DEADLYSIGNAL
> =================================================================
> ==2872492==ERROR: AddressSanitizer: SEGV on unknown address 0x000000019bd0 (pc
> 0x000000019bd0 bp 0x7ffe22f7b9f0 sp 0x7ffe22f7b938 T0)
> ==2872492==The signal is caused by a READ memory access.

Hmm, doesn't crash with libboost_regex.so for me either… Okay, could you please
provide an `strace` of the testcase when it crashes? Hopefully it could shine
some light into what's going on.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* AW: AW: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20  8:15     ` Konstantin Kharlamov
@ 2020-11-20  9:47       ` Wendeborn, Jonathan
  2020-11-20 10:20         ` Konstantin Kharlamov
  0 siblings, 1 reply; 11+ messages in thread
From: Wendeborn, Jonathan @ 2020-11-20  9:47 UTC (permalink / raw)
  To: Konstantin Kharlamov, libc-help

[-- Attachment #1: Type: text/plain, Size: 2013 bytes --]

Hi Konstantin,

Here you are :)

Best,
Jonathan

-----Ursprüngliche Nachricht-----
Von: Konstantin Kharlamov <hi-angel@yandex.ru> 
Gesendet: Freitag, 20. November 2020 09:16
An: Wendeborn, Jonathan <Jonathan.Wendeborn@bruker.com>; libc-help@sourceware.org
Betreff: Re: AW: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again

**EXTERNAL EMAIL**

On Fri, 2020-11-20 at 08:01 +0000, Wendeborn, Jonathan wrote:
> Hi,
>
> Thank you for your quick answer!
> I don't have Boost installed globally, so I had to adjust the command:
> g++9 -g3 -O0 -Wall -Wextra -Wsign-conversion -std=c++17 
> g++-fsanitize=address  -o
> test2 test.cpp  -I/home/Jonathan.Wendeborn/.boost/1.70/include/  - 
> L/home/Jonathan.Wendeborn/.boost/1.70/bin/boost/linux-x86_64-gcc9-debu
> g  -Wl,- Bstatic -lboost_filesystem -lboost_system  -Wl,-Bdynamic -ldl
>
> This is the output:
> ./test2
> pre load
> loaded
> pre load
> loaded
> AddressSanitizer:DEADLYSIGNAL
> =================================================================
> ==2872455==ERROR: AddressSanitizer: SEGV on unknown address 
> 0x000000657726 (pc
> 0x000000657726 bp 0x000000000000 sp 0x7ffc91e7d0a8 T0) ==2872455==The 
> signal is caused by a READ memory access.
> AddressSanitizer:DEADLYSIGNAL
> AddressSanitizer: nested bug in the same thread, aborting.
>
> I didn't test my program with a different .so before, so I copied 
> libboost_regex.so to libSomething.so and get a Segfault, too:
> AddressSanitizer:DEADLYSIGNAL
> =================================================================
> ==2872492==ERROR: AddressSanitizer: SEGV on unknown address 
> 0x000000019bd0 (pc
> 0x000000019bd0 bp 0x7ffe22f7b9f0 sp 0x7ffe22f7b938 T0) ==2872492==The 
> signal is caused by a READ memory access.

Hmm, doesn't crash with libboost_regex.so for me either… Okay, could you please provide an `strace` of the testcase when it crashes? Hopefully it could shine some light into what's going on.


[-- Attachment #2: strace.txt --]
[-- Type: text/plain, Size: 27460 bytes --]

strace ./test2
execve("./test2", ["./test2"], 0x7ffe657042f0 /* 25 vars */) = 0
brk(NULL)                               = 0x55ac61109000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=47152, ...}) = 0
mmap(NULL, 47152, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7768330000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libasan.so.5", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p*\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=1578440, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776832e000
mmap(NULL, 10648648, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7767906000
mprotect(0x7f7767928000, 1417216, PROT_NONE) = 0
mmap(0x7f7767928000, 1191936, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f7767928000
mmap(0x7f7767a4b000, 221184, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x145000) = 0x7f7767a4b000
mmap(0x7f7767a82000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17b000) = 0x7f7767a82000
mmap(0x7f7767a88000, 9067592, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7767a88000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\21\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=18688, ...}) = 0
mmap(NULL, 20752, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7767900000
mmap(0x7f7767901000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f7767901000
mmap(0x7f7767903000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f7767903000
mmap(0x7f7767904000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f7767904000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\240\t\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=1870824, ...}) = 0
mmap(NULL, 1886208, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7767733000
mmap(0x7f77677c9000, 901120, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x96000) = 0x7f77677c9000
mmap(0x7f77678a5000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x172000) = 0x7f77678a5000
mmap(0x7f77678ef000, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bb000) = 0x7f77678ef000
mmap(0x7f77678fd000, 10240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f77678fd000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0203\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=100736, ...}) = 0
mmap(NULL, 103496, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7767719000
mmap(0x7f776771c000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f776771c000
mmap(0x7f776772d000, 16384, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14000) = 0x7f776772d000
mmap(0x7f7767731000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7f7767731000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0n\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1839792, ...}) = 0
mmap(NULL, 1852680, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7767554000
mprotect(0x7f7767579000, 1662976, PROT_NONE) = 0
mmap(0x7f7767579000, 1355776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f7767579000
mmap(0x7f77676c4000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x170000) = 0x7f77676c4000
mmap(0x7f776770f000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ba000) = 0x7f776770f000
mmap(0x7f7767715000, 13576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7767715000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\2603\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=39912, ...}) = 0
mmap(NULL, 44000, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7767549000
mprotect(0x7f776754c000, 24576, PROT_NONE) = 0
mmap(0x7f776754c000, 16384, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f776754c000
mmap(0x7f7767550000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f7767550000
mmap(0x7f7767552000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x8000) = 0x7f7767552000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 |\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=149608, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7767547000
mmap(NULL, 136304, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7767525000
mmap(0x7f776752c000, 65536, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f776752c000
mmap(0x7f776753c000, 20480, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7f776753c000
mmap(0x7f7767541000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7f7767541000
mmap(0x7f7767543000, 13424, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7767543000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\362\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=1321344, ...}) = 0
mmap(NULL, 1323280, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f77673e1000
mmap(0x7f77673f0000, 630784, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xf000) = 0x7f77673f0000
mmap(0x7f776748a000, 626688, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xa9000) = 0x7f776748a000
mmap(0x7f7767523000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x141000) = 0x7f7767523000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f77673df000
arch_prctl(ARCH_SET_FS, 0x7f77673dfe40) = 0
mprotect(0x7f776770f000, 12288, PROT_READ) = 0
mprotect(0x7f7767523000, 4096, PROT_READ) = 0
mprotect(0x7f7767541000, 4096, PROT_READ) = 0
mprotect(0x7f7767552000, 4096, PROT_READ) = 0
mprotect(0x7f7767731000, 4096, PROT_READ) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f77673dd000
mprotect(0x7f77678ef000, 45056, PROT_READ) = 0
mprotect(0x7f7767904000, 4096, PROT_READ) = 0
mprotect(0x7f7767a82000, 12288, PROT_READ) = 0
mprotect(0x55ac60b24000, 4096, PROT_READ) = 0
mprotect(0x7f7768366000, 4096, PROT_READ) = 0
munmap(0x7f7768330000, 47152)           = 0
set_tid_address(0x7f77673e0110)         = 2872675
set_robust_list(0x7f77673e0120, 24)     = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7f776752c690, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f7767539140}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7f776752c730, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f7767539140}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
readlink("/proc/self/exe", "/tmp/test2", 4096) = 10
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768365000
open("/proc/self/cmdline", O_RDONLY)    = 3
read(3, "./test2\0", 4096)              = 8
read(3, "", 4088)                       = 0
close(3)                                = 0
munmap(0x7f7768365000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768365000
open("/proc/self/environ", O_RDONLY)    = 3
read(3, "SHELL=/bin/bash\0LANGUAGE=en_US:e"..., 4096) = 2224
read(3, "", 1872)                       = 0
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776833a000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768339000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768337000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768336000
mmap(NULL, 3481600, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776708b000
futex(0x7f77679050c8, FUTEX_WAKE_PRIVATE, 2147483647) = 0
getpid()                                = 2872675
write(2, "==2872675==AddressSanitizer: lib"..., 59==2872675==AddressSanitizer: libc interceptors initialized
) = 59
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776707b000
prlimit64(0, RLIMIT_CORE, {rlim_cur=0, rlim_max=0}, NULL) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768335000
open("/proc/self/maps", O_RDONLY)       = 3
read(3, "55ac60aeb000-55ac60af3000 r--p 0"..., 4096) = 3989
read(3, "7f77678ef000-7f77678fa000 r--p 0"..., 107) = 107
close(3)                                = 0
munmap(0x7f7768335000, 4096)            = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768334000
open("/proc/self/maps", O_RDONLY)       = 3
read(3, "55ac60aeb000-55ac60af3000 r--p 0"..., 8192) = 3989
read(3, "7f77678ef000-7f77678fa000 r--p 0"..., 4203) = 2535
read(3, "", 1668)                       = 0
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768333000
open("/proc/self/maps", O_RDONLY)       = 3
read(3, "55ac60aeb000-55ac60af3000 r--p 0"..., 4096) = 3989
read(3, "7f77678ef000-7f77678fa000 r--p 0"..., 107) = 107
close(3)                                = 0
munmap(0x7f7768333000, 4096)            = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768332000
open("/proc/self/maps", O_RDONLY)       = 3
read(3, "55ac60aeb000-55ac60af3000 r--p 0"..., 8192) = 3989
read(3, "7f77678ef000-7f77678fa000 r--p 0"..., 4203) = 2535
read(3, "", 1668)                       = 0
close(3)                                = 0
munmap(0x7f7768332000, 8192)            = 0
write(2, "|| `[0x10007fff8000, 0x7ffffffff"..., 55|| `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
) = 55
write(2, "|| `[0x02008fff7000, 0x10007fff7"..., 55|| `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
) = 55
write(2, "|| `[0x00008fff7000, 0x02008fff6"..., 55|| `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap  ||
) = 55
write(2, "|| `[0x00007fff8000, 0x00008fff6"..., 55|| `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
) = 55
write(2, "|| `[0x000000000000, 0x00007fff7"..., 55|| `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
) = 55
write(2, "MemToShadow(shadow): 0x00008fff7"..., 50MemToShadow(shadow): 0x00008fff7000 0x000091ff6dff) = 50
write(2, " 0x004091ff6e00 0x02008fff6fff", 30 0x004091ff6e00 0x02008fff6fff) = 30
write(2, "\n", 1
)                       = 1
write(2, "redzone=16\n", 11redzone=16
)            = 11
write(2, "max_redzone=2048\n", 17max_redzone=2048
)      = 17
write(2, "quarantine_size_mb=256M\n", 24quarantine_size_mb=256M
) = 24
write(2, "thread_local_quarantine_size_kb="..., 38thread_local_quarantine_size_kb=1024K
) = 38
write(2, "malloc_context_size=30\n", 23malloc_context_size=30
) = 23
write(2, "SHADOW_SCALE: 3\n", 16SHADOW_SCALE: 3
)       = 16
write(2, "SHADOW_GRANULARITY: 8\n", 22SHADOW_GRANULARITY: 8
) = 22
write(2, "SHADOW_OFFSET: 0x7fff8000\n", 26SHADOW_OFFSET: 0x7fff8000
) = 26
mmap(0x7fff7000, 268435456, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7fff7000
madvise(0x7fff7000, 268435456, MADV_NOHUGEPAGE) = 0
madvise(0x7fff7000, 268435456, MADV_DONTDUMP) = 0
mmap(0x2008fff7000, 15392894357504, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x2008fff7000
madvise(0x2008fff7000, 15392894357504, MADV_NOHUGEPAGE) = 0
madvise(0x2008fff7000, 15392894357504, MADV_DONTDUMP) = 0
mmap(0x8fff7000, 2199023255552, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x8fff7000
sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7767073000
sigaltstack({ss_sp=0x7f7767073000, ss_flags=0, ss_size=32768}, NULL) = 0
rt_sigaction(SIGSEGV, {sa_handler=0x7f7767a13df0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_NODEFER|SA_SIGINFO, sa_restorer=0x7f776758fcc0}, NULL, 8) = 0
getpid()                                = 2872675
write(2, "==2872675==Installed the sigacti"..., 49==2872675==Installed the sigaction for signal 11
) = 49
rt_sigaction(SIGBUS, {sa_handler=0x7f7767a13df0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_NODEFER|SA_SIGINFO, sa_restorer=0x7f776758fcc0}, NULL, 8) = 0
getpid()                                = 2872675
write(2, "==2872675==Installed the sigacti"..., 48==2872675==Installed the sigaction for signal 7
) = 48
rt_sigaction(SIGFPE, {sa_handler=0x7f7767a13df0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_NODEFER|SA_SIGINFO, sa_restorer=0x7f776758fcc0}, NULL, 8) = 0
getpid()                                = 2872675
write(2, "==2872675==Installed the sigacti"..., 48==2872675==Installed the sigaction for signal 8
) = 48
mmap(0x600000000000, 4398046523392, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x600000000000
mmap(0x640000000000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x640000000000
mmap(NULL, 8388608, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f7766873000
mmap(NULL, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7766865000
mmap(NULL, 33554432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764865000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768333000
getpid()                                = 2872675
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768332000
open("/proc/self/maps", O_RDONLY)       = 3
read(3, "7fff7000-8fff7000 rw-p 00000000 "..., 4096) = 4080
read(3, "7f77677c9000-7f7", 16)         = 16
close(3)                                = 0
munmap(0x7f7768332000, 4096)            = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768331000
open("/proc/self/maps", O_RDONLY)       = 3
read(3, "7fff7000-8fff7000 rw-p 00000000 "..., 8192) = 4080
read(3, "7f77677c9000-7f77678a5000 r-xp 0"..., 4112) = 2773
read(3, "", 1339)                       = 0
close(3)                                = 0
munmap(0x7f7768334000, 8192)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768335000
open("/proc/self/maps", O_RDONLY)       = 3
read(3, "7fff7000-8fff7000 rw-p 00000000 "..., 4096) = 4080
read(3, "7f77677c9000-7f7", 16)         = 16
close(3)                                = 0
munmap(0x7f7768335000, 4096)            = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768334000
open("/proc/self/maps", O_RDONLY)       = 3
read(3, "7fff7000-8fff7000 rw-p 00000000 "..., 8192) = 4080
read(3, "7f77677c9000-7f77678a5000 r-xp 0"..., 4112) = 2773
read(3, "", 1339)                       = 0
close(3)                                = 0
munmap(0x7f7768334000, 8192)            = 0
mmap(0x10001a513000, 1044480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x10001a513000
madvise(0x10001a513000, 1044480, MADV_NOHUGEPAGE) = 0
madvise(0x10001a513000, 1044480, MADV_DONTDUMP) = 0
getpid()                                = 2872675
write(2, "==2872675==T0: stack [0x7ffcd28d"..., 89==2872675==T0: stack [0x7ffcd28d3000,0x7ffcd30d3000) size 0x800000; local=0x7ffcd30d0bcc
) = 89
sigaltstack(NULL, {ss_sp=0x7f7767073000, ss_flags=0, ss_size=32768}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768335000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768334000
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764665000
munmap(0x7f7764665000, 634880)          = 0
munmap(0x7f7764800000, 413696)          = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7768330000
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764500000
munmap(0x7f7764600000, 1048576)         = 0
mmap(NULL, 1179648, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f77643e0000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f77641e0000
munmap(0x7f77641e0000, 131072)          = 0
munmap(0x7f7764300000, 917504)          = 0
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764000000
munmap(0x7f7764100000, 1048576)         = 0
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
munmap(0x7f7764864000, 4096)            = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764864000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764863000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764862000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764861000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776485f000
munmap(0x7f7764861000, 4096)            = 0
clock_gettime(CLOCK_MONOTONIC, {tv_sec=7440342, tv_nsec=864987995}) = 0
mmap(0x607000000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x607000000000
mmap(0x607e00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x607e00000000
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776484f000
clock_gettime(CLOCK_MONOTONIC, {tv_sec=7440342, tv_nsec=865493136}) = 0
mmap(0x60b000000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x60b000000000
mmap(0x60be00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x60be00000000
clock_gettime(CLOCK_MONOTONIC, {tv_sec=7440342, tv_nsec=865960146}) = 0
mmap(0x624000000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x624000000000
mmap(0x624e00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x624e00000000
getpid()                                = 2872675
write(2, "==2872675==AddressSanitizer Init"..., 38==2872675==AddressSanitizer Init done
) = 38
mmap(0x631000000000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x631000000000
mmap(0x631e00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x631e00000000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764861000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776484e000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776484d000
mmap(NULL, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764844000
munmap(0x7f776484d000, 4096)            = 0
futex(0x7f77678fd6bc, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f77678fd6c8, FUTEX_WAKE_PRIVATE, 2147483647) = 0
mmap(0x603000000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x603000000000
mmap(0x603e00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x603e00000000
mmap(0x631000020000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x631000020000
openat(AT_FDCWD, "/tmp/libSomething.so", O_RDONLY) = 3
stat("/tmp/libSomething.so", {st_mode=S_IFREG|0644, st_size=7784, ...}) = 0
openat(AT_FDCWD, "/tmp/libSomething2.so", O_WRONLY|O_CREAT|O_TRUNC, 0100644) = 4
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\5\0\0\0\0\0\0"..., 65536) = 7784
write(4, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\5\0\0\0\0\0\0"..., 7784) = 7784
read(3, "", 65536)                      = 0
close(3)                                = 0
close(4)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x3), ...}) = 0
mmap(0x619000000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x619000000000
mmap(0x619e00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x619e00000000
write(1, "pre load\n", 9pre load
)               = 9
openat(AT_FDCWD, "/tmp/libSomething2.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\5\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=7784, ...}) = 0
mmap(0x61a000000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x61a000000000
mmap(0x61ae00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x61ae00000000
mmap(NULL, 2101288, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7763dfe000
mprotect(0x7f7763dff000, 2093056, PROT_NONE) = 0
mmap(0x7f7763ffe000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x7f7763ffe000
close(3)                                = 0
mmap(0x60d000000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x60d000000000
mmap(0x60de00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x60de00000000
mprotect(0x7f7763ffe000, 4096, PROT_READ) = 0
write(1, "loaded\n", 7loaded
)                 = 7
munmap(0x7f7763dfe000, 2101288)         = 0
mmap(0x631000030000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x631000030000
openat(AT_FDCWD, "/tmp/libSomething.so", O_RDONLY) = 3
stat("/tmp/libSomething.so", {st_mode=S_IFREG|0644, st_size=7784, ...}) = 0
openat(AT_FDCWD, "/tmp/libSomething2.so", O_WRONLY|O_CREAT|O_TRUNC, 0100644) = 4
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\5\0\0\0\0\0\0"..., 65536) = 7784
write(4, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\5\0\0\0\0\0\0"..., 7784) = 7784
read(3, "", 65536)                      = 0
close(3)                                = 0
close(4)                                = 0
write(1, "pre load\n", 9pre load
)               = 9
openat(AT_FDCWD, "/tmp/libSomething2.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\5\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=7784, ...}) = 0
mmap(NULL, 2101288, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7763dfe000
mprotect(0x7f7763dff000, 2093056, PROT_NONE) = 0
mmap(0x7f7763ffe000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x7f7763ffe000
close(3)                                = 0
mprotect(0x7f7763ffe000, 4096, PROT_READ) = 0
write(1, "loaded\n", 7loaded
)                 = 7
munmap(0x7f7763dfe000, 2101288)         = 0
gettid()                                = 2872675
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f776484d000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7764843000
prctl(PR_GET_DUMPABLE)                  = 1 (SUID_DUMP_USER)
getpid()                                = 2872675
mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7763dff000
mprotect(0x7f7763dff000, 4096, PROT_NONE) = 0
rt_sigprocmask(SIG_BLOCK, ~[ILL ABRT BUS FPE SEGV XCPU XFSZ], [], 8) = 0
clone(child_stack=0x7f7763fffff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED) = 2872677
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
getpid()                                = 2872675
prctl(PR_SET_PTRACER, 2872677)          = 0
futex(0x7ffcd30d0810, FUTEX_WAKE_PRIVATE, 1) = 1
sched_yield()                           = 0
sched_yield()                           = 0
sched_yield()                           = 0
==2872677==Could not attach to thread 2872675 (errno 1).
sched_yield()                           = 0
sched_yield()                           = 0
==2872677==Failed suspending threads.
sched_yield()                           = 0
sched_yield()                           = 0
sched_yield()                           = 0
wait4(2872677, NULL, __WALL, NULL)      = 2872677
munmap(0x7f7763dff000, 2101248)         = 0
getpid()                                = 2872675
write(2, "==2872675==LeakSanitizer has enc"..., 56==2872675==LeakSanitizer has encountered a fatal error.
) = 56
getpid()                                = 2872675
write(2, "==2872675==HINT: For debugging, "..., 104==2872675==HINT: For debugging, try setting environment variable LSAN_OPTIONS=verbosity=1:log_threads=1
) = 104
getpid()                                = 2872675
write(2, "==2872675==HINT: LeakSanitizer d"..., 77==2872675==HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)
) = 77
exit_group(1)                           = ?
+++ exited with 1 +++

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: AW: AW: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20  9:47       ` AW: " Wendeborn, Jonathan
@ 2020-11-20 10:20         ` Konstantin Kharlamov
  0 siblings, 0 replies; 11+ messages in thread
From: Konstantin Kharlamov @ 2020-11-20 10:20 UTC (permalink / raw)
  To: Wendeborn, Jonathan, libc-help

Thanks! I'm not sure it crashed here. I see a LeakSanitizer complaint at the end
, but it's not about a crash. FWIW, I see the same here, probably `strace` does
not get along too well with leak sanitizer. Anyway, if it crashed, you'd seen
something along the lines 

	write(2, "SUMMARY: AddressSanitizer: SEGV "..., 57SUMMARY:
AddressSanitizer: SEGV /tmp/test.cpp:16 in main

On Fri, 2020-11-20 at 09:47 +0000, Wendeborn, Jonathan wrote:
> Hi Konstantin,
> 
> Here you are :)
> 
> Best,
> Jonathan
> 
> -----Ursprüngliche Nachricht-----
> Von: Konstantin Kharlamov <hi-angel@yandex.ru> 
> Gesendet: Freitag, 20. November 2020 09:16
> An: Wendeborn, Jonathan <Jonathan.Wendeborn@bruker.com>;
> libc-help@sourceware.org
> Betreff: Re: AW: dlopen: Segfault due to overwriting .so file after it was
> loaded and loading it again
> 
> **EXTERNAL EMAIL**
> 
> On Fri, 2020-11-20 at 08:01 +0000, Wendeborn, Jonathan wrote:
> > Hi,
> > 
> > Thank you for your quick answer!
> > I don't have Boost installed globally, so I had to adjust the command:
> > g++9 -g3 -O0 -Wall -Wextra -Wsign-conversion -std=c++17 
> > g++-fsanitize=address  -o
> > test2 test.cpp  -I/home/Jonathan.Wendeborn/.boost/1.70/include/  - 
> > L/home/Jonathan.Wendeborn/.boost/1.70/bin/boost/linux-x86_64-gcc9-debu
> > g  -Wl,- Bstatic -lboost_filesystem -lboost_system  -Wl,-Bdynamic -ldl
> > 
> > This is the output:
> > ./test2
> > pre load
> > loaded
> > pre load
> > loaded
> > AddressSanitizer:DEADLYSIGNAL
> > =================================================================
> > ==2872455==ERROR: AddressSanitizer: SEGV on unknown address 
> > 0x000000657726 (pc
> > 0x000000657726 bp 0x000000000000 sp 0x7ffc91e7d0a8 T0) ==2872455==The 
> > signal is caused by a READ memory access.
> > AddressSanitizer:DEADLYSIGNAL
> > AddressSanitizer: nested bug in the same thread, aborting.
> > 
> > I didn't test my program with a different .so before, so I copied 
> > libboost_regex.so to libSomething.so and get a Segfault, too:
> > AddressSanitizer:DEADLYSIGNAL
> > =================================================================
> > ==2872492==ERROR: AddressSanitizer: SEGV on unknown address 
> > 0x000000019bd0 (pc
> > 0x000000019bd0 bp 0x7ffe22f7b9f0 sp 0x7ffe22f7b938 T0) ==2872492==The 
> > signal is caused by a READ memory access.
> 
> Hmm, doesn't crash with libboost_regex.so for me either… Okay, could you
> please provide an `strace` of the testcase when it crashes? Hopefully it could
> shine some light into what's going on.
> 



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20  6:52 dlopen: Segfault due to overwriting .so file after it was loaded and loading it again Wendeborn, Jonathan
  2020-11-20  7:17 ` Konstantin Kharlamov
@ 2020-11-20 11:33 ` Florian Weimer
  2020-11-20 12:45   ` AW: " Wendeborn, Jonathan
  1 sibling, 1 reply; 11+ messages in thread
From: Florian Weimer @ 2020-11-20 11:33 UTC (permalink / raw)
  To: Wendeborn, Jonathan via Libc-help

* Jonathan via Libc-help Wendeborn:

> The destructor ~shared_library() calls dlclose(), but I suspect the
> library stays loaded. Overwriting the file creates a new file node
> and my program wants to load the same library again (at the same
> location but with a different file node/handle).

This crash happens if the file is truncated on disk and rewritten.
All mapped data is reset to zero if that happens and relocations are
gone.  The kernel does that, there is nothing that glibc can do about
it (Linux does not support MAP_COPY).

So you have two issues here: The library stays loaded (maybe it is
marked as NODELETE, LD_DEBUG=all output logs that in recent glibc
versions), and the file is rewritten in place (and not a “new file
node” is created).

^ permalink raw reply	[flat|nested] 11+ messages in thread

* AW: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20 11:33 ` Florian Weimer
@ 2020-11-20 12:45   ` Wendeborn, Jonathan
  2020-11-20 12:48     ` Florian Weimer
  0 siblings, 1 reply; 11+ messages in thread
From: Wendeborn, Jonathan @ 2020-11-20 12:45 UTC (permalink / raw)
  To: Florian Weimer, Wendeborn, Jonathan via Libc-help, Konstantin Kharlamov

[-- Attachment #1: Type: text/plain, Size: 1422 bytes --]

Hi Florian,

Thank you, that sounds reasonable. Indeed the library is marked NODELETE due to unique symbols. Is it forbidden in general to write executables which are loaded?

I attached the outputs of strace and LD_DEBUG=all if you're interested.

Thanks!
Jonathan 

-----Ursprüngliche Nachricht-----
Von: Florian Weimer <fw@deneb.enyo.de> 
Gesendet: Freitag, 20. November 2020 12:33
An: Wendeborn, Jonathan via Libc-help <libc-help@sourceware.org>
Cc: Wendeborn, Jonathan <Jonathan.Wendeborn@bruker.com>
Betreff: Re: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again

**EXTERNAL EMAIL**

* Jonathan via Libc-help Wendeborn:

> The destructor ~shared_library() calls dlclose(), but I suspect the 
> library stays loaded. Overwriting the file creates a new file node and 
> my program wants to load the same library again (at the same location 
> but with a different file node/handle).

This crash happens if the file is truncated on disk and rewritten.
All mapped data is reset to zero if that happens and relocations are gone.  The kernel does that, there is nothing that glibc can do about it (Linux does not support MAP_COPY).

So you have two issues here: The library stays loaded (maybe it is marked as NODELETE, LD_DEBUG=all output logs that in recent glibc versions), and the file is rewritten in place (and not a “new file node” is created).

[-- Attachment #2: output.tar.gz --]
[-- Type: application/x-gzip, Size: 253917 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: AW: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20 12:45   ` AW: " Wendeborn, Jonathan
@ 2020-11-20 12:48     ` Florian Weimer
  2020-11-20 12:59       ` AW: " Wendeborn, Jonathan
  0 siblings, 1 reply; 11+ messages in thread
From: Florian Weimer @ 2020-11-20 12:48 UTC (permalink / raw)
  To: Wendeborn, Jonathan
  Cc: Wendeborn, Jonathan via Libc-help, Konstantin Kharlamov

* Jonathan Wendeborn:

> Thank you, that sounds reasonable. Indeed the library is marked
> NODELETE due to unique symbols. Is it forbidden in general to write
> executables which are loaded?

You need to follow a specific sequence: write the new version to a
temporary file, and after it has been written completely, rename that
version over the previous version.  This way, the old file is not
truncated, and mapped versions of it continue to work.

It won't address the dependency on a unique symbol, though, that's
unrelated.  It's not possible for now to unload such objects.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* AW: AW: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
  2020-11-20 12:48     ` Florian Weimer
@ 2020-11-20 12:59       ` Wendeborn, Jonathan
  0 siblings, 0 replies; 11+ messages in thread
From: Wendeborn, Jonathan @ 2020-11-20 12:59 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Wendeborn, Jonathan via Libc-help, Konstantin Kharlamov

Thank you!

^ permalink raw reply	[flat|nested] 11+ messages in thread

* dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
@ 2020-12-04 10:39 Wendeborn, Jonathan
  0 siblings, 0 replies; 11+ messages in thread
From: Wendeborn, Jonathan @ 2020-12-04 10:39 UTC (permalink / raw)
  To: libc-help

Hi,

I am a C++ developer but usually programming and debugging on Windows (so please excuse any wrong terms). Now I'm compiling my program on Linux (gcc 9.3.0 on Debian Bullseye with Boost 1.70) for the first time and get a Segfault in my unit tests.
Luckily I was able to write a reproducer and boil it down to my code overwriting the .so file after having it loaded (and unloaded):

#include <boost/filesystem/operations.hpp>
#include <boost/dll/shared_library.hpp>
#include <iostream>

void doit() {
    boost::filesystem::copy_file("~/project/target/references/bin/libSomething.so", "~/project/build/bin/ linux-x86_64-gcc9-debug/ libSomething.so", boost::filesystem::copy_option::overwrite_if_exists);

    boost::dll::shared_library l;
    std::cout << "pre load" << std::endl;
    l.load("./libSomething.so");
    std::cout << "loaded" << std::endl;
}
int main() {
    doit();
    doit();
    return 0;
}

Output:
pre load
loaded
pre load
loaded
Segmentation fault

When removing the copy_file() call everything is fine. The destructor ~shared_library() calls dlclose(), but I suspect the library stays loaded. Overwriting the file creates a new file node and my program wants to load the same library again (at the same location but with a different file node/handle).
This works on Windows because the library is really unloaded after ~shared_library() (otherwise copy_file() would fail as Windows does not support overwriting files in use anyway).

I did debug into dlopen() and think the error gets visible in dl_lookup_x(): In there the strtab and symtab pointers don't have valid pointers the second time, i.e. they have the quite small value from the beginning of elf_get_dynamic_info() (l.51), the l_addr offset from the second part of elf_get_dynamic_info() wasn't added (l.104).
Sure I'm going to rewrite my tests (I'm going to not copy the files at all anymore) but I thought this could be of interest for you.

Best regards,
Jonathan


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-12-04 10:39 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-20  6:52 dlopen: Segfault due to overwriting .so file after it was loaded and loading it again Wendeborn, Jonathan
2020-11-20  7:17 ` Konstantin Kharlamov
2020-11-20  8:01   ` AW: " Wendeborn, Jonathan
2020-11-20  8:15     ` Konstantin Kharlamov
2020-11-20  9:47       ` AW: " Wendeborn, Jonathan
2020-11-20 10:20         ` Konstantin Kharlamov
2020-11-20 11:33 ` Florian Weimer
2020-11-20 12:45   ` AW: " Wendeborn, Jonathan
2020-11-20 12:48     ` Florian Weimer
2020-11-20 12:59       ` AW: " Wendeborn, Jonathan
2020-12-04 10:39 Wendeborn, Jonathan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).