cameron314 / concurrentqueue

A fast multi-producer, multi-consumer lock-free concurrent queue for C++11
Other
9.85k stars 1.68k forks source link

loop panic #397

Open guojun08512 opened 6 days ago

guojun08512 commented 6 days ago

code:

  struct LogEvent {
  std::string fmt;
  void *udata;
  std::string file_path;
  int line;
  SlogLevel level;
  std::string tag;
  int syslog_triger;

  explicit LogEvent(std::string fmt, void *udata, std::string file_path, int line, SlogLevel level, std::string tag,
                    int syslog_triger = 0)
      : fmt(std::move(fmt)),
        udata(udata),
        file_path(std::move(file_path)),
        line(line),
        level(level),
        tag(std::move(tag)),
        syslog_triger(syslog_triger) {}
};

 moodycamel::ConcurrentQueue<LogEvent> log_buffer_;
   static void LogToSyslog(const LogEvent &lev) {
    auto log_t = fmt::format("{}: {}", lev.tag, lev.fmt);
    syslog(LoggerTools::LevelSyslog(lev.level), "%s", log_t.c_str());
  } 
int main() {
   const LogEvent lev{
        formatted, nullptr, file, line, level, tag,
    };

    log_buffer_.enqueue(lev);
    while (log_buffer_.size_approx() > 0) {
    LogEvent lev{"", nullptr, "", 0, SlogLevel::DEBUG, ""};
    auto ret = log_buffer_.try_dequeue(lev);
    if (!ret) {
      continue;
    }
    if (lev.level >= default_level_) {
      LogToSyslog(lev);
    }
  }
}

panic info:

#0  std::__atomic_base<unsigned long>::load (__m=std::memory_order_relaxed, this=0x8c618a53ab61cf75) at /home/sinsegye/.conan/data/gcc/8.4.0/_/_/package/c36389a16c86a80fda9a30c45330b881d7951813/include/c++/8.4.0/bits/atomic_base.h:396
#1  moodycamel::ConcurrentQueue<slog::LogEvent, moodycamel::ConcurrentQueueDefaultTraits>::ProducerBase::size_approx (this=0x8c618a53ab61cf55) at /home/sinsegye/.conan/data/concurrentqueue/1.0.4/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/moodycamel/concurrentqueue.h:1739
#2  0x000000000041721a in moodycamel::ConcurrentQueue<slog::LogEvent, moodycamel::ConcurrentQueueDefaultTraits>::size_approx (this=0x4a3860 <slog::Logger::instance()::inst>)
    at /home/sinsegye/.conan/data/concurrentqueue/1.0.4/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/moodycamel/concurrentqueue.h:1329
#3  0x0000000000406b36 in slog::Logger::Worker (this=0x4a3860 <slog::Logger::instance()::inst>) at /home/sinsegye/workspace/apps/src/logger/logger.cc:75
#4  0x000000000041b54f in std::__invoke_impl<void, void (slog::Logger::*)(), slog::Logger*> (__f=@0x1397bd0: (void (slog::Logger::*)(slog::Logger * const)) 0x406acc <slog::Logger::Worker()>, __t=@0x1397bc8: 0x4a3860 <slog::Logger::instance()::inst>)
    at /home/sinsegye/.conan/data/gcc/8.4.0/_/_/package/c36389a16c86a80fda9a30c45330b881d7951813/include/c++/8.4.0/bits/invoke.h:73
#5  0x0000000000417a95 in std::__invoke<void (slog::Logger::*)(), slog::Logger*> (__fn=@0x1397bd0: (void (slog::Logger::*)(slog::Logger * const)) 0x406acc <slog::Logger::Worker()>)
    at /home/sinsegye/.conan/data/gcc/8.4.0/_/_/package/c36389a16c86a80fda9a30c45330b881d7951813/include/c++/8.4.0/bits/invoke.h:95
#6  0x000000000045ddae in std::thread::_Invoker<std::tuple<void (slog::Logger::*)(), slog::Logger*> >::_M_invoke<0ul, 1ul> (this=0x1397bc8) at /home/sinsegye/.conan/data/gcc/8.4.0/_/_/package/c36389a16c86a80fda9a30c45330b881d7951813/include/c++/8.4.0/thread:244
#7  0x000000000045d92e in std::thread::_Invoker<std::tuple<void (slog::Logger::*)(), slog::Logger*> >::operator() (this=0x1397bc8) at /home/sinsegye/.conan/data/gcc/8.4.0/_/_/package/c36389a16c86a80fda9a30c45330b881d7951813/include/c++/8.4.0/thread:253
#8  0x000000000045c50e in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (slog::Logger::*)(), slog::Logger*> > >::_M_run (this=0x1397bc0) at /home/sinsegye/.conan/data/gcc/8.4.0/_/_/package/c36389a16c86a80fda9a30c45330b881d7951813/include/c++/8.4.0/thread:196
#9  0x00007ac349537253 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#10 0x00007ac3491bfac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#11 0x00007ac349250a04 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
cameron314 commented 6 days ago

The code you've shared seems fine at first glance. Callstack suggests something else is happening in code not shown here.

guojun08512 commented 6 days ago
enum SYSLOGTRG : int {
  DEFAULT,
  ENABLE,
  DISABLE,
};

auto Logger::IsLogBufferEmpty() -> bool { return log_buffer_.size_approx() == 0; }

auto Logger::SysLogEnable(SyslogType type) -> bool {
#ifdef _WIN32
  init_syslog();
#endif
  closelog();
  switch (type) {
    case APPLICATION:
      openlog(nullptr, LOG_PID, LOG_LOCAL4);
      break;
    case SERVICE:
      openlog(nullptr, LOG_PID, LOG_LOCAL3);
      break;
    case IO_DEVICES:
      openlog(nullptr, LOG_PID, LOG_LOCAL0);
      break;
    case COMMUNICATION_BUS:
      openlog(nullptr, LOG_PID, LOG_LOCAL1);
      break;
    case SAFETY_SYSTEMS:
      openlog(nullptr, LOG_PID, LOG_LOCAL2);
      break;
    case RUNTIME:
      openlog(nullptr, LOG_PID, LOG_LOCAL5);
      break;
    case SYSTEM_MAINTENANCE:
      openlog(nullptr, LOG_PID, LOG_LOCAL6);
      break;
    case TEMPORARY_DEBUGGING:
      openlog(nullptr, LOG_PID, LOG_LOCAL7);
      break;
  }
  const LogEvent lev{"", nullptr, "", 0, SlogLevel::DEBUG, "", ENABLE};
  log_buffer_.enqueue(lev);
  return true;
}

void Logger::SysLogDisable() {
  const LogEvent lev{"", nullptr, "", 0, SlogLevel::DEBUG, "", DISABLE};
  log_buffer_.enqueue(lev);
  closelog();
}

void Logger::Log(SlogLevel level, const std::string &tag, const std::string &file, int line,
                 const std::string &formatted) {
  const LogEvent lev{
      formatted, nullptr, file, line, level, tag,
  };

  log_buffer_.enqueue(lev);
}

void Logger::Worker() {
  while (!stop_worker_) {
    while (log_buffer_.size_approx() > 0) {
      if (stop_worker_) {
        break;
      }
      static std::atomic<bool> syslog{false};
      LogEvent lev{"", nullptr, "", 0, SlogLevel::DEBUG, ""};
      auto ret = log_buffer_.try_dequeue(lev);
      if (!ret) {
        continue;
      }

      switch (lev.syslog_triger) {
        case ENABLE:
          syslog.store(true);
          continue;
        case DISABLE:
          syslog.store(false);
          continue;
      }

      if (!quiet_ && lev.level >= default_level_) {
        LogToStdout(lev);
      }

      if (syslog && lev.level >= default_level_) {
        LogToSyslog(lev);
      }
    }
  }
}

Logger::Logger() {
  SysLogEnable(TEMPORARY_DEBUGGING);
  std::thread worker_thread(&Logger::Worker, this);
  worker_thread.detach();
}

void Logger::ResetLogBuffer() {
  while (!IsLogBufferEmpty()) {
    LogEvent lev{"", nullptr, "", 0, SlogLevel::DEBUG, ""};
    auto ret = log_buffer_.try_dequeue(lev);
    if (!ret) {
      continue;
    }
    if (lev.level >= default_level_) {
      LogToSyslog(lev);
    }
  }
}

Logger::~Logger() {  // NOLINT(bugprone-exception-escape)
  stop_worker_ = true;
  ResetLogBuffer();
}