aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt4
-rw-r--r--src/common/compat/glibc_compat.cpp98
-rw-r--r--src/common/perf_timer.cpp46
-rw-r--r--src/common/perf_timer.h6
-rw-r--r--src/common/spawn.cpp4
-rw-r--r--src/common/util.cpp32
6 files changed, 177 insertions, 13 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 5da23c944..3b1eb6d23 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -50,6 +50,10 @@ if (STACK_TRACE)
list(APPEND common_sources stack_trace.cpp)
endif()
+if (BACKCOMPAT)
+ list(APPEND common_sources compat/glibc_compat.cpp)
+endif()
+
set(common_headers)
set(common_private_headers
diff --git a/src/common/compat/glibc_compat.cpp b/src/common/compat/glibc_compat.cpp
new file mode 100644
index 000000000..bf567987d
--- /dev/null
+++ b/src/common/compat/glibc_compat.cpp
@@ -0,0 +1,98 @@
+#include <cstddef>
+#include <cstdint>
+#include <strings.h>
+#include <string.h>
+#include <glob.h>
+#include <unistd.h>
+#include <fnmatch.h>
+
+#if defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+
+// Prior to GLIBC_2.14, memcpy was aliased to memmove.
+extern "C" void* memmove(void* a, const void* b, size_t c);
+//extern "C" void* memset(void* a, int b, long unsigned int c);
+extern "C" void* memcpy(void* a, const void* b, size_t c)
+{
+ return memmove(a, b, c);
+}
+
+extern "C" void __chk_fail(void) __attribute__((__noreturn__));
+
+#if defined(__i386__) || defined(__arm__)
+
+extern "C" int64_t __udivmoddi4(uint64_t u, uint64_t v, uint64_t* rp);
+
+extern "C" int64_t __wrap___divmoddi4(int64_t u, int64_t v, int64_t* rp)
+{
+ int32_t c1 = 0, c2 = 0;
+ int64_t uu = u, vv = v;
+ int64_t w;
+ int64_t r;
+
+ if (uu < 0) {
+ c1 = ~c1, c2 = ~c2, uu = -uu;
+ }
+ if (vv < 0) {
+ c1 = ~c1, vv = -vv;
+ }
+
+ w = __udivmoddi4(uu, vv, (uint64_t*)&r);
+ if (c1)
+ w = -w;
+ if (c2)
+ r = -r;
+
+ *rp = r;
+ return w;
+}
+#endif
+
+/* glibc-internal users use __explicit_bzero_chk, and explicit_bzero
+ redirects to that. */
+#undef explicit_bzero
+/* Set LEN bytes of S to 0. The compiler will not delete a call to
+ this function, even if S is dead after the call. */
+void
+explicit_bzero (void *s, size_t len)
+{
+ memset (s, '\0', len);
+ /* Compiler barrier. */
+ asm volatile ("" ::: "memory");
+}
+
+// Redefine explicit_bzero_chk
+void
+__explicit_bzero_chk (void *dst, size_t len, size_t dstlen)
+{
+ /* Inline __memset_chk to avoid a PLT reference to __memset_chk. */
+ if (__glibc_unlikely (dstlen < len))
+ __chk_fail ();
+ memset (dst, '\0', len);
+ /* Compiler barrier. */
+ asm volatile ("" ::: "memory");
+}
+/* libc-internal references use the hidden
+ __explicit_bzero_chk_internal symbol. This is necessary if
+ __explicit_bzero_chk is implemented as an IFUNC because some
+ targets do not support hidden references to IFUNC symbols. */
+#define strong_alias (__explicit_bzero_chk, __explicit_bzero_chk_internal)
+
+#undef glob
+extern "C" int glob_old(const char * pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob);
+#ifdef __i386__
+__asm__(".symver glob_old,glob@GLIBC_2.1");
+#elif defined(__amd64__)
+__asm__(".symver glob_old,glob@GLIBC_2.2.5");
+#elif defined(__arm__)
+__asm(".symver glob_old,glob@GLIBC_2.4");
+#elif defined(__aarch64__)
+__asm__(".symver glob_old,glob@GLIBC_2.17");
+#endif
+
+extern "C" int __wrap_glob(const char * pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob)
+{
+ return glob_old(pattern, flags, errfunc, pglob);
+}
+
diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp
index d9f1f65c1..3e1357833 100644
--- a/src/common/perf_timer.cpp
+++ b/src/common/perf_timer.cpp
@@ -33,6 +33,13 @@
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "perf"
+#define PERF_LOG_ALWAYS(level, cat, x) \
+ el::base::Writer(level, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::FileOnlyLog).construct(cat) << x
+#define PERF_LOG(level, cat, x) \
+ do { \
+ if (ELPP->vRegistry()->allowed(level, cat)) PERF_LOG_ALWAYS(level, cat, x); \
+ } while(0)
+
namespace tools
{
uint64_t get_tick_count()
@@ -106,9 +113,11 @@ PerformanceTimer::PerformanceTimer(bool paused): started(true), paused(paused)
LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l): PerformanceTimer(), name(s), cat(cat), unit(unit), level(l)
{
+ const bool log = ELPP->vRegistry()->allowed(level, cat.c_str());
if (!performance_timers)
{
- MCLOG(level, cat.c_str(), "PERF ----------");
+ if (log)
+ PERF_LOG_ALWAYS(level, cat.c_str(), "PERF ----------");
performance_timers = new std::vector<LoggingPerformanceTimer*>();
performance_timers->reserve(16); // how deep before realloc
}
@@ -117,8 +126,11 @@ LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, const std
LoggingPerformanceTimer *pt = performance_timers->back();
if (!pt->started && !pt->paused)
{
- size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size;
- MCLOG(pt->level, cat.c_str(), "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name);
+ if (log)
+ {
+ size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size;
+ PERF_LOG_ALWAYS(pt->level, cat.c_str(), "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name);
+ }
pt->started = true;
}
}
@@ -135,10 +147,14 @@ LoggingPerformanceTimer::~LoggingPerformanceTimer()
{
pause();
performance_timers->pop_back();
- char s[12];
- snprintf(s, sizeof(s), "%8llu ", (unsigned long long)(ticks_to_ns(ticks) / (1000000000 / unit)));
- size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused || tmp==this) ++size;
- MCLOG(level, cat.c_str(), "PERF " << s << std::string(size * 2, ' ') << " " << name);
+ const bool log = ELPP->vRegistry()->allowed(level, cat.c_str());
+ if (log)
+ {
+ char s[12];
+ snprintf(s, sizeof(s), "%8llu ", (unsigned long long)(ticks_to_ns(ticks) / (1000000000 / unit)));
+ size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused || tmp==this) ++size;
+ PERF_LOG_ALWAYS(level, cat.c_str(), "PERF " << s << std::string(size * 2, ' ') << " " << name);
+ }
if (performance_timers->empty())
{
delete performance_timers;
@@ -162,4 +178,20 @@ void PerformanceTimer::resume()
paused = false;
}
+void PerformanceTimer::reset()
+{
+ if (paused)
+ ticks = 0;
+ else
+ ticks = get_tick_count();
+}
+
+uint64_t PerformanceTimer::value() const
+{
+ uint64_t v = ticks;
+ if (!paused)
+ v = get_tick_count() - v;
+ return ticks_to_ns(v);
+}
+
}
diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h
index 584434a0d..d859cf576 100644
--- a/src/common/perf_timer.h
+++ b/src/common/perf_timer.h
@@ -51,8 +51,8 @@ public:
~PerformanceTimer();
void pause();
void resume();
-
- uint64_t value() const { return ticks; }
+ void reset();
+ uint64_t value() const;
protected:
uint64_t ticks;
@@ -63,7 +63,7 @@ protected:
class LoggingPerformanceTimer: public PerformanceTimer
{
public:
- LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l = el::Level::Debug);
+ LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l = el::Level::Info);
~LoggingPerformanceTimer();
private:
diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp
index 0a2ce8387..b2d03f62f 100644
--- a/src/common/spawn.cpp
+++ b/src/common/spawn.cpp
@@ -35,6 +35,7 @@
#include <windows.h>
#else
#include <sys/wait.h>
+#include <signal.h>
#endif
#include "misc_log_ex.h"
@@ -114,7 +115,10 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
if (pid > 0)
{
if (!wait)
+ {
+ signal(SIGCHLD, SIG_IGN);
return 0;
+ }
while (1)
{
diff --git a/src/common/util.cpp b/src/common/util.cpp
index 448f792ff..28745eea4 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -82,6 +82,32 @@ using namespace epee;
#include <boost/asio.hpp>
#include <openssl/sha.h>
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "util"
+
+namespace
+{
+
+#ifndef _WIN32
+static int flock_exnb(int fd)
+{
+ struct flock fl;
+ int ret;
+
+ memset(&fl, 0, sizeof(fl));
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ ret = fcntl(fd, F_SETLK, &fl);
+ if (ret < 0)
+ MERROR("Error locking fd " << fd << ": " << errno << " (" << strerror(errno) << ")");
+ return ret;
+}
+#endif
+
+}
+
namespace tools
{
std::function<void(int)> signal_handler::m_handler;
@@ -182,7 +208,7 @@ namespace tools
struct stat wstats = {};
if (fstat(fdw, std::addressof(wstats)) == 0 &&
rstats.st_dev == wstats.st_dev && rstats.st_ino == wstats.st_ino &&
- flock(fdw, (LOCK_EX | LOCK_NB)) == 0 && ftruncate(fdw, 0) == 0)
+ flock_exnb(fdw) == 0 && ftruncate(fdw, 0) == 0)
{
std::FILE* file = fdopen(fdw, "w");
if (file) return {file, std::move(name)};
@@ -235,10 +261,10 @@ namespace tools
MERROR("Failed to open " << filename << ": " << std::error_code(GetLastError(), std::system_category()));
}
#else
- m_fd = open(filename.c_str(), O_RDONLY | O_CREAT | O_CLOEXEC, 0666);
+ m_fd = open(filename.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0666);
if (m_fd != -1)
{
- if (flock(m_fd, LOCK_EX | LOCK_NB) == -1)
+ if (flock_exnb(m_fd) == -1)
{
MERROR("Failed to lock " << filename << ": " << std::strerror(errno));
close(m_fd);