-
Notifications
You must be signed in to change notification settings - Fork 256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
System error code handling and utiltity function cleanup #238
Conversation
Codecov Report
@@ Coverage Diff @@
## development #238 +/- ##
===============================================
+ Coverage 77.58% 82.73% +5.15%
===============================================
Files 117 188 +71
Lines 8011 13298 +5287
===============================================
+ Hits 6215 11002 +4787
- Misses 1796 2296 +500
|
cmake/usCTestScript_travis.cmake
Outdated
set(CTEST_BUILD_FLAGS "-j") | ||
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") | ||
# gcc in combination with gcov seems to consume a lot of memory | ||
# and my lead to OOM error on Travis containers. Hence we compile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: "my" -> "may"
bundleRegistry.Install(execPath, systemBundle.get()); | ||
} | ||
} | ||
catch (const std::exception& e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the behavior to users will change since exceptions are now suppressed from failing to install embedded bundles. is this the right thing to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. That was not intended.
extern const char DIR_SEP; | ||
|
||
// Get the path of the calling executable. | ||
// Throws std::runtime_error is the path cannot be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: "is" -> "if"
|
||
#else | ||
#ifndef WIN32_LEAN_AND_MEAN | ||
#define WIN32_LEAN_AND_MEAN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this #ifndef/#define WIN32_LEAN_AND_MEAN is in multiple places. it would be good to put it in a central location. perhaps in GlobalConfig.h?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need #126 resolved and have an internal global .h
file (which is not included in public .h
files) where we can place such defines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that sounds good to me.
util/src/Error.cpp
Outdated
|
||
std::string GetLastWin32ErrorStr() | ||
{ | ||
#ifdef US_PLATFORM_WINDOWS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this function is only intended to be called on Windows, I think it should only be visible to the compiler when building on Windows. perhaps move the #ifdef outside of the function body?
This has an added benefit of failing at compile time if this function is called from non-Windows code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will look at that.
util/src/Error.cpp
Outdated
// This is the XSI strerror_r version | ||
if (strerror_r(errno, errorString, sizeof errorString)) | ||
{ | ||
return "Unknown error"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strerror_r will return a error number indicating why it failed. It would be useful to return the error instead of "unknown".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could return errno
as a number in the returned string (by saving it before calling strerror_r
). I think returning the error code from a failing strerror_r
call would be misleading, because it will mask the original error for which we wanted to retrieve the textual description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant returning a string indicating why strerror_r failed.
According to the documentation for strerror_r it only returns a failure if errno is invalid or the string buffer isn't big enough.
util/src/Error.cpp
Outdated
} | ||
|
||
US_MSVC_PUSH_DISABLE_WARNING(4715) // 'function' : not all control paths return a value | ||
std::string GetExceptionStr(const std::exception_ptr& exc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The warning push pop can be removed with the following block.
std::string GetExceptionStr(const std::exception_ptr& exc)
{
std::string exceptionStr;
try
{
if(exc)
{
std::rethrow_exception(exc);
}
}
catch (const std::exception& e)
{
exceptionStr = e.what();
}
catch (...)
{
exceptionStr= "unknown";
}
return exceptionStr;
}
return std::string(); | ||
} | ||
|
||
static const std::string s_CurrWorkingDir = InitCurrentWorkingDirectory(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not make this magic static inside the function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code was just moved from a different file and not changed. We had a discussion about the actual code in the original PR. Basically, we need to call InitCurrentWorkingDirectory
at a time when there is only the main thread running (during static init).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karthikreddy09 take a look at PR #216 for more information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ... now I understand. Thanks for pointing to the previous discussion.
} | ||
catch (const std::exception& e) | ||
{ | ||
DIAG_LOG(*sink) << e.what(); | ||
// Let the exeception propagate all the way up to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: "exeception"
} | ||
|
||
// A cross-platform version of the POSIX mkdtemp function | ||
char* mkdtemps_compat(char *tmpl, int suffixlen) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like there's a lot of common code between mkdtemps_compat and mkstemps_compat that can be factored out to remove the duplication?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly for the same reason as above. Laziness, working on bugs or features, afraid of introducing regressions, ...
|
||
static const char validLetters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | ||
|
||
// A cross-platform version of the mkstemps function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sascha, curious about why we need to be compatible with mkstemp (or mkdtemp), AFAIU, these are only called by our tests and if we drop the compatibility criterion, we could avoid passing "char *" and avoid using strlen() etc.
i.e. I think it's better to operate on std::string's instead of (less safe) C-style strings, use std::string methods and throw an exception from this function itself in-case of any error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The answer is a historical one. The code originates from the public domain on the Internet. As such it was C code, written to be compatible with mkstemp and friends by the original author. I only did very small changes initially (many years ago) and used the code as is in another project. It did its job well enough and I thought I would spend my time elsewhere instead of making it prettier for CppMicroServices.
Feel free to send a PR for C++ification or other improvements, but I think there is not much gain unless there is a bug of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Sounds good.
|
||
static const char validLetters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | ||
|
||
// A cross-platform version of the mkstemps function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Sounds good.
e6caf9b
to
4fb25d9
Compare
This PR addresses issues #191 and #220 and also contains further cleanup.
The first commit contains the actual fixes:
errno
to 0 before calling C runtime library functionsstrerrror
variants if availableIt also improves code sharing between the legacy and the new GTest test executable:
TestUtils.cpp
for re-use in legacy and GTest testsTestUtils.cpp
changes:mkdtemp
andmkstemp
functions for creating unique files and directories (originated from public domain and contributed by me with slight changes to another project a couple of years ago; now just copied here)The commit also adds unit tests for our internal filesystem related functions:
cppmicroservices::fs
functions. The tests are compiled for static builds only to avoid exporting internal functions.TestUtils.cpp
.For the above changes, I had to duplicate a little more code from the internal file-system code. Seeing that we then had almost the same content duplicated in the framework and the unit test code I wanted to get rid of that and make it reusable.
This is what the second commit contains:
Please note that virtually no new code was written, except for disentangling our C / Win32 error handling, using
strerror_r
etc. where appropriate, and writing new unit tests (GTest based).