Fix tsan error (#5414)

Summary:
Previous code has a warning when compile with tsan, leading to an error since we have -Werror.
Compilation result
```
In file included from ./env/env_chroot.h:12,
                 from env/env_test.cc:40:
./include/rocksdb/env.h: In instantiation of ‘rocksdb::Status rocksdb::DynamicLibrary::LoadFunction(const string&, std::function<T>*) [with T = void*(void*, const char*); std::__cxx11::string = std::__cxx11::basic_string<char>]’:
env/env_test.cc:260:5:   required from here
./include/rocksdb/env.h:1010:17: error: cast between incompatible function types from ‘rocksdb::DynamicLibrary::FunctionPtr’ {aka ‘void* (*)()’} to ‘void* (*)(void*, const char*)’ [-Werror=cast-function-type]
     *function = reinterpret_cast<T*>(ptr);
                 ^~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
make: *** [env/env_test.o] Error 1
```
It also has another error reported by clang
```
env/env_posix.cc:141:11: warning: Value stored to 'err' during its initialization is never read
    char* err = dlerror();  // Clear any old error
          ^~~   ~~~~~~~~~
1 warning generated.
```

Test plan (on my devserver).
```
$make clean
$OPT=-g ROCKSDB_FBCODE_BUILD_WITH_PLATFORM007=1 COMPILE_WITH_TSAN=1 make -j32
$
$make clean
$USE_CLANG=1 TEST_TMPDIR=/dev/shm/rocksdb OPT=-g make -j1 analyze
```
Both should pass.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/5414

Differential Revision: D15637315

Pulled By: riversand963

fbshipit-source-id: 8e307483761019a4d5998cab92d49516d7edffbf
main
Yanqin Jin 5 years ago committed by Facebook Github Bot
parent 267b9b1091
commit cb1bf09bfc
  1. 27
      env/env_posix.cc
  2. 16
      include/rocksdb/env.h

27
env/env_posix.cc vendored

@ -137,13 +137,14 @@ class PosixDynamicLibrary : public DynamicLibrary {
: name_(name), handle_(handle) {} : name_(name), handle_(handle) {}
~PosixDynamicLibrary() override { dlclose(handle_); } ~PosixDynamicLibrary() override { dlclose(handle_); }
Status LoadSymbol(const std::string& sym_name, FunctionPtr* func) override { Status LoadSymbol(const std::string& sym_name, void** func) override {
char* err = dlerror(); // Clear any old error assert(nullptr != func);
*func = (FunctionPtr)dlsym(handle_, sym_name.c_str()); dlerror(); // Clear any old error
*func = dlsym(handle_, sym_name.c_str());
if (*func != nullptr) { if (*func != nullptr) {
return Status::OK(); return Status::OK();
} else { } else {
err = dlerror(); char* err = dlerror();
return Status::NotFound("Error finding symbol: " + sym_name, err); return Status::NotFound("Error finding symbol: " + sym_name, err);
} }
} }
@ -771,16 +772,14 @@ class PosixEnv : public Env {
} }
#ifndef ROCKSDB_NO_DYNAMIC_EXTENSION #ifndef ROCKSDB_NO_DYNAMIC_EXTENSION
/** // Loads the named library into the result.
* Loads the named library into the result. // If the input name is empty, the current executable is loaded
* If the input name is empty, the current executable is loaded // On *nix systems, a "lib" prefix is added to the name if one is not supplied
* On *nix systems, a "lib" prefix is added to the name if one is not supplied // Comparably, the appropriate shared library extension is added to the name
* Comparably, the appropriate shared library extension is added to the name // if not supplied. If search_path is not specified, the shared library will
* if not supplied. If search_path is not specified, the shared library will // be loaded using the default path (LD_LIBRARY_PATH) If search_path is
* be loaded using the default path (LD_LIBRARY_PATH) If search_path is // specified, the shared library will be searched for in the directories
* specified, the shared library will be searched for in the directories // provided by the search path
* provided by the search path
*/
Status LoadLibrary(const std::string& name, const std::string& path, Status LoadLibrary(const std::string& name, const std::string& path,
std::shared_ptr<DynamicLibrary>* result) override { std::shared_ptr<DynamicLibrary>* result) override {
Status status; Status status;

@ -1029,25 +1029,23 @@ class FileLock {
class DynamicLibrary { class DynamicLibrary {
public: public:
typedef void* (*FunctionPtr)();
virtual ~DynamicLibrary() {} virtual ~DynamicLibrary() {}
/** Returns the name of the dynamic library */ // Returns the name of the dynamic library.
virtual const char* Name() const = 0; virtual const char* Name() const = 0;
/** // Loads the symbol for sym_name from the library and updates the input
* Loads the symbol for sym_name from the library and updates the input // function. Returns the loaded symbol.
* function. Returns the loaded symbol
*/
template <typename T> template <typename T>
Status LoadFunction(const std::string& sym_name, std::function<T>* function) { Status LoadFunction(const std::string& sym_name, std::function<T>* function) {
FunctionPtr ptr; assert(nullptr != function);
void* ptr = nullptr;
Status s = LoadSymbol(sym_name, &ptr); Status s = LoadSymbol(sym_name, &ptr);
*function = reinterpret_cast<T*>(ptr); *function = reinterpret_cast<T*>(ptr);
return s; return s;
} }
/** Loads and returns the symbol for sym_name from the library */ // Loads and returns the symbol for sym_name from the library.
virtual Status LoadSymbol(const std::string& sym_name, FunctionPtr* func) = 0; virtual Status LoadSymbol(const std::string& sym_name, void** func) = 0;
}; };
extern void LogFlush(const std::shared_ptr<Logger>& info_log); extern void LogFlush(const std::shared_ptr<Logger>& info_log);

Loading…
Cancel
Save