diff --git a/.github/workflows/macos-builds.yml b/.github/workflows/macos-builds.yml index 0821cb6..58321cc 100644 --- a/.github/workflows/macos-builds.yml +++ b/.github/workflows/macos-builds.yml @@ -24,15 +24,19 @@ jobs: - name: Configure shell: bash + env: + CXXFLAGS: -Wall -Wextra -Wsign-conversion -Werror run: | if [[ ${{matrix.std}} == 98 ]]; then - export CXXFLAGS=-Werror=c++11-extensions + export CXXFLAGS="-Werror=c++11-extensions ${CXXFLAGS}" fi cmake -S . -B ${{runner.workspace}}/build_${{matrix.name}}_${{matrix.build_type}} \ -G "${{matrix.generator}}" \ + -DCMAKE_CXX_EXTENSIONS=OFF \ + -DCMAKE_CXX_FLAGS_DEBUG=-pedantic-errors \ + -DCMAKE_CXX_FLAGS_RELEASE=-pedantic-errors \ -DCMAKE_CXX_STANDARD=${{matrix.std}} \ - -DCMAKE_CXX_STANDARD_REQUIRED=ON \ - -DCMAKE_CXX_EXTENSIONS=OFF + -DCMAKE_CXX_STANDARD_REQUIRED=ON - name: Build run: | cmake --build ${{runner.workspace}}/build_${{matrix.name}}_${{matrix.build_type}} \ diff --git a/.github/workflows/windows-builds.yml b/.github/workflows/windows-builds.yml index 77a1970..12628a8 100644 --- a/.github/workflows/windows-builds.yml +++ b/.github/workflows/windows-builds.yml @@ -101,6 +101,8 @@ jobs: - name: Configure build MinGW if: ${{ startswith(matrix.config.name, 'MinGW-') }} shell: powershell + env: + CXXFLAGS: -Wall -Wextra -Wpedantic -Wsign-conversion -Werror -Wno-error=variadic-macros -Wno-error=long-long run: cmake -S . -B ${{runner.workspace}}/build_${{matrix.config.name}}_${{matrix.build_type}} -G "${{matrix.config.generator}}" -DCMAKE_CXX_STANDARD=${{matrix.config.std}} -DCMAKE_CXX_EXTENSIONS=OFF -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_BUILD_TYPE=${{matrix.build_type}} - name: Build MinGW if: ${{ startswith(matrix.config.name, 'MinGW-') }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 387a685..8c79176 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,7 +128,7 @@ check_function_exists (fcntl HAVE_FCNTL) check_function_exists (pread HAVE_PREAD) check_function_exists (pwrite HAVE_PWRITE) check_function_exists (sigaction HAVE_SIGACTION) -check_function_exists (sigaltstack HAVE_SIGALSTACK) +check_function_exists (sigaltstack HAVE_SIGALTSTACK) # NOTE gcc does not fail if you pass a non-existent -Wno-* option as an # argument. However, it will happily fail if you pass the corresponding -W* diff --git a/src/demangle.cc b/src/demangle.cc index f3e6ad7..0010c1c 100644 --- a/src/demangle.cc +++ b/src/demangle.cc @@ -35,12 +35,12 @@ // Note that we only have partial C++0x support yet. #include // for NULL -#include "utilities.h" + #include "demangle.h" +#include "utilities.h" #if defined(OS_WINDOWS) #include -#pragma comment(lib, "dbghelp") #endif _START_GOOGLE_NAMESPACE_ @@ -192,7 +192,7 @@ static bool StrPrefix(const char *str, const char *prefix) { } static void InitState(State *state, const char *mangled, - char *out, int out_size) { + char *out, size_t out_size) { state->mangled_cur = mangled; state->out_cur = out; state->out_begin = out; @@ -1323,7 +1323,7 @@ static bool ParseTopLevelMangledName(State *state) { #endif // The demangler entry point. -bool Demangle(const char *mangled, char *out, int out_size) { +bool Demangle(const char *mangled, char *out, size_t out_size) { #if defined(OS_WINDOWS) // When built with incremental linking, the Windows debugger // library provides a more complicated `Symbol->Name` with the @@ -1339,7 +1339,7 @@ bool Demangle(const char *mangled, char *out, int out_size) { if (lparen) { // Extract the string `(?...)` const char *rparen = strchr(lparen, ')'); - size_t length = rparen - lparen - 1; + size_t length = static_cast(rparen - lparen) - 1; strncpy(buffer, lparen + 1, length); buffer[length] = '\0'; mangled = buffer; diff --git a/src/demangle.h b/src/demangle.h index 991b6ff..a667db4 100644 --- a/src/demangle.h +++ b/src/demangle.h @@ -78,7 +78,7 @@ _START_GOOGLE_NAMESPACE_ // Demangle "mangled". On success, return true and write the // demangled symbol name to "out". Otherwise, return false. // "out" is modified even if demangling is unsuccessful. -bool GOOGLE_GLOG_DLL_DECL Demangle(const char *mangled, char *out, int out_size); +bool GOOGLE_GLOG_DLL_DECL Demangle(const char *mangled, char *out, size_t out_size); _END_GOOGLE_NAMESPACE_ diff --git a/src/glog/logging.h.in b/src/glog/logging.h.in index 15186de..cb19032 100644 --- a/src/glog/logging.h.in +++ b/src/glog/logging.h.in @@ -33,8 +33,8 @@ // Pretty much everybody needs to #include this file so that they can // log various happenings. // -#ifndef _LOGGING_H_ -#define _LOGGING_H_ +#ifndef GLOG_LOGGING_H +#define GLOG_LOGGING_H #if @ac_cv_cxx11_chrono@ && __cplusplus >= 201103L #include @@ -605,8 +605,14 @@ GOOGLE_GLOG_DLL_DECL bool IsGoogleLoggingInitialized(); // Shutdown google's logging library. GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging(); +#if defined(__GNUC__) +typedef void (*logging_fail_func_t)() __attribute__((noreturn)); +#else +typedef void (*logging_fail_func_t)(); +#endif + // Install a function which will be called after LOG(FATAL). -GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); +GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(logging_fail_func_t fail_func); // Enable/Disable old log cleaner. GOOGLE_GLOG_DLL_DECL void EnableLogCleaner(int overdue_days); @@ -1004,22 +1010,22 @@ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ #define LOG_PREVIOUS_TIME LOG_EVERY_N_VARNAME(previousTime_, __LINE__) #if defined(__has_feature) -#define _GLOG_HAS_FEATURE(...) __has_feature(__VA_ARGS__) +# if __has_feature(thread_sanitizer) +# define GLOG_SANITIZE_THREAD 1 +# endif +#endif + +#if !defined(GLOG_SANITIZE_THREAD) && defined(__SANITIZE_THREAD__) && __SANITIZE_THREAD__ +# define GLOG_SANITIZE_THREAD 1 +#endif + +#if defined(GLOG_SANITIZE_THREAD) +#define GLOG_IFDEF_THREAD_SANITIZER(X) X #else -#define _GLOG_HAS_FEATURE(...) 0 +#define GLOG_IFDEF_THREAD_SANITIZER(X) #endif -#if _GLOG_HAS_FEATURE(thread_sanitizer) || __SANITIZE_THREAD__ -#define _GLOG_SANITIZE_THREAD 1 -#endif - -#if defined(_GLOG_SANITIZE_THREAD) -#define _GLOG_IFDEF_THREAD_SANITIZER(X) X -#else -#define _GLOG_IFDEF_THREAD_SANITIZER(X) -#endif - -#if defined(_GLOG_SANITIZE_THREAD) +#if defined(GLOG_SANITIZE_THREAD) } // namespace google // We need to identify the static variables as "benign" races @@ -1038,9 +1044,9 @@ namespace google { #define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \ GLOG_CONSTEXPR std::chrono::nanoseconds LOG_TIME_PERIOD = std::chrono::duration_cast(std::chrono::duration(seconds)); \ static std::atomic LOG_PREVIOUS_TIME_RAW; \ - _GLOG_IFDEF_THREAD_SANITIZER( \ + GLOG_IFDEF_THREAD_SANITIZER( \ AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_TIME_PERIOD, sizeof(int64), "")); \ - _GLOG_IFDEF_THREAD_SANITIZER( \ + GLOG_IFDEF_THREAD_SANITIZER( \ AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_PREVIOUS_TIME_RAW, sizeof(int64), "")); \ const auto LOG_CURRENT_TIME = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()); \ const auto LOG_PREVIOUS_TIME = LOG_PREVIOUS_TIME_RAW.load(std::memory_order_relaxed); \ @@ -1083,9 +1089,9 @@ namespace google { #if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L #define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ - _GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ - _GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ + static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ + GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ + GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ ++LOG_OCCURRENCES; \ if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ if (LOG_OCCURRENCES_MOD_N == 1) \ @@ -1094,9 +1100,9 @@ namespace google { &what_to_do).stream() #define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ - static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ - _GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ - _GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ + static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ + GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ + GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ ++LOG_OCCURRENCES; \ if ((condition) && \ ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ @@ -1105,9 +1111,9 @@ namespace google { &what_to_do).stream() #define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ - static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ - _GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ - _GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ + static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ + GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ + GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ ++LOG_OCCURRENCES; \ if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ if (LOG_OCCURRENCES_MOD_N == 1) \ @@ -1116,8 +1122,8 @@ namespace google { &what_to_do).stream() #define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ - static std::atomic LOG_OCCURRENCES(0); \ - _GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ + static std::atomic LOG_OCCURRENCES(0); \ + GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ if (LOG_OCCURRENCES <= n) \ ++LOG_OCCURRENCES; \ if (LOG_OCCURRENCES <= n) \ @@ -1173,7 +1179,7 @@ namespace google { #else #define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + static unsigned LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \ if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \ __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \ @@ -1183,7 +1189,7 @@ namespace google { &what_to_do).stream() #define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + static unsigned LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \ if ((condition) && \ (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) || true) && \ @@ -1194,7 +1200,7 @@ namespace google { &what_to_do).stream() #define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + static unsigned LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \ if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \ __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \ @@ -1204,7 +1210,7 @@ namespace google { &what_to_do).stream() #define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0; \ + static unsigned LOG_OCCURRENCES = 0; \ if (LOG_OCCURRENCES <= n) \ __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \ if (LOG_OCCURRENCES <= n) \ @@ -1412,7 +1418,7 @@ class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf { } // Legacy public ostrstream method. - size_t pcount() const { return pptr() - pbase(); } + size_t pcount() const { return static_cast(pptr() - pbase()); } char* pbase() const { return std::streambuf::pbase(); } }; @@ -1860,7 +1866,7 @@ class GOOGLE_GLOG_DLL_DECL Logger { virtual void Write(bool force_flush, time_t timestamp, const char* message, - int message_len) = 0; + size_t message_len) = 0; // Flush any buffered messages virtual void Flush() = 0; @@ -1961,7 +1967,7 @@ GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); // is the size of the message. You should not expect the data is // terminated with '\0'. GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( - void (*writer)(const char* data, int size)); + void (*writer)(const char* data, size_t size)); @ac_google_end_namespace@ @@ -1970,4 +1976,4 @@ GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( #pragma pop_macro("GFLAGS_DLL_DECLARE_FLAG") #endif // defined(GLOG_GFLAGS_DLL_DECLARE_FLAG_WAS_DEFINED) -#endif // _LOGGING_H_ +#endif // GLOG_LOGGING_H diff --git a/src/glog/raw_logging.h.in b/src/glog/raw_logging.h.in index a0ba100..4372f54 100644 --- a/src/glog/raw_logging.h.in +++ b/src/glog/raw_logging.h.in @@ -33,8 +33,8 @@ // acquire any locks, and can therefore be used by low-level memory // allocation and synchronization code. -#ifndef BASE_RAW_LOGGING_H_ -#define BASE_RAW_LOGGING_H_ +#ifndef GLOG_RAW_LOGGING_H +#define GLOG_RAW_LOGGING_H #include @@ -52,6 +52,11 @@ # endif #endif +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wvariadic-macros" +#endif + // This is similar to LOG(severity) << format... and VLOG(level) << format.., // but // * it is to be used ONLY by low-level modules that can't use normal LOG() @@ -88,7 +93,7 @@ // The following STRIP_LOG testing is performed in the header file so that it's // possible to completely compile out the logging code and the log messages. -#if STRIP_LOG == 0 +#if !defined(STRIP_LOG) || STRIP_LOG == 0 #define RAW_VLOG(verboselevel, ...) \ do { \ if (VLOG_IS_ON(verboselevel)) { \ @@ -99,28 +104,28 @@ #define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__) #endif // STRIP_LOG == 0 -#if STRIP_LOG == 0 +#if !defined(STRIP_LOG) || STRIP_LOG == 0 #define RAW_LOG_INFO(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_INFO, \ __FILE__, __LINE__, __VA_ARGS__) #else #define RAW_LOG_INFO(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) #endif // STRIP_LOG == 0 -#if STRIP_LOG <= 1 +#if !defined(STRIP_LOG) || STRIP_LOG <= 1 #define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_WARNING, \ __FILE__, __LINE__, __VA_ARGS__) #else #define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) #endif // STRIP_LOG <= 1 -#if STRIP_LOG <= 2 +#if !defined(STRIP_LOG) || STRIP_LOG <= 2 #define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_ERROR, \ __FILE__, __LINE__, __VA_ARGS__) #else #define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) #endif // STRIP_LOG <= 2 -#if STRIP_LOG <= 3 +#if !defined(STRIP_LOG) || STRIP_LOG <= 3 #define RAW_LOG_FATAL(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_FATAL, \ __FILE__, __LINE__, __VA_ARGS__) #else @@ -160,6 +165,10 @@ #endif // NDEBUG +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + // Stub log function used to work around for unused variable warnings when // building with STRIP_LOG > 0. static inline void RawLogStub__(int /* ignored */, ...) { @@ -177,4 +186,4 @@ GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, @ac_google_end_namespace@ -#endif // BASE_RAW_LOGGING_H_ +#endif // GLOG_RAW_LOGGING_H diff --git a/src/googletest.h b/src/googletest.h index 801b559..bc3890f 100644 --- a/src/googletest.h +++ b/src/googletest.h @@ -273,8 +273,15 @@ static inline void RunSpecifiedBenchmarks() { iter->second(iter_cnt); double elapsed_ns = ((double)clock() - start) / CLOCKS_PER_SEC * 1000*1000*1000; +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat=" +#endif printf("%s\t%8.2lf\t%10d\n", iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt); +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif } puts(""); } @@ -402,7 +409,7 @@ static inline string GetCapturedTestStderr() { static inline bool IsLoggingPrefix(const string& s) { if (s.size() != 9) return false; if (!strchr("IWEF", s[0])) return false; - for (int i = 1; i <= 8; ++i) { + for (size_t i = 1; i <= 8; ++i) { if (!isdigit(s[i]) && s[i] != "YEARDATE"[i-1]) return false; } return true; @@ -549,7 +556,7 @@ class Thread { void Start() { handle_ = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE)&Thread::InvokeThread, + &Thread::InvokeThreadW, (LPVOID)this, 0, &th_); @@ -579,6 +586,10 @@ class Thread { } #if defined(OS_WINDOWS) && !defined(OS_CYGWIN) + static DWORD InvokeThreadW(void* self) { + InvokeThread(self); + return 0; + } HANDLE handle_; DWORD th_; #else @@ -586,7 +597,7 @@ class Thread { #endif }; -static inline void SleepForMilliseconds(int t) { +static inline void SleepForMilliseconds(unsigned t) { #ifndef OS_WINDOWS # if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L const struct timespec req = {0, t * 1000 * 1000}; @@ -620,6 +631,14 @@ void operator delete(void* p) throw() { free(p); } +void operator delete(void* p, size_t) throw() { + ::operator delete(p); +} + void operator delete[](void* p) throw() { ::operator delete(p); } + +void operator delete[](void* p, size_t) throw() { + ::operator delete(p); +} diff --git a/src/logging.cc b/src/logging.cc index b2fbc86..4309a3d 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -429,7 +429,7 @@ class LogFileObject : public base::Logger { virtual void Write(bool force_flush, // Should we force a flush here? time_t timestamp, // Timestamp for this entry const char* message, - int message_len); + size_t message_len); // Configuration options void SetBasename(const char* basename); @@ -695,13 +695,7 @@ inline void LogDestination::RemoveLogSink(LogSink *destination) { MutexLock l(&sink_mutex_); // This doesn't keep the sinks in order, but who cares? if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - if ((*sinks_)[i] == destination) { - (*sinks_)[i] = (*sinks_)[sinks_->size() - 1]; - sinks_->pop_back(); - break; - } - } + sinks_->erase(std::remove(sinks_->begin(), sinks_->end(), destination), sinks_->end()); } } @@ -785,7 +779,7 @@ static void WriteToStderr(const char* message, size_t len) { } inline void LogDestination::MaybeLogToStderr(LogSeverity severity, - const char* message, size_t message_len, size_t prefix_len) { + const char* message, size_t message_len, size_t /*prefix_len*/) { if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { ColoredWriteToStderr(severity, message, message_len); #ifdef OS_WINDOWS @@ -865,7 +859,7 @@ inline void LogDestination::LogToSinks(LogSeverity severity, int32 usecs) { ReaderMutexLock l(&sink_mutex_); if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { + for (size_t i = sinks_->size(); i-- > 0; ) { (*sinks_)[i]->send(severity, full_filename, base_filename, line, tm_time, message, message_len, usecs); } @@ -875,7 +869,7 @@ inline void LogDestination::LogToSinks(LogSeverity severity, inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { ReaderMutexLock l(&sink_mutex_); if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { + for (size_t i = sinks_->size(); i-- > 0; ) { (*sinks_)[i]->WaitTillSent(); } } @@ -1076,7 +1070,7 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) { const string linkname = symlink_basename_ + '.' + LogSeverityNames[severity_]; string linkpath; - if ( slash ) linkpath = string(filename, slash-filename+1); // get dirname + if ( slash ) linkpath = string(filename, static_cast(slash-filename+1)); // get dirname linkpath += linkname; unlink(linkpath.c_str()); // delete old one if it exists @@ -1109,7 +1103,7 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) { void LogFileObject::Write(bool force_flush, time_t timestamp, const char* message, - int message_len) { + size_t message_len) { MutexLock l(&lock_); // We don't log if the base_name_ is "" (which means "don't write") @@ -1235,7 +1229,7 @@ void LogFileObject::Write(bool force_flush, << "threadid file:line] msg" << '\n'; const string& file_header_string = file_header_stream.str(); - const int header_len = file_header_string.size(); + const size_t header_len = file_header_string.size(); fwrite(file_header_string.data(), 1, header_len, file_); file_length_ += header_len; bytes_since_flush_ += header_len; @@ -1275,7 +1269,7 @@ void LogFileObject::Write(bool force_flush, if (FLAGS_drop_log_memory && file_length_ >= (3 << 20)) { // Don't evict the most recent 1-2MiB so as not to impact a tailer // of the log file and to avoid page rounding issue on linux < 4.7 - uint32 total_drop_length = (file_length_ & ~((1 << 20) - 1)) - (1 << 20); + uint32 total_drop_length = (file_length_ & ~((1 << 20U) - 1U)) - (1U << 20U); uint32 this_drop_length = total_drop_length - dropped_mem_length_; if (this_drop_length >= (2 << 20)) { // Only advise when >= 2MiB to drop @@ -1773,7 +1767,7 @@ static char fatal_message[256]; void ReprintFatalMessage() { if (fatal_message[0]) { - const int n = strlen(fatal_message); + const size_t n = strlen(fatal_message); if (!FLAGS_logtostderr) { // Also write to stderr (don't color to avoid terminal checks) WriteToStderr(fatal_message, n); @@ -1848,7 +1842,7 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { SetCrashReason(&crash_reason); // Store shortened fatal message for other logs and GWQ status - const int copy = min(data_->num_chars_to_log_, + const size_t copy = min(data_->num_chars_to_log_, sizeof(fatal_message)-1); memcpy(fatal_message, data_->message_text_, copy); fatal_message[copy] = '\0'; @@ -1892,28 +1886,10 @@ void LogMessage::RecordCrashReason( #endif } -#ifdef HAVE___ATTRIBUTE__ -# define ATTRIBUTE_NORETURN __attribute__((noreturn)) -#else -# define ATTRIBUTE_NORETURN -#endif +GOOGLE_GLOG_DLL_DECL logging_fail_func_t g_logging_fail_func = reinterpret_cast(&abort); -#if defined(OS_WINDOWS) -__declspec(noreturn) -#endif -static void logging_fail() ATTRIBUTE_NORETURN; - -static void logging_fail() { - abort(); -} - -typedef void (*logging_fail_func_t)() ATTRIBUTE_NORETURN; - -GOOGLE_GLOG_DLL_DECL -logging_fail_func_t g_logging_fail_func = &logging_fail; - -void InstallFailureFunction(void (*fail_func)()) { - g_logging_fail_func = (logging_fail_func_t)fail_func; +void InstallFailureFunction(logging_fail_func_t fail_func) { + g_logging_fail_func = fail_func; } void LogMessage::Fail() { @@ -1947,7 +1923,7 @@ void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); // Omit prefix of message and trailing newline when recording in outvec_. const char *start = data_->message_text_ + data_->num_prefix_chars_; - int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; + size_t len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; data_->outvec_->push_back(string(start, len)); } else { SendToLog(); @@ -1960,7 +1936,7 @@ void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); // Omit prefix of message and trailing newline when writing to message_. const char *start = data_->message_text_ + data_->num_prefix_chars_; - int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; + size_t len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; data_->message_->assign(start, len); } SendToLog(); @@ -2321,7 +2297,7 @@ void TruncateLogFile(const char *path, int64 limit, int64 keep) { struct stat statbuf; const int kCopyBlockSize = 8 << 10; char copybuf[kCopyBlockSize]; - int64 read_offset, write_offset; + off_t read_offset, write_offset; // Don't follow symlinks unless they're our own fd symlinks in /proc int flags = O_RDWR; // TODO(hamaji): Support other environments. @@ -2366,9 +2342,9 @@ void TruncateLogFile(const char *path, int64 limit, int64 keep) { // Copy the last "keep" bytes of the file to the beginning of the file read_offset = statbuf.st_size - keep; write_offset = 0; - int bytesin, bytesout; + ssize_t bytesin, bytesout; while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) { - bytesout = pwrite(fd, copybuf, bytesin, write_offset); + bytesout = pwrite(fd, copybuf, static_cast(bytesin), write_offset); if (bytesout == -1) { PLOG(ERROR) << "Unable to write to " << path; break; @@ -2549,7 +2525,7 @@ void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) { #if defined(HAVE_CXX11_NULLPTR_T) && __cplusplus >= 201103L template <> -void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& v) { +void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) { (*os) << "nullptr"; } #endif // defined(HAVE_CXX11_NULLPTR_T) diff --git a/src/logging_unittest.cc b/src/logging_unittest.cc index 6bf08ab..ff26749 100644 --- a/src/logging_unittest.cc +++ b/src/logging_unittest.cc @@ -685,7 +685,7 @@ static void GetFiles(const string& pattern, vector* files) { files->push_back(dirname + data.cFileName); } while (FindNextFileA(handle, &data)); BOOL result = FindClose(handle); - LOG_SYSRESULT(result); + LOG_SYSRESULT(result != 0); #else # error There is no way to do glob. #endif @@ -844,7 +844,7 @@ struct MyLogger : public base::Logger { virtual void Write(bool /* should_flush */, time_t /* timestamp */, const char* message, - int length) { + size_t length) { data.append(message, length); } @@ -875,7 +875,7 @@ static void TestErrno() { } static void TestOneTruncate(const char *path, int64 limit, int64 keep, - int64 dsize, int64 ksize, int64 expect) { + size_t dsize, size_t ksize, size_t expect) { int fd; CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600)); @@ -883,15 +883,15 @@ static void TestOneTruncate(const char *path, int64 limit, int64 keep, const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr); // Fill the file with the requested data; first discard data, then kept data - int64 written = 0; + size_t written = 0; while (written < dsize) { - int bytes = min(dsize - written, discard_size); + size_t bytes = min(dsize - written, discard_size); CHECK_ERR(write(fd, discardstr, bytes)); written += bytes; } written = 0; while (written < ksize) { - int bytes = min(ksize - written, keep_size); + size_t bytes = min(ksize - written, keep_size); CHECK_ERR(write(fd, keepstr, bytes)); written += bytes; } @@ -901,19 +901,19 @@ static void TestOneTruncate(const char *path, int64 limit, int64 keep, // File should now be shorter struct stat statbuf; CHECK_ERR(fstat(fd, &statbuf)); - CHECK_EQ(statbuf.st_size, expect); + CHECK_EQ(static_cast(statbuf.st_size), expect); CHECK_ERR(lseek(fd, 0, SEEK_SET)); // File should contain the suffix of the original file - const size_t buf_size = statbuf.st_size + 1; + const size_t buf_size = static_cast(statbuf.st_size) + 1; char* buf = new char[buf_size]; memset(buf, 0, buf_size); CHECK_ERR(read(fd, buf, buf_size)); const char *p = buf; - int64 checked = 0; + size_t checked = 0; while (checked < expect) { - int bytes = min(expect - checked, keep_size); + size_t bytes = min(expect - checked, keep_size); CHECK(!memcmp(p, keepstr, bytes)); checked += bytes; } @@ -976,7 +976,7 @@ struct RecordDeletionLogger : public base::Logger { virtual void Write(bool force_flush, time_t timestamp, const char* message, - int length) { + size_t length) { wrapped_logger_->Write(force_flush, timestamp, message, length); } virtual void Flush() { wrapped_logger_->Flush(); } @@ -1201,7 +1201,7 @@ class TestLogSinkWriter : public Thread { // Normally this would be some more real/involved logging logic // where LOG() usage can't be eliminated, // e.g. pushing the message over with an RPC: - int messages_left = messages_.size(); + size_t messages_left = messages_.size(); mutex_.Unlock(); SleepForMilliseconds(20); // May not use LOG while holding mutex_, because Buffer() @@ -1256,7 +1256,7 @@ class TestWaitingLogSink : public LogSink { const char* base_filename, int line, const struct tm* tm_time, const char* message, size_t message_len) { - send(severity, full_filename, base_filename, line, tm_time, message, message_len); + send(severity, full_filename, base_filename, line, tm_time, message, message_len, 0); } virtual void WaitTillSent() { diff --git a/src/raw_logging.cc b/src/raw_logging.cc index be868ec..e7dc543 100644 --- a/src/raw_logging.cc +++ b/src/raw_logging.cc @@ -76,23 +76,23 @@ _START_GOOGLE_NAMESPACE_ // Helper for RawLog__ below. // *DoRawLog writes to *buf of *size and move them past the written portion. // It returns true iff there was no overflow or error. -static bool DoRawLog(char** buf, int* size, const char* format, ...) { +static bool DoRawLog(char** buf, size_t* size, const char* format, ...) { va_list ap; va_start(ap, format); int n = vsnprintf(*buf, *size, format, ap); va_end(ap); - if (n < 0 || n > *size) return false; - *size -= n; + if (n < 0 || static_cast(n) > *size) return false; + *size -= static_cast(n); *buf += n; return true; } // Helper for RawLog__ below. -inline static bool VADoRawLog(char** buf, int* size, +inline static bool VADoRawLog(char** buf, size_t* size, const char* format, va_list ap) { int n = vsnprintf(*buf, *size, format, ap); - if (n < 0 || n > *size) return false; - *size -= n; + if (n < 0 || static_cast(n) > *size) return false; + *size -= static_cast(n); *buf += n; return true; } @@ -111,7 +111,7 @@ void RawLog__(LogSeverity severity, const char* file, int line, // can't call localtime_r here: it can allocate char buffer[kLogBufSize]; char* buf = buffer; - int size = sizeof(buffer); + size_t size = sizeof(buffer); // NOTE: this format should match the specification in base/logging.h DoRawLog(&buf, &size, "%c00000000 00:00:00.000000 %5u %s:%d] RAW: ", @@ -121,7 +121,7 @@ void RawLog__(LogSeverity severity, const char* file, int line, // Record the position and size of the buffer after the prefix const char* msg_start = buf; - const int msg_size = size; + const size_t msg_size = size; va_list ap; va_start(ap, format); diff --git a/src/signalhandler.cc b/src/signalhandler.cc index b6d6e25..b319d4b 100644 --- a/src/signalhandler.cc +++ b/src/signalhandler.cc @@ -71,6 +71,7 @@ const struct { static bool kFailureSignalHandlerInstalled = false; +#if !defined(OS_WINDOWS) // Returns the program counter from signal context, NULL if unknown. void* GetPC(void* ucontext_in_void) { #if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT) @@ -78,26 +79,29 @@ void* GetPC(void* ucontext_in_void) { ucontext_t *context = reinterpret_cast(ucontext_in_void); return (void*)context->PC_FROM_UCONTEXT; } +#else + (void)ucontext_in_void; #endif return NULL; } +#endif // The class is used for formatting error messages. We don't use printf() // as it's not async signal safe. class MinimalFormatter { public: - MinimalFormatter(char *buffer, int size) + MinimalFormatter(char *buffer, size_t size) : buffer_(buffer), cursor_(buffer), end_(buffer + size) { } // Returns the number of bytes written in the buffer. - int num_bytes_written() const { return (int) (cursor_ - buffer_); } + std::size_t num_bytes_written() const { return static_cast(cursor_ - buffer_); } // Appends string from "str" and updates the internal cursor. void AppendString(const char* str) { - int i = 0; + ptrdiff_t i = 0; while (str[i] != '\0' && cursor_ + i < end_) { cursor_[i] = str[i]; ++i; @@ -107,12 +111,12 @@ class MinimalFormatter { // Formats "number" in "radix" and updates the internal cursor. // Lowercase letters are used for 'a' - 'z'. - void AppendUint64(uint64 number, int radix) { - int i = 0; + void AppendUint64(uint64 number, unsigned radix) { + unsigned i = 0; while (cursor_ + i < end_) { - const int tmp = number % radix; + const uint64 tmp = number % radix; number /= radix; - cursor_[i] = (tmp < 10 ? '0' + tmp : 'a' + tmp - 10); + cursor_[i] = static_cast(tmp < 10 ? '0' + tmp : 'a' + tmp - 10); ++i; if (number == 0) { break; @@ -145,14 +149,14 @@ class MinimalFormatter { }; // Writes the given data with the size to the standard error. -void WriteToStderr(const char* data, int size) { +void WriteToStderr(const char* data, size_t size) { if (write(STDERR_FILENO, data, size) < 0) { // Ignore errors. } } // The writer function can be changed by InstallFailureWriter(). -void (*g_failure_writer)(const char* data, int size) = WriteToStderr; +void (*g_failure_writer)(const char* data, size_t size) = WriteToStderr; // Dumps time information. We don't dump human-readable time information // as localtime() is not guaranteed to be async signal safe. @@ -161,10 +165,10 @@ void DumpTimeInfo() { char buf[256]; // Big enough for time info. MinimalFormatter formatter(buf, sizeof(buf)); formatter.AppendString("*** Aborted at "); - formatter.AppendUint64(time_in_sec, 10); + formatter.AppendUint64(static_cast(time_in_sec), 10); formatter.AppendString(" (unix time)"); formatter.AppendString(" try \"date -d @"); - formatter.AppendUint64(time_in_sec, 10); + formatter.AppendUint64(static_cast(time_in_sec), 10); formatter.AppendString("\" if you are using GNU date ***\n"); g_failure_writer(buf, formatter.num_bytes_written()); } @@ -192,13 +196,13 @@ void DumpSignalInfo(int signal_number, siginfo_t *siginfo) { // Use the signal number if the name is unknown. The signal name // should be known, but just in case. formatter.AppendString("Signal "); - formatter.AppendUint64(signal_number, 10); + formatter.AppendUint64(static_cast(signal_number), 10); } formatter.AppendString(" (@0x"); formatter.AppendUint64(reinterpret_cast(siginfo->si_addr), 16); formatter.AppendString(")"); formatter.AppendString(" received by PID "); - formatter.AppendUint64(getpid(), 10); + formatter.AppendUint64(static_cast(getpid()), 10); formatter.AppendString(" (TID 0x"); // We assume pthread_t is an integral number or a pointer, rather // than a complex struct. In some environments, pthread_self() @@ -210,7 +214,7 @@ void DumpSignalInfo(int signal_number, siginfo_t *siginfo) { // Only linux has the PID of the signal sender in si_pid. #ifdef OS_LINUX formatter.AppendString("from PID "); - formatter.AppendUint64(siginfo->si_pid, 10); + formatter.AppendUint64(static_cast(siginfo->si_pid), 10); formatter.AppendString("; "); #endif formatter.AppendString("stack trace: ***\n"); @@ -394,7 +398,7 @@ void InstallFailureSignalHandler() { #endif // HAVE_SIGACTION } -void InstallFailureWriter(void (*writer)(const char* data, int size)) { +void InstallFailureWriter(void (*writer)(const char* data, size_t size)) { #if defined(HAVE_SIGACTION) || defined(OS_WINDOWS) g_failure_writer = writer; #endif // HAVE_SIGACTION diff --git a/src/signalhandler_unittest.cc b/src/signalhandler_unittest.cc index 13b27d3..3c90556 100644 --- a/src/signalhandler_unittest.cc +++ b/src/signalhandler_unittest.cc @@ -64,7 +64,7 @@ static void* DieInThread(void*) { return NULL; } -static void WriteToStdout(const char* data, int size) { +static void WriteToStdout(const char* data, size_t size) { if (write(STDOUT_FILENO, data, size) < 0) { // Ignore errors. } diff --git a/src/stacktrace_unittest.cc b/src/stacktrace_unittest.cc index e23b4c4..df78d62 100644 --- a/src/stacktrace_unittest.cc +++ b/src/stacktrace_unittest.cc @@ -111,6 +111,11 @@ static void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range) //-----------------------------------------------------------------------// +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu-label-as-value" +#endif + void ATTRIBUTE_NOINLINE CheckStackTrace(int); static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) { const int STACK_LEN = 10; @@ -131,7 +136,13 @@ static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) { printf("Obtained %d stack frames.\n", size); for (int i = 0; i < size; i++) printf("%s %p\n", strings[i], stack[i]); - printf("CheckStackTrace() addr: %p\n", &CheckStackTrace); + + union { + void (*p1)(int); + void* p2; + } p = {&CheckStackTrace}; + + printf("CheckStackTrace() addr: %p\n", p.p2); free(strings); #endif } @@ -180,6 +191,7 @@ static void ATTRIBUTE_NOINLINE CheckStackTrace1(int i) { CheckStackTrace2(j); DECLARE_ADDRESS_LABEL(end); } + #ifndef __GNUC__ // On non-GNU environment, we use the address of `CheckStackTrace` to // guess the address range of this function. This guess is wrong for @@ -197,6 +209,10 @@ void ATTRIBUTE_NOINLINE CheckStackTrace(int i) { DECLARE_ADDRESS_LABEL(end); } +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + //-----------------------------------------------------------------------// int main(int, char ** argv) { diff --git a/src/stacktrace_windows-inl.h b/src/stacktrace_windows-inl.h index f7553a6..e6af561 100644 --- a/src/stacktrace_windows-inl.h +++ b/src/stacktrace_windows-inl.h @@ -44,7 +44,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) { } skip_count++; // we want to skip the current frame as well // This API is thread-safe (moreover it walks only the current thread). - return CaptureStackBackTrace(skip_count, max_depth, result, NULL); + return CaptureStackBackTrace(static_cast(skip_count), static_cast(max_depth), result, NULL); } _END_GOOGLE_NAMESPACE_ diff --git a/src/stl_logging_unittest.cc b/src/stl_logging_unittest.cc index b3d7c27..79be2b5 100644 --- a/src/stl_logging_unittest.cc +++ b/src/stl_logging_unittest.cc @@ -68,7 +68,7 @@ using namespace __gnu_cxx; #endif struct user_hash { - size_t operator()(int x) const { return x; } + size_t operator()(int x) const { return static_cast(x); } }; static void TestSTLLogging() { diff --git a/src/symbolize.cc b/src/symbolize.cc index f7fbc53..99cc79e 100644 --- a/src/symbolize.cc +++ b/src/symbolize.cc @@ -144,25 +144,25 @@ _START_GOOGLE_NAMESPACE_ // and EINTR. On success, return the number of bytes read. Otherwise, return // -1. static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count, - const off_t offset) { + const size_t offset) { SAFE_ASSERT(fd >= 0); SAFE_ASSERT(count <= std::numeric_limits::max()); char *buf0 = reinterpret_cast(buf); - ssize_t num_bytes = 0; + size_t num_bytes = 0; while (num_bytes < count) { ssize_t len; NO_INTR(len = pread(fd, buf0 + num_bytes, count - num_bytes, - offset + num_bytes)); + static_cast(offset + num_bytes))); if (len < 0) { // There was an error other than EINTR. return -1; } if (len == 0) { // Reached EOF. break; } - num_bytes += len; + num_bytes += static_cast(len); } SAFE_ASSERT(num_bytes <= count); - return num_bytes; + return static_cast(num_bytes); } // Try reading exactly "count" bytes from "offset" bytes in a file @@ -170,9 +170,9 @@ static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count, // short reads and EINTR. On success, return true. Otherwise, return // false. static bool ReadFromOffsetExact(const int fd, void *buf, - const size_t count, const off_t offset) { + const size_t count, const size_t offset) { ssize_t len = ReadFromOffset(fd, buf, count, offset); - return len == count; + return static_cast(len) == count; } // Returns elf_header.e_type if the file pointed by fd is an ELF binary. @@ -193,23 +193,23 @@ static int FileGetElfType(const int fd) { // To keep stack consumption low, we would like this function to not get // inlined. static ATTRIBUTE_NOINLINE bool -GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const off_t sh_offset, +GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const size_t sh_offset, ElfW(Word) type, ElfW(Shdr) *out) { // Read at most 16 section headers at a time to save read calls. ElfW(Shdr) buf[16]; - for (int i = 0; i < sh_num;) { - const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]); - const ssize_t num_bytes_to_read = + for (size_t i = 0; i < sh_num;) { + const size_t num_bytes_left = (sh_num - i) * sizeof(buf[0]); + const size_t num_bytes_to_read = (sizeof(buf) > num_bytes_left) ? num_bytes_left : sizeof(buf); const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read, sh_offset + i * sizeof(buf[0])); if (len == -1) { return false; } - SAFE_ASSERT(len % sizeof(buf[0]) == 0); - const ssize_t num_headers_in_buf = len / sizeof(buf[0]); + SAFE_ASSERT(static_cast(len) % sizeof(buf[0]) == 0); + const size_t num_headers_in_buf = static_cast(len) / sizeof(buf[0]); SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0])); - for (int j = 0; j < num_headers_in_buf; ++j) { + for (size_t j = 0; j < num_headers_in_buf; ++j) { if (buf[j].sh_type == type) { *out = buf[j]; return true; @@ -233,14 +233,14 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, } ElfW(Shdr) shstrtab; - off_t shstrtab_offset = (elf_header.e_shoff + + size_t shstrtab_offset = (elf_header.e_shoff + elf_header.e_shentsize * elf_header.e_shstrndx); if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) { return false; } - for (int i = 0; i < elf_header.e_shnum; ++i) { - off_t section_header_offset = (elf_header.e_shoff + + for (size_t i = 0; i < elf_header.e_shnum; ++i) { + size_t section_header_offset = (elf_header.e_shoff + elf_header.e_shentsize * i); if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) { return false; @@ -252,11 +252,11 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, // No point in even trying. return false; } - off_t name_offset = shstrtab.sh_offset + out->sh_name; + size_t name_offset = shstrtab.sh_offset + out->sh_name; ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset); if (n_read == -1) { return false; - } else if (n_read != name_len) { + } else if (static_cast(n_read) != name_len) { // Short read -- name could be at end of file. continue; } @@ -274,34 +274,34 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, // To keep stack consumption low, we would like this function to not get // inlined. static ATTRIBUTE_NOINLINE bool -FindSymbol(uint64_t pc, const int fd, char *out, int out_size, +FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size, uint64_t symbol_offset, const ElfW(Shdr) *strtab, const ElfW(Shdr) *symtab) { if (symtab == NULL) { return false; } - const int num_symbols = symtab->sh_size / symtab->sh_entsize; - for (int i = 0; i < num_symbols;) { - off_t offset = symtab->sh_offset + i * symtab->sh_entsize; + const size_t num_symbols = symtab->sh_size / symtab->sh_entsize; + for (unsigned i = 0; i < num_symbols;) { + size_t offset = symtab->sh_offset + i * symtab->sh_entsize; // If we are reading Elf64_Sym's, we want to limit this array to // 32 elements (to keep stack consumption low), otherwise we can // have a 64 element Elf32_Sym array. -#if __WORDSIZE == 64 -#define NUM_SYMBOLS 32 +#if defined(__WORDSIZE) && __WORDSIZE == 64 + const size_t NUM_SYMBOLS = 32U; #else -#define NUM_SYMBOLS 64 + const size_t NUM_SYMBOLS = 64U; #endif // Read at most NUM_SYMBOLS symbols at once to save read() calls. ElfW(Sym) buf[NUM_SYMBOLS]; - int num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i); + size_t num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i); const ssize_t len = ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset); - SAFE_ASSERT(len % sizeof(buf[0]) == 0); - const ssize_t num_symbols_in_buf = len / sizeof(buf[0]); + SAFE_ASSERT(static_cast(len) % sizeof(buf[0]) == 0); + const size_t num_symbols_in_buf = static_cast(len) / sizeof(buf[0]); SAFE_ASSERT(num_symbols_in_buf <= num_symbols_to_read); - for (int j = 0; j < num_symbols_in_buf; ++j) { + for (unsigned j = 0; j < num_symbols_in_buf; ++j) { const ElfW(Sym)& symbol = buf[j]; uint64_t start_address = symbol.st_value; start_address += symbol_offset; @@ -330,7 +330,7 @@ FindSymbol(uint64_t pc, const int fd, char *out, int out_size, static bool GetSymbolFromObjectFile(const int fd, uint64_t pc, char* out, - int out_size, + size_t out_size, uint64_t base_address) { // Read the ELF header. ElfW(Ehdr) elf_header; @@ -392,7 +392,7 @@ struct FileDescriptor { // and snprintf(). class LineReader { public: - explicit LineReader(int fd, char *buf, int buf_len, off_t offset) + explicit LineReader(int fd, char *buf, size_t buf_len, size_t offset) : fd_(fd), buf_(buf), buf_len_(buf_len), @@ -412,25 +412,25 @@ class LineReader { if (num_bytes <= 0) { // EOF or error. return false; } - offset_ += num_bytes; + offset_ += static_cast(num_bytes); eod_ = buf_ + num_bytes; bol_ = buf_; } else { bol_ = eol_ + 1; // Advance to the next line in the buffer. SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_". if (!HasCompleteLine()) { - const int incomplete_line_length = eod_ - bol_; + const size_t incomplete_line_length = static_cast(eod_ - bol_); // Move the trailing incomplete line to the beginning. memmove(buf_, bol_, incomplete_line_length); // Read text from file and append it. char * const append_pos = buf_ + incomplete_line_length; - const int capacity_left = buf_len_ - incomplete_line_length; + const size_t capacity_left = buf_len_ - incomplete_line_length; const ssize_t num_bytes = ReadFromOffset(fd_, append_pos, capacity_left, offset_); if (num_bytes <= 0) { // EOF or error. return false; } - offset_ += num_bytes; + offset_ += static_cast(num_bytes); eod_ = append_pos + num_bytes; bol_ = buf_; } @@ -461,7 +461,7 @@ class LineReader { void operator=(const LineReader&); char *FindLineFeed() { - return reinterpret_cast(memchr(bol_, '\n', eod_ - bol_)); + return reinterpret_cast(memchr(bol_, '\n', static_cast(eod_ - bol_))); } bool BufferIsEmpty() { @@ -474,8 +474,8 @@ class LineReader { const int fd_; char * const buf_; - const int buf_len_; - off_t offset_; + const size_t buf_len_; + size_t offset_; char *bol_; char *eol_; const char *eod_; // End of data in "buf_". @@ -491,7 +491,7 @@ static char *GetHex(const char *start, const char *end, uint64_t *hex) { int ch = *p; if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) { - *hex = (*hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9); + *hex = (*hex << 4U) | (ch < 'A' ? static_cast(ch - '0') : (ch & 0xF) + 9U); } else { // Encountered the first non-hex character. break; } @@ -513,7 +513,7 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc, uint64_t &start_address, uint64_t &base_address, char *out_file_name, - int out_file_name_size) { + size_t out_file_name_size) { int object_fd; int maps_fd; @@ -533,7 +533,7 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc, // Iterate over maps and look for the map containing the pc. Then // look into the symbol tables inside. char buf[1024]; // Big enough for line of sane /proc/self/maps - int num_maps = 0; + unsigned num_maps = 0; LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf), 0); while (true) { num_maps++; @@ -670,7 +670,7 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc, // bytes. Output will be truncated as needed, and a NUL character is always // appended. // NOTE: code from sandbox/linux/seccomp-bpf/demo.cc. -static char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) { +static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t padding) { // Make sure we can write at least one NUL byte. size_t n = 1; if (n > sz) @@ -733,8 +733,8 @@ static char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) // Safely appends string |source| to string |dest|. Never writes past the // buffer size |dest_size| and guarantees that |dest| is null-terminated. -static void SafeAppendString(const char* source, char* dest, int dest_size) { - int dest_string_length = strlen(dest); +static void SafeAppendString(const char* source, char* dest, size_t dest_size) { + size_t dest_string_length = strlen(dest); SAFE_ASSERT(dest_string_length < dest_size); dest += dest_string_length; dest_size -= dest_string_length; @@ -746,7 +746,7 @@ static void SafeAppendString(const char* source, char* dest, int dest_size) { // Converts a 64-bit value into a hex string, and safely appends it to |dest|. // Never writes past the buffer size |dest_size| and guarantees that |dest| is // null-terminated. -static void SafeAppendHexNumber(uint64_t value, char* dest, int dest_size) { +static void SafeAppendHexNumber(uint64_t value, char* dest, size_t dest_size) { // 64-bit numbers in hex can have up to 16 digits. char buf[17] = {'\0'}; SafeAppendString(itoa_r(value, buf, sizeof(buf), 16, 0), dest, dest_size); @@ -761,7 +761,7 @@ static void SafeAppendHexNumber(uint64_t value, char* dest, int dest_size) { // To keep stack consumption low, we would like this function to not // get inlined. static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - int out_size) { + size_t out_size) { uint64_t pc0 = reinterpret_cast(pc); uint64_t start_address = 0; uint64_t base_address = 0; @@ -819,8 +819,8 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, pc, out, out_size, relocation); if (num_bytes_written > 0) { - out += num_bytes_written; - out_size -= num_bytes_written; + out += static_cast(num_bytes_written); + out_size -= static_cast(num_bytes_written); } } if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0, @@ -854,11 +854,11 @@ _END_GOOGLE_NAMESPACE_ _START_GOOGLE_NAMESPACE_ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - int out_size) { + size_t out_size) { Dl_info info; if (dladdr(pc, &info)) { if (info.dli_sname) { - if ((int)strlen(info.dli_sname) < out_size) { + if (strlen(info.dli_sname) < out_size) { strcpy(out, info.dli_sname); // Symbolization succeeded. Now we try to demangle the symbol. DemangleInplace(out, out_size); @@ -942,7 +942,7 @@ _END_GOOGLE_NAMESPACE_ _START_GOOGLE_NAMESPACE_ -bool Symbolize(void *pc, char *out, int out_size) { +bool Symbolize(void *pc, char *out, size_t out_size) { SAFE_ASSERT(out_size >= 0); return SymbolizeAndDemangle(pc, out, out_size); } @@ -958,7 +958,7 @@ _END_GOOGLE_NAMESPACE_ _START_GOOGLE_NAMESPACE_ // TODO: Support other environments. -bool Symbolize(void *pc, char *out, int out_size) { +bool Symbolize(void* /*pc*/, char* /*out*/, size_t /*out_size*/) { assert(0); return false; } diff --git a/src/symbolize.h b/src/symbolize.h index fbc36f5..082ca67 100644 --- a/src/symbolize.h +++ b/src/symbolize.h @@ -138,7 +138,7 @@ typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc, uint64_t& start_address, uint64_t& base_address, char* out_file_name, - int out_file_name_size); + size_t out_file_name_size); void InstallSymbolizeOpenObjectFileCallback( SymbolizeOpenObjectFileCallback callback); @@ -152,7 +152,7 @@ _START_GOOGLE_NAMESPACE_ // symbol name to "out". The symbol name is demangled if possible // (supports symbols generated by GCC 3.x or newer). Otherwise, // returns false. -GOOGLE_GLOG_DLL_DECL bool Symbolize(void *pc, char *out, int out_size); +GOOGLE_GLOG_DLL_DECL bool Symbolize(void *pc, char *out, size_t out_size); _END_GOOGLE_NAMESPACE_ diff --git a/src/symbolize_unittest.cc b/src/symbolize_unittest.cc index 0b53230..d150049 100644 --- a/src/symbolize_unittest.cc +++ b/src/symbolize_unittest.cc @@ -31,15 +31,14 @@ // // Unit tests for functions in symbolize.cc. -#include "utilities.h" - #include #include -#include "glog/logging.h" -#include "symbolize.h" -#include "googletest.h" #include "config.h" +#include "glog/logging.h" +#include "googletest.h" +#include "symbolize.h" +#include "utilities.h" #ifdef HAVE_LIB_GFLAGS #include @@ -53,6 +52,7 @@ using namespace GOOGLE_NAMESPACE; #define always_inline +#if defined(__ELF__) || defined(OS_WINDOWS) || defined(OS_CYGWIN) // A wrapper function for Symbolize() to make the unit test simple. static const char *TrySymbolize(void *pc) { static char symbol[4096]; @@ -62,6 +62,7 @@ static const char *TrySymbolize(void *pc) { return NULL; } } +#endif # if defined(__ELF__) @@ -152,9 +153,9 @@ static void *g_pc_to_symbolize; static char g_symbolize_buffer[4096]; static char *g_symbolize_result; -static void EmptySignalHandler(int signo) {} +static void EmptySignalHandler(int /*signo*/) {} -static void SymbolizeSignalHandler(int signo) { +static void SymbolizeSignalHandler(int /*signo*/) { if (Symbolize(g_pc_to_symbolize, g_symbolize_buffer, sizeof(g_symbolize_buffer))) { g_symbolize_result = g_symbolize_buffer; diff --git a/src/utilities.cc b/src/utilities.cc index ba6189a..2222b7e 100644 --- a/src/utilities.cc +++ b/src/utilities.cc @@ -29,6 +29,7 @@ // // Author: Shinichiro Hamaji +#include "config.h" #include "utilities.h" #include @@ -142,6 +143,11 @@ static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) { } } +#if defined(__GNUC__) +__attribute__((noreturn)) +#elif defined(_MSC_VER) +__declspec(noreturn) +#endif static void DumpStackTraceAndExit() { DumpStackTrace(1, DebugWriteToStderr, NULL); @@ -187,10 +193,14 @@ struct timeval { // Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd // See COPYING for copyright information. -static int gettimeofday(struct timeval *tv, void* tz) { +static int gettimeofday(struct timeval *tv, void* /*tz*/) { +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlong-long" +#endif #define EPOCHFILETIME (116444736000000000ULL) FILETIME ft; - LARGE_INTEGER li; + ULARGE_INTEGER li; uint64 tt; GetSystemTimeAsFileTime(&ft); @@ -199,6 +209,9 @@ static int gettimeofday(struct timeval *tv, void* tz) { tt = (li.QuadPart - EPOCHFILETIME) / 10; tv->tv_sec = tt / 1000000; tv->tv_usec = tt % 1000000; +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif return 0; } @@ -251,9 +264,9 @@ pid_t GetTID() { #if (defined(OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP)) uint64_t tid64; const int error = pthread_threadid_np(NULL, &tid64); - pid_t tid = error ? -1 : (pid_t)tid64; + pid_t tid = error ? -1 : static_cast(tid64); #else - pid_t tid = syscall(__NR_gettid); + pid_t tid = static_cast(syscall(__NR_gettid)); #endif if (tid != -1) { return tid; diff --git a/src/vlog_is_on.cc b/src/vlog_is_on.cc index 6e930c5..41ddbdf 100644 --- a/src/vlog_is_on.cc +++ b/src/vlog_is_on.cc @@ -141,7 +141,7 @@ static void VLOG2Initializer() { VModuleInfo* head = NULL; VModuleInfo* tail = NULL; while ((sep = strchr(vmodule, '=')) != NULL) { - string pattern(vmodule, sep - vmodule); + string pattern(vmodule, static_cast(sep - vmodule)); int module_level; if (sscanf(sep, "=%d", &module_level) == 1) { VModuleInfo* info = new VModuleInfo; @@ -166,7 +166,7 @@ static void VLOG2Initializer() { // This can be called very early, so we use SpinLock and RAW_VLOG here. int SetVLOGLevel(const char* module_pattern, int log_level) { int result = FLAGS_v; - int const pattern_len = strlen(module_pattern); + size_t const pattern_len = strlen(module_pattern); bool found = false; { MutexLock l(&vmodule_lock); // protect whole read-modify-write