Thanks for the answers. I have some followup questions below.

On Sun, Jan 12, 2020 at 10:36 PM zhiting zhu <zhiti...@cs.utexas.edu> wrote:

> You can look at this thread:
> https://groups.google.com/forum/#!topic/osv-dev/FLsWldGFUiY
>
> The tests are coming from bionic which is Android's libc. They have their
> own implementation of libdl with lots of tests for each functions. The
> tests that are added to tst-dlfcn.cc are derived from the bionic tests.
>

So, I thought the stuff in dl_tests comes from Bionic, but you're staying
that the code in tst-tlfcn.cc was also copied from Bionic?
Is it an actual copy, or just "inspired" by their test and written by you
from scratch?

If it's a copy, I have to ask:

1. What license does Bionic have? We will need to add Bionic's copyright
statement. Better create a separate test file just for the stuff you copied
from Bionic, so the entire source file has one copyright statement. No need
to stuff this code - if it's copied - into the existing tst-dlfcn.cc file.
We can create a new source file.
2. If you copied test code, why do we need to "git clone" the Bionic
project for the dl_tests module? What does this module do? (oh, I see you
answered this below so I'll continue below).

In the future, please try to make these issues understandable by using
commit messages and/or internal documentation (e.g., a file
modules/dl_tests/README would have been useful).
As I said, I missed the original discussion, but somebody may wonder about
these things two years from now (e.g., when a build suddenly breaks because
"dl_tests" no longer compiles), and would also like to be able to figure
out what these things do.



> I have run these tests on Linux. They can be run without any error. But
> there're some errors when running in osv. Some of the failed checks are
> commented out with TODO comments which is due to incorrect implementation
> of dlopen.
>

> Here's the command if you want to build them and run on linux:
> g++ -std=gnu++11 -Wall -o tst-dlfcn tst-dlfcn.cc -rdynamic -ldl
> -Wl,-Bstatic -lboost_unit_test_framework -Wl,-Bdynamic
> g++ -std=gnu++11 -Wall -o libtest_simple.so -shared -fpic
> dlopen_testlib_simple.cpp
> g++ -std=gnu++11 -Wall -o libtest_empty.so -shared -fpic empty.cpp
> g++ -std=gnu++11 -Wall -o libtest_check_rtld_next_from_library.so -shared
> -fpic check_rtld_next_from_library.cpp
> g++ -std=gnu++11 -Wall -o libtest_dlsym_from_this_grandchild.so -shared
> -fPIC dlsym_from_this_symbol2.cpp
> g++ -std=gnu++11 -Wall -o libtest_dlsym_from_this_child.so -shared -fPIC
> dlsym_from_this_functions.cpp -Wl,--no-as-needed
> -ltest_dlsym_from_this_grandchild -L. -Wl,-rpath=.
> g++ -std=gnu++11 -Wall -o libtest_dlsym_from_this.so -shared -fPIC
> dlsym_from_this_symbol.cpp -Wl,--no-as-needed -ltest_dlsym_from_this_child
> -L. -Wl,-rpath=.
> g++ -std=gnu++11 -Wall -o libdlext_test.so -shared -fPIC
> dlext_test_library.cpp -Wl,-z,relro -Wl,--no-as-needed -ltest_simple -L.
> -Wl,-rpath=.
> g++ -std=gnu++11 -Wall -o libtest_with_dependency.so -shared -fPIC
> dlopen_testlib_simple.cpp -Wl,--no-as-needed -ldlext_test -L. -Wl,-rpath=.
> sudo mkdir -p /tests
> sudo cp *.so /tests
>
> Some of the comments in the code are coming from bionic. Those links
> should be removed.
>
> dl_tests contains the library that's needed by tst-dlfcn.cc. Those library
> are built to help testing dlsym and dlopen. There're no tests in dl_tests.
> The reason for cloning the bionic repo is to avoid license issues. In my
> original patch, I submit those files which contains Android's license
> header. I can add a git checkout to a specific commit.
>

Can you give me an example of why we need a library to "help test dlsym and
dlopen"?
Isn't it an overkill to download the entire bionic project (which I
understood from you is an entire glibc) just to get a few utility functions?
What do these functions do and how hard would it be to just write our own?


>
>
> For enable_if, I'm following the boost unit test document:
> https://www.boost.org/doc/libs/1_72_0/libs/test/doc/html/boost_test/tests_organization/enabling.html
> When the boolean condition is false, those tests would not be run. They are
> failing without the other patches.
>

I see. So I guess your plan is to eventually fix bugs and drop the
"enable_if" thing and make these tests run unconditionally?

Thanks,
Nadav.


>
> Zhiting
>
>
>
> On Sun, Jan 12, 2020 at 4:02 AM Nadav Har'El <n...@scylladb.com> wrote:
>
>>
>> On Fri, Jan 10, 2020 at 9:16 AM Zhiting Zhu <zhiti...@cs.utexas.edu>
>> wrote:
>>
>>> This patch includes a module called dl_tests which clones the bionic
>>> and compile the needed library files.
>>>
>>
>> Hi,
>>
>> Unfortunately, I missed the discussion which led to this commit (I
>> haven't been able
>> to put enough time into OSv recently, sorry about that...).
>>
>> This patch seems to contain two unrelated things:
>> 1. It adds our own tests for dlsym() and friends.
>> 2. It adds a module dl_tests which clones the external project "bionic" -
>> and makes the regular "test" require it.
>>
>> I have some minor questions about #1 (how did you test that this test
>> checks the right thing? Can you run the same test on Linux?)
>> But I'm more bothered by #2:
>>
>> I'm not thrilled that OSv's test build - not some specific image - now
>> needs to clone an external project we have no control over,
>> and moreover, it clones the latest version of that code instead of a
>> specific version.
>> Does this mean our test build can now break at any time due to changes to
>> this external project?
>> Does "make check" even run this dl_tests thing, or not? I didn't
>> understand.
>>
>> More fundementally,  someone please explain to me now (this *should* have
>> been explained in this commit
>> message...), what is this "bionic", what does it test, and why is it even
>> needed given that you wrote our own
>> tests for dlsym and friends?
>>
>> I also have more comments inline, below.
>>
>>
>>> Signed-off-by: Zhiting Zhu <zhiti...@cs.utexas.edu>
>>> ---
>>>  .gitignore                |   2 +
>>>  modules/dl_tests/Makefile | 118 ++++++++++++++++++
>>>  modules/tests/Makefile    |   2 +
>>>  modules/tests/module.py   |   1 +
>>>  tests/tst-dlfcn.cc        | 245 ++++++++++++++++++++++++++++++++++++++
>>>  5 files changed, 368 insertions(+)
>>>  create mode 100644 modules/dl_tests/Makefile
>>>
>>> diff --git a/.gitignore b/.gitignore
>>> index e0a76dc2..2dcb3225 100644
>>> --- a/.gitignore
>>> +++ b/.gitignore
>>> @@ -46,4 +46,6 @@ modules/httpserver-jvm-plugin/obj/
>>>  modules/libtools/*.so
>>>  modules/libtools/*.o
>>>  modules/libyaml/usr.manifest
>>> +modules/dl_tests/bionic/
>>> +modules/dl_tests/usr.manifest
>>>  .idea
>>> diff --git a/modules/dl_tests/Makefile b/modules/dl_tests/Makefile
>>> new file mode 100644
>>> index 00000000..8f3bd0da
>>> --- /dev/null
>>> +++ b/modules/dl_tests/Makefile
>>> @@ -0,0 +1,118 @@
>>> +module: usr.manifest build_all
>>> +
>>> +src := $(OSV_BASE)
>>> +out := $(OSV_BUILD_PATH)
>>> +arch := $(ARCH)
>>> +fs_type := $(fs_type)
>>> +bionic_test_libs := $(src)/modules/dl_tests/bionic/tests/libs
>>> +
>>> +quiet = $(if $V, $1, @echo " $2"; $1)
>>> +very-quiet = $(if $V, $1, @$1)
>>> +makedir = $(call very-quiet, mkdir -p $(dir $@))
>>> +
>>> +autodepend = -MD -MT $@ -MP
>>> +
>>> +INCLUDES = -I$(src)/arch/$(ARCH) -I$(src) -I$(src)/include \
>>> +       -I$(src)/arch/common -isystem $(src)/include/glibc-compat \
>>> +       $(shell $(CXX) -E -xc++ - -v </dev/null 2>&1 | awk '/^End/
>>> {exit} /^ .*c\+\+/ {print "-isystem" $$0}') \
>>> +       -isystem $(src)/include/api -isystem $(src)/include/api/$(ARCH) \
>>> +       -isystem $(out)/gen/include
>>> +
>>> +COMMON = $(autodepend) $(INCLUDES) -g -O2 -fPIC -DBOOST_TEST_DYN_LINK \
>>> +       -U _FORTIFY_SOURCE -D_KERNEL -D__OSV__ -DCONF_debug_memory=0 \
>>> +       -Wall -Wno-pointer-arith -Wformat=0 -Wno-format-security
>>> +
>>> +LIBS =
>>> +
>>> +CXXFLAGS = -std=gnu++11 $(COMMON)
>>> +CFLAGS = -std=gnu99 $(COMMON)
>>> +
>>> +tests := libtest_simple.so libtest_empty.so
>>> libtest_dlsym_from_this_grandchild.so \
>>> +       libtest_dlsym_from_this_child.so libtest_dlsym_from_this.so
>>> libdlext_test.so \
>>> +       libtest_with_dependency.so
>>> libtest_check_rtld_next_from_library.so
>>> +
>>> +.PHONY: get_file
>>> +get_file:
>>> +       if cd $(src)/modules/dl_tests/bionic; then \
>>> +               git pull; \
>>> +       else \
>>> +               git clone --depth=1
>>> https://android.googlesource.com/platform/bionic
>>> $(src)/modules/dl_tests/bionic; \
>>> +       fi
>>> +
>>> +all_tests := $(tests:%=dl_tests/%)
>>> +
>>> +build_all:
>>> +       $(MAKE) get_file
>>> +       $(MAKE) $(all_tests:%=$(out)/%)
>>> +.PHONY: build_all
>>> +
>>> +$(out)/dl_tests/libtest_simple.so:
>>> $(bionic_test_libs)/dlopen_testlib_simple.cpp
>>> +       $(makedir)
>>> +       $(call quiet, cd $(out); $(CXX) $(CXXFLAGS)
>>> -D__SHARED_OBJECT__=1 -shared -o $@ $<, CXX dl_tests/libtest_simple.so)
>>> +
>>> +$(out)/dl_tests/libtest_empty.so: $(bionic_test_libs)/empty.cpp
>>> +       $(makedir)
>>> +       $(call quiet, cd $(out); $(CXX) $(CXXFLAGS)
>>> -D__SHARED_OBJECT__=1 -shared -o $@ $<, CXX dl_tests/libtest_empty.so)
>>> +
>>> +$(out)/dl_tests/libtest_check_rtld_next_from_library.so:
>>> $(bionic_test_libs)/check_rtld_next_from_library.cpp
>>> +       $(makedir)
>>> +       $(call quiet, cd $(out); $(CXX) $(CXXFLAGS)
>>> -D__SHARED_OBJECT__=1 -shared -o $@ $<, CXX
>>> dl_tests/libtest_check_rtld_next_from_library.so)
>>> +
>>> +$(out)/dl_tests/libtest_dlsym_from_this_grandchild.so:
>>> $(bionic_test_libs)/dlsym_from_this_symbol2.cpp
>>> +       $(makedir)
>>> +       $(call quiet, cd $(out); $(CXX) $(CXXFLAGS)
>>> -D__SHARED_OBJECT__=1 -shared -o $@ $<, CXX
>>> dl_tests/libtest_dlsym_from_this_grandchild.so)
>>> +
>>> +$(out)/dl_tests/libtest_dlsym_from_this_child.so: COMMON +=
>>> -Wl,--no-as-needed -ltest_dlsym_from_this_grandchild -L=$(out)/dl_tests
>>> -L=/usr/lib -Wl,-rpath . -Wl,-rpath / -Wl,-rpath /usr/lib
>>> +$(out)/dl_tests/libtest_dlsym_from_this_child.so: \
>>> +               $(bionic_test_libs)/dlsym_from_this_functions.cpp
>>> +       $(MAKE) $(out)/dl_tests/libtest_dlsym_from_this_grandchild.so
>>> +       $(makedir)
>>> +       $(call quiet, cd $(out); $(CXX) $(CXXFLAGS)
>>> -D__SHARED_OBJECT__=1 -shared -o $@ $<, CXX
>>> dl_tests/libtest_dlsym_from_this_child.so)
>>> +
>>> +$(out)/dl_tests/libtest_dlsym_from_this.so: COMMON +=
>>> -Wl,--no-as-needed -ltest_dlsym_from_this_child -L=$(out)/dl_tests
>>> -L=/usr/lib -Wl,-rpath . -Wl,-rpath / -Wl,-rpath /usr/lib
>>> +$(out)/dl_tests/libtest_dlsym_from_this.so: \
>>> +               $(bionic_test_libs)/dlsym_from_this_symbol.cpp
>>> +       $(MAKE) $(out)/dl_tests/libtest_dlsym_from_this_child.so
>>> +       $(makedir)
>>> +       $(call quiet, cd $(out); $(CXX) $(CXXFLAGS)
>>> -D__SHARED_OBJECT__=1 -shared -o $@ $<, CXX
>>> dl_tests/libtest_dlsym_from_this.so)
>>> +
>>> +$(out)/dl_tests/libdlext_test.so: COMMON += -Wl,-z,relro
>>> -Wl,--no-as-needed -ltest_simple -L=$(out)/dl_tests -L=/usr/lib -Wl,-rpath
>>> . -Wl,-rpath / -Wl,-rpath /usr/lib
>>> +$(out)/dl_tests/libdlext_test.so: \
>>> +               $(bionic_test_libs)/dlext_test_library.cpp
>>> +       $(MAKE) $(out)/dl_tests/libtest_simple.so
>>> +       $(makedir)
>>> +       $(call quiet, cd $(out); $(CXX) $(CXXFLAGS)
>>> -D__SHARED_OBJECT__=1 -shared -o $@ $<, CXX dl_tests/libdlext_test.so)
>>> +
>>> +$(out)/dl_tests/libtest_with_dependency.so: COMMON +=
>>> -Wl,--no-as-needed -ldlext_test -L=$(out)/dl_tests -L=/usr/lib -Wl,-rpath .
>>> -Wl,-rpath / -Wl,-rpath /usr/lib
>>> +$(out)/dl_tests/libtest_with_dependency.so: \
>>> +               $(bionic_test_libs)/dlopen_testlib_simple.cpp
>>> +       $(MAKE) $(out)/dl_tests/libdlext_test.so
>>> +       $(makedir)
>>> +       $(call quiet, cd $(out); $(CXX) $(CXXFLAGS)
>>> -D__SHARED_OBJECT__=1 -shared -o $@ $<, CXX
>>> dl_tests/libtest_with_dependency.so)
>>> +
>>> +usr.manifest: build_all FORCE
>>> +       @echo "/usr/lib/libtest_simple.so: ./dl_tests/libtest_simple.so"
>>> > $@
>>> +       @echo "/usr/lib/libtest_empty.so: ./dl_tests/libtest_empty.so"
>>> >> $@
>>> +       @echo "/usr/lib/libtest_dlsym_from_this_grandchild.so:
>>> ./dl_tests/libtest_dlsym_from_this_grandchild.so" >> $@
>>> +       @echo "/usr/lib/libtest_dlsym_from_this_child.so:
>>> ./dl_tests/libtest_dlsym_from_this_child.so" >> $@
>>> +       @echo "/usr/lib/libtest_dlsym_from_this.so:
>>> ./dl_tests/libtest_dlsym_from_this.so" >> $@
>>> +       @echo "/usr/lib/libdlext_test.so: ./dl_tests/libdlext_test.so"
>>> >> $@
>>> +       @echo "/usr/lib/libtest_with_dependency.so:
>>> ./dl_tests/libtest_with_dependency.so" >> $@
>>> +       @echo "/usr/lib/libtest_check_rtld_next_from_library.so:
>>> ./dl_tests/libtest_check_rtld_next_from_library.so" >> $@
>>> +       @echo "/tests/libtest_simple.so: ./dl_tests/libtest_simple.so"
>>> >> $@
>>> +       @echo "/tests/libtest_empty.so: ./dl_tests/libtest_empty.so" >>
>>> $@
>>> +       @echo "/tests/libtest_dlsym_from_this_grandchild.so:
>>> ./dl_tests/libtest_dlsym_from_this_grandchild.so" >> $@
>>> +       @echo "/tests/libtest_dlsym_from_this_child.so:
>>> ./dl_tests/libtest_dlsym_from_this_child.so" >> $@
>>> +       @echo "/tests/libtest_dlsym_from_this.so:
>>> ./dl_tests/libtest_dlsym_from_this.so" >> $@
>>> +       @echo "/tests/libdlext_test.so: ./dl_tests/libdlext_test.so" >>
>>> $@
>>> +       @echo "/tests/libtest_with_dependency.so:
>>> ./dl_tests/libtest_with_dependency.so" >> $@
>>> +       @echo "/tests/libtest_check_rtld_next_from_library.so:
>>> ./dl_tests/libtest_check_rtld_next_from_library.so" >> $@
>>>
>>
>> Unless I'm missing something, this entire chunk of code just writes fixed
>> text to usr.manifest. So why not just
>> have a text file, instead of all these commands?
>>
>> +.PHONY: FORCE
>>> +FORCE:
>>> +
>>> +clean:
>>> +       -rm -f usr.manifest
>>> +
>>> +ifneq ($(MAKECMDGOALS),clean)
>>> +include $(shell test -d $(out)/dl_tests && find $(out)/dl_tests -name
>>> '*.d')
>>> +endif
>>> diff --git a/modules/tests/Makefile b/modules/tests/Makefile
>>> index aac12d3d..ce004339 100644
>>> --- a/modules/tests/Makefile
>>> +++ b/modules/tests/Makefile
>>> @@ -147,6 +147,8 @@ $(out)/tests/tst-mmap.so: COMMON += -fuse-ld=bfd
>>>  $(out)/tests/tst-elf-permissions.so: COMMON += -fuse-ld=bfd
>>>  $(out)/tests/tst-tls.so: COMMON += -fuse-ld=bfd
>>>
>>> +$(out)/tests/tst-dlfcn.so: COMMON += -rdynamic -ldl
>>> +
>>>  $(out)/tests/tst-tls.so: \
>>>                 $(src)/tests/tst-tls.cc \
>>>                 $(out)/tests/libtls.so
>>> diff --git a/modules/tests/module.py b/modules/tests/module.py
>>> index be6315c5..f795280d 100644
>>> --- a/modules/tests/module.py
>>> +++ b/modules/tests/module.py
>>> @@ -1,3 +1,4 @@
>>>  from osv.modules import api
>>>
>>>  api.require('java-tests')
>>> +api.require('dl_tests')
>>> diff --git a/tests/tst-dlfcn.cc b/tests/tst-dlfcn.cc
>>> index 3913c6bf..5258256a 100644
>>> --- a/tests/tst-dlfcn.cc
>>> +++ b/tests/tst-dlfcn.cc
>>> @@ -10,6 +10,16 @@
>>>  #include <dlfcn.h>
>>>
>>>  #include <boost/test/unit_test.hpp>
>>> +namespace utf = boost::unit_test;
>>> +
>>> +const bool rtld_next = false;
>>> +const bool deep_lookup = false;
>>> +
>>> +static bool called = false;
>>> +extern "C" void DlSymTestFunction()
>>> +{
>>> +    called = true;
>>> +}
>>>
>>>  BOOST_AUTO_TEST_CASE(test_dlopen_with_null_as_filename)
>>>  {
>>> @@ -53,3 +63,238 @@ BOOST_AUTO_TEST_CASE(test_dladdr)
>>>      BOOST_CHECK_EQUAL("vfprintf", info.dli_sname);
>>>      BOOST_CHECK_EQUAL(vfprintf, info.dli_saddr);
>>>  }
>>> +
>>> +BOOST_AUTO_TEST_CASE(test_dlsym_in_executable)
>>> +{
>>> +    dlerror();
>>> +    void* self = dlopen(NULL, RTLD_NOW);
>>> +    BOOST_REQUIRE_NE(self, nullptr);
>>> +    BOOST_REQUIRE_EQUAL(dlerror(), nullptr);
>>> +
>>> +    void* sym = dlsym(self, "DlSymTestFunction");
>>> +    BOOST_REQUIRE_NE(sym, nullptr);
>>> +
>>> +    void (*function)() = reinterpret_cast<void(*)()>(sym);
>>> +
>>> +    called = false;
>>> +    function();
>>> +    BOOST_REQUIRE_EQUAL(called, true);
>>> +    BOOST_CHECK_EQUAL(0, dlclose(self));
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(test_dlsym_from_sofile,
>>> +        *utf::enable_if<rtld_next>())
>>>
>>
>> What does this enable_if do?
>> Does it mean these tests don't run? They do run?
>> Again, this should have been explained somewhere - in comments, commit
>> message, or something.
>>
>> +{
>>> +    dlerror();
>>> +    void* handle = dlopen("/tests/libtest_dlsym_from_this.so",
>>> RTLD_LAZY | RTLD_LOCAL);
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE_NE(handle, nullptr);
>>> +
>>> +    // check that we can't find '_test_dlsym_symbol' via
>>> dlsym(RTLD_DEFAULT)
>>> +    void* symbol = dlsym(RTLD_DEFAULT, "test_dlsym_symbol");
>>> +    (void)symbol;
>>> +    // TODO: dlopen ignores all the flags; the current implementation
>>> assumes the flag to be RTLD_GLOBAL but the default should be RTLD_LOCAL
>>> +    //       Should reenable the test after flags are implemented
>>> +    // BOOST_REQUIRE_EQUAL(symbol, nullptr);
>>> +    // auto err_msg = std::string(dlerror());
>>> +    // BOOST_TEST_CONTEXT(err_msg)
>>> +    // BOOST_REQUIRE_NE(err_msg.find("dlsym: symbol test_dlsym_symbol
>>> not found"),
>>> +    //     std::string::npos);
>>> +    // BOOST_REQUIRE_NE(err_msg.find("undefined symbol:
>>> test_dlsym_symbol"),
>>> +    //         std::string::npos);
>>> +
>>> +    typedef int* (*fn_t)();
>>> +    fn_t lookup_dlsym_symbol_using_RTLD_DEFAULT =
>>> +        reinterpret_cast<fn_t>(dlsym(handle,
>>> "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE_NE(lookup_dlsym_symbol_using_RTLD_DEFAULT, nullptr);
>>> +
>>> +    int* ptr = lookup_dlsym_symbol_using_RTLD_DEFAULT();
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE_NE(ptr, nullptr);
>>> +    BOOST_REQUIRE_EQUAL(42, *ptr);
>>> +
>>> +    fn_t lookup_dlsym_symbol2_using_RTLD_DEFAULT =
>>> +        reinterpret_cast<fn_t>(dlsym(handle,
>>> "lookup_dlsym_symbol2_using_RTLD_DEFAULT"));
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(lookup_dlsym_symbol2_using_RTLD_DEFAULT != nullptr);
>>> +
>>> +    ptr = lookup_dlsym_symbol2_using_RTLD_DEFAULT();
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(ptr != nullptr);
>>> +    BOOST_REQUIRE_EQUAL(44, *ptr);
>>> +
>>> +    fn_t lookup_dlsym_symbol_using_RTLD_NEXT =
>>> +        reinterpret_cast<fn_t>(dlsym(handle,
>>> "lookup_dlsym_symbol_using_RTLD_NEXT"));
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(lookup_dlsym_symbol_using_RTLD_NEXT != nullptr);
>>> +
>>> +    ptr = lookup_dlsym_symbol_using_RTLD_NEXT();
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(ptr != nullptr);
>>> +    BOOST_REQUIRE_EQUAL(43, *ptr);
>>> +
>>> +    dlclose(handle);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(test_dlsym_from_sofile_with_preload,
>>> +        *utf::enable_if<deep_lookup>())
>>> +{
>>> +    void* preload =
>>> dlopen("/tests/libtest_dlsym_from_this_grandchild.so", RTLD_NOW |
>>> RTLD_LOCAL);
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(preload != nullptr);
>>> +
>>> +    void* handle = dlopen("/tests/libtest_dlsym_from_this.so", RTLD_NOW
>>> | RTLD_LOCAL);
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(handle != nullptr);
>>> +
>>> +    // check that we can't find '_test_dlsym_symbol' via
>>> dlsym(RTLD_DEFAULT)
>>> +    void* symbol = dlsym(RTLD_DEFAULT, "test_dlsym_symbol");
>>> +    (void)symbol;
>>> +    // TODO: dlopen ignores all the flags; the current implementation
>>> assumes the flag to be RTLD_GLOBAL but the default should be RTLD_LOCAL
>>> +    //       Should reenable the test after flags are implemented
>>> +    // BOOST_REQUIRE_EQUAL(symbol, nullptr);
>>> +    // auto err_msg = std::string(dlerror());
>>> +    // BOOST_TEST_CONTEXT(err_msg)
>>> +    // BOOST_REQUIRE_NE(err_msg.find("dlsym: symbol test_dlsym_symbol
>>> not found"),
>>> +    //      std::string::npos);
>>> +    // BOOST_REQUIRE_NE(err_msg.find("undefined symbol:
>>> test_dlsym_symbol"),
>>> +    //         std::string::npos);
>>> +
>>> +    typedef int* (*fn_t)();
>>> +    fn_t lookup_dlsym_symbol_using_RTLD_DEFAULT =
>>> +        reinterpret_cast<fn_t>(dlsym(handle,
>>> "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(lookup_dlsym_symbol_using_RTLD_DEFAULT != nullptr);
>>> +
>>> +    int* ptr = lookup_dlsym_symbol_using_RTLD_DEFAULT();
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(ptr != nullptr);
>>> +    BOOST_REQUIRE_EQUAL(42, *ptr);
>>> +
>>> +    fn_t lookup_dlsym_symbol2_using_RTLD_DEFAULT =
>>> +        reinterpret_cast<fn_t>(dlsym(handle,
>>> "lookup_dlsym_symbol2_using_RTLD_DEFAULT"));
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(lookup_dlsym_symbol2_using_RTLD_DEFAULT != nullptr);
>>> +
>>> +    ptr = lookup_dlsym_symbol2_using_RTLD_DEFAULT();
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE_NE(ptr, nullptr);
>>> +    BOOST_REQUIRE_EQUAL(44, *ptr);
>>> +
>>> +    fn_t lookup_dlsym_symbol_using_RTLD_NEXT =
>>> +        reinterpret_cast<fn_t>(dlsym(handle,
>>> "lookup_dlsym_symbol_using_RTLD_NEXT"));
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(lookup_dlsym_symbol_using_RTLD_NEXT != nullptr);
>>> +
>>> +    ptr = lookup_dlsym_symbol_using_RTLD_NEXT();
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(ptr != nullptr);
>>> +    BOOST_REQUIRE_EQUAL(43, *ptr);
>>> +
>>> +    dlclose(handle);
>>> +    dlclose(preload);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(dlsym_handle_global_sym)
>>> +{
>>> +    // check that we do not look into global group
>>> +    // when looking up symbol by handle
>>> +    void* handle = dlopen("/tests/libtest_empty.so", RTLD_NOW);
>>> +    dlopen("libtest_with_dependency.so", RTLD_NOW | RTLD_GLOBAL);
>>> +    void* sym = dlsym(handle, "getRandomNumber");
>>> +    BOOST_REQUIRE(sym == nullptr);
>>> +    auto err_msg = std::string(dlerror());
>>> +    BOOST_TEST_CONTEXT(err_msg)
>>> +    BOOST_REQUIRE_NE(err_msg.find("dlsym: symbol getRandomNumber not
>>> found"),
>>> +            std::string::npos);
>>> +    // BOOST_REQUIRE_NE(err_msg.find("undefined symbol:
>>> getRandomNumber"),
>>> +    //         std::string::npos);
>>> +
>>> +    sym = dlsym(handle, "DlSymTestFunction");
>>> +    BOOST_REQUIRE(sym == nullptr);
>>> +    err_msg = std::string(dlerror());
>>> +    BOOST_TEST_CONTEXT(err_msg)
>>> +    BOOST_REQUIRE_NE(err_msg.find("dlsym: symbol DlSymTestFunction not
>>> found"),
>>> +            std::string::npos);
>>> +    // BOOST_REQUIRE_NE(err_msg.find("undefined symbol:
>>> DlSymTestFunction"),
>>> +    //         std::string::npos);
>>> +    dlclose(handle);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(dlsym_handle_empty_symbol)
>>> +{
>>> +    // check that dlsym of an empty symbol fails (see http://b/33530622
>>> )
>>>
>>
>> I don't know what you tried to link here, but obviously the link is wrong
>> :-(
>>
>>
>>> +    void* handle = dlopen("/tests/libtest_dlsym_from_this.so",
>>> RTLD_NOW);
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(handle != nullptr);
>>> +    void* sym = dlsym(handle, "");
>>> +    BOOST_REQUIRE(sym == nullptr);
>>> +    auto err_msg = std::string(dlerror());
>>> +    BOOST_TEST_CONTEXT(err_msg)
>>> +    BOOST_REQUIRE_NE(err_msg.find("dlsym: symbol  not found"),
>>> +            std::string::npos);
>>> +    // BOOST_REQUIRE_NE(err_msg.find("undefined symbol: "),
>>> +    //         std::string::npos);
>>> +    dlclose(handle);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(dlsym_with_dependencies,
>>> +        *utf::enable_if<deep_lookup>())
>>> +{
>>> +    void* handle = dlopen("/tests/libtest_with_dependency.so",
>>> RTLD_NOW);
>>> +    BOOST_REQUIRE(handle != nullptr);
>>> +    dlerror();
>>> +    // This symbol is in DT_NEEDED library.
>>> +    void* sym = dlsym(handle, "getRandomNumber");
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE_NE(sym, nullptr);
>>> +    int (*fn)(void);
>>> +    fn = reinterpret_cast<int (*)(void)>(sym);
>>> +    BOOST_CHECK_EQUAL(4, fn());
>>> +    dlclose(handle);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(rtld_default_unknown_symbol)
>>> +{
>>> +    void* addr = dlsym(RTLD_DEFAULT, "UNKNOWN");
>>> +    BOOST_REQUIRE_EQUAL(addr, nullptr);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(rtld_default_fclose)
>>> +{
>>> +    void* addr = dlsym(RTLD_DEFAULT, "fclose");
>>> +    BOOST_REQUIRE_NE(addr, nullptr);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(rtld_next_unknown_symbol,
>>> +        *utf::enable_if<rtld_next>())
>>> +{
>>> +    void* addr = dlsym(RTLD_NEXT, "UNKNOWN");
>>> +    BOOST_REQUIRE_EQUAL(addr, nullptr);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(rtld_next_fclose,
>>> +        *utf::enable_if<rtld_next>())
>>> +{
>>> +    void* addr = dlsym(RTLD_NEXT, "fclose");
>>> +    BOOST_REQUIRE_NE(addr, nullptr);
>>> +}
>>> +
>>> +BOOST_AUTO_TEST_CASE(rtld_next_from_lib, *utf::enable_if<rtld_next>())
>>> +{
>>> +    void* library_with_fclose =
>>> dlopen("/tests/libtest_check_rtld_next_from_library.so", RTLD_NOW |
>>> RTLD_GLOBAL);
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(library_with_fclose != nullptr);
>>> +    void* expected_addr = dlsym(RTLD_DEFAULT, "fclose");
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(expected_addr != nullptr);
>>> +    typedef void* (*get_libc_fclose_ptr_fn_t)();
>>> +    get_libc_fclose_ptr_fn_t get_libc_fclose_ptr =
>>> +
>>> reinterpret_cast<get_libc_fclose_ptr_fn_t>(dlsym(library_with_fclose,
>>> "get_libc_fclose_ptr"));
>>> +    BOOST_TEST_CONTEXT(dlerror())
>>> +    BOOST_REQUIRE(get_libc_fclose_ptr != nullptr);
>>> +    BOOST_REQUIRE_EQUAL(expected_addr, get_libc_fclose_ptr());
>>> +
>>> +    dlclose(library_with_fclose);
>>> +}
>>> --
>>> 2.17.1
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "OSv Development" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to osv-dev+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/osv-dev/20200110071641.110196-1-zhitingz%40cs.utexas.edu
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "OSv Development" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to osv-dev+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/osv-dev/CANEVyjss8DhaxNzOryuLyAYR%3DkA3kdFCb1nU30y9f-hQQLkp0A%40mail.gmail.com
>> <https://groups.google.com/d/msgid/osv-dev/CANEVyjss8DhaxNzOryuLyAYR%3DkA3kdFCb1nU30y9f-hQQLkp0A%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/CANEVyjt%3Dd69gM5hKVhfkkFfeGf%2BOw-0nhTFpdQ0BRy448%3DyHtA%40mail.gmail.com.

Reply via email to