mirror of https://github.com/status-im/evmc.git
loader: Expose DLL load errors with evmc_last_error_msg()
Currently only works for errors by dlopen() on Linux and macos, otherwise returns NULL.
This commit is contained in:
parent
4408da2758
commit
14c5356ae6
|
@ -158,7 +158,13 @@ func Load(filename string) (instance *Instance, err error) {
|
|||
case C.EVMC_LOADER_SUCCESS:
|
||||
instance = &Instance{handle}
|
||||
case C.EVMC_LOADER_CANNOT_OPEN:
|
||||
err = fmt.Errorf("evmc loader: cannot open %s", filename)
|
||||
optionalErrMsg := C.evmc_last_error_msg()
|
||||
if optionalErrMsg != nil {
|
||||
msg := C.GoString(optionalErrMsg)
|
||||
err = fmt.Errorf("evmc loader: %s", msg)
|
||||
} else {
|
||||
err = fmt.Errorf("evmc loader: cannot open %s", filename)
|
||||
}
|
||||
case C.EVMC_LOADER_SYMBOL_NOT_FOUND:
|
||||
err = fmt.Errorf("evmc loader: the EVMC create function not found in %s", filename)
|
||||
case C.EVMC_LOADER_INVALID_ARGUMENT:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* EVMC: Ethereum Client-VM Connector API.
|
||||
* Copyright 2018 The EVMC Authors.
|
||||
* Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||
* Copyright 2019 The EVMC Authors.
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -103,6 +103,19 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
|
|||
struct evmc_instance* evmc_load_and_create(const char* filename,
|
||||
enum evmc_loader_error_code* error_code);
|
||||
|
||||
/**
|
||||
* Returns the human-readable message describing the most recent error
|
||||
* that occurred in EVMC loading.
|
||||
*
|
||||
* In case any loading function returned ::EVMC_LOADER_SUCCESS this function always returns NULL.
|
||||
* In case of error code other than success returned, this function MAY return the error message.
|
||||
* This function is not thread-safe.
|
||||
*
|
||||
* @return Error message or NULL if no additional information is available.
|
||||
* The returned pointer MUST NOT be freed by the caller.
|
||||
*/
|
||||
const char* evmc_last_error_msg();
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -44,9 +44,12 @@ static void strcpy_s(char* dest, size_t destsz, const char* src)
|
|||
}
|
||||
#endif
|
||||
|
||||
static const char* last_error_msg = NULL;
|
||||
|
||||
|
||||
evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code)
|
||||
{
|
||||
last_error_msg = NULL; // Reset last error.
|
||||
enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;
|
||||
evmc_create_fn create_fn = NULL;
|
||||
|
||||
|
@ -66,6 +69,11 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
|
|||
DLL_HANDLE handle = DLL_OPEN(filename);
|
||||
if (!handle)
|
||||
{
|
||||
#if !defined(EVMC_LOADER_MOCK) && !_WIN32
|
||||
// If available, get the error message from dlerror().
|
||||
last_error_msg = dlerror();
|
||||
#endif
|
||||
|
||||
ec = EVMC_LOADER_CANNOT_OPEN;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -130,9 +138,15 @@ exit:
|
|||
return create_fn;
|
||||
}
|
||||
|
||||
const char* evmc_last_error_msg()
|
||||
{
|
||||
return last_error_msg;
|
||||
}
|
||||
|
||||
struct evmc_instance* evmc_load_and_create(const char* filename,
|
||||
enum evmc_loader_error_code* error_code)
|
||||
{
|
||||
// First load the DLL. This also resets the last_error_msg;
|
||||
evmc_create_fn create_fn = evmc_load(filename, error_code);
|
||||
|
||||
if (!create_fn)
|
||||
|
|
|
@ -18,7 +18,7 @@ add_test(NAME vmtester/help COMMAND evmc-vmtester --version --help)
|
|||
set_tests_properties(vmtester/help PROPERTIES PASS_REGULAR_EXPRESSION "Usage:")
|
||||
|
||||
add_test(NAME vmtester/nonexistingvm COMMAND evmc-vmtester nonexistingvm)
|
||||
set_tests_properties(vmtester/nonexistingvm PROPERTIES PASS_REGULAR_EXPRESSION "Cannot open")
|
||||
set_tests_properties(vmtester/nonexistingvm PROPERTIES PASS_REGULAR_EXPRESSION "[Cc]annot open")
|
||||
|
||||
add_test(NAME vmtester/noarg COMMAND evmc-vmtester)
|
||||
set_tests_properties(vmtester/noarg PROPERTIES PASS_REGULAR_EXPRESSION "is required")
|
||||
|
|
|
@ -140,8 +140,14 @@ int main(int argc, char* argv[])
|
|||
case EVMC_LOADER_SUCCESS:
|
||||
break;
|
||||
case EVMC_LOADER_CANNOT_OPEN:
|
||||
std::cerr << "Cannot open " << evmc_module << "\n";
|
||||
{
|
||||
const auto error = evmc_last_error_msg();
|
||||
if (error)
|
||||
std::cerr << error << "\n";
|
||||
else
|
||||
std::cerr << "Cannot open " << evmc_module << "\n";
|
||||
return static_cast<int>(ec);
|
||||
}
|
||||
case EVMC_LOADER_SYMBOL_NOT_FOUND:
|
||||
std::cerr << "EVMC create function not found in " << evmc_module << "\n";
|
||||
return static_cast<int>(ec);
|
||||
|
|
Loading…
Reference in New Issue