Fixed error when dynamically compiled .so file is broken [#METR-25550].

This commit is contained in:
Alexey Milovidov 2017-06-21 20:31:22 +03:00
parent 8c9aa37318
commit 4738094d7e
3 changed files with 37 additions and 8 deletions

View File

@ -377,6 +377,7 @@ namespace ErrorCodes
extern const int SESSION_NOT_FOUND = 372;
extern const int SESSION_IS_LOCKED = 373;
extern const int INVALID_SESSION_TIMEOUT = 374;
extern const int CANNOT_DLOPEN = 375;
extern const int KEEPER_EXCEPTION = 999;
extern const int POCO_EXCEPTION = 1000;

View File

@ -92,25 +92,47 @@ SharedLibraryPtr Compiler::getOrCount(
UInt32 count = ++counts[hashed_key];
/// Is there a ready open library? Or, if the library is in the process of compiling, there will be nullptr.
Libraries::iterator it = libraries.find(hashed_key);
if (libraries.end() != it)
Libraries::iterator libraries_it = libraries.find(hashed_key);
if (libraries.end() != libraries_it)
{
if (!it->second)
if (!libraries_it->second)
LOG_INFO(log, "Library " << hashedKeyToFileName(hashed_key) << " is already compiling or compilation was failed.");
/// TODO In this case, after the compilation is finished, the callback will not be called.
return it->second;
return libraries_it->second;
}
/// Is there a file with the library left over from the previous launch?
std::string file_name = hashedKeyToFileName(hashed_key);
if (files.count(file_name))
Files::iterator files_it = files.find(file_name);
if (files.end() != files_it)
{
std::string so_file_path = path + '/' + file_name + ".so";
LOG_INFO(log, "Loading existing library " << so_file_path);
SharedLibraryPtr lib(new SharedLibrary(so_file_path));
SharedLibraryPtr lib;
try
{
lib = std::make_shared<SharedLibrary>(so_file_path);
}
catch (const Exception & e)
{
if (e.code() != ErrorCodes::CANNOT_DLOPEN)
throw;
/// Found broken .so file (or file cannot be dlopened by whatever reason).
/// This could happen when filesystem is corrupted after server restart.
/// We remove the file - it will be recompiled on next attempt.
tryLogCurrentException(log);
files.erase(files_it);
Poco::File(so_file_path).remove();
return nullptr;
}
libraries[hashed_key] = lib;
return lib;
}

View File

@ -19,6 +19,12 @@
namespace DB
{
namespace ErrorCodes
{
extern const int CANNOT_DLOPEN;
extern const int CANNOT_DLSYM;
}
/** Allows you to open a dynamic library and get a pointer to a function from it.
*/
@ -29,7 +35,7 @@ public:
{
handle = dlopen(path.c_str(), RTLD_LAZY);
if (!handle)
throw Exception(std::string("Cannot dlopen: ") + dlerror());
throw Exception(std::string("Cannot dlopen: ") + dlerror(), ErrorCodes::CANNOT_DLOPEN);
}
~SharedLibrary()
@ -46,7 +52,7 @@ public:
Func res = reinterpret_cast<Func>(dlsym(handle, name.c_str()));
if (char * error = dlerror())
throw Exception(std::string("Cannot dlsym: ") + error);
throw Exception(std::string("Cannot dlsym: ") + error, ErrorCodes::CANNOT_DLSYM);
return res;
}