mardi 5 décembre 2017

Segmentation fault (core dumped) using stringstream in multithread application

I trying do simple threadsafe looger, which print messages to console.

// Test function for check logger. It is work
void test(double& diff)
{
  std::vector<double> result;
  for( int counter = 0; counter < 100000; ++counter)
  {
    result.push_back(clock());

    std::string text = "counter = ";
    text.append(std::to_string(counter));
    LOG_MESSAGE(text); //<-- Correct log..
  }
  diff = clock() - result.front();

}

int main(int argc, char** argv)
{
  double time2;
  double time1;
  std::vector<double> timerResult;
  std::vector<std::thread> threadVector;

  time1 = clock();
  for(int i = 0; i < 5; ++i) //<-- Create 5 thread of test function
  {
    timerResult.push_back(0);
    threadVector.push_back(std::thread(test, std::ref(timerResult[i])));
  }
  for(std::thread& t : threadVector)
    t.join();
  time2 = clock(); //<-- Threads is finished

  double res = 0;
  for(double tRes : timerResult)
     res += tRes;
  res = res / static_cast<double>(CLOCKS_PER_SEC);

  std::string message; //<-- Generate final message
  message.append("Timer: ")
      .append(std::to_string((time2 - time1) / (double)CLOCKS_PER_SEC))
      .append(" - thread timer: ")
      .append(std::to_string(res));

  LOG_MESSAGE(message); //<-- Crash inside!!    

  return 0;
}

Logger is good working in threads. But when I try log in main() function that call SIGSEGV signal in destructor of std::ostringstream (in function of construct log message):

static Logger::Core logger; //<--Global Logger variable

#define LOG_MESSAGE( TEXT ) logger.addNoteInLog(TEXT) //<-- Define for log message

void Core::addNoteInLog(const Message &message) //<-- threadsafe log function
{  
  std::string text;
  message.generateString(text); //<-- [Crash here] generate log message
  g_lock.lock();
  std::cout << text;
  g_lock.unlock();
}

void Message::generateString(std::string& text) const
{
  text.clear();
  tm *ltm = localtime(&mDate);

  std::ostringstream data; //<-- [Crash here] function is finished, but cannot destruct object.
  data << 1900 + ltm->tm_year << "/"
       << 1 + ltm->tm_mon << "/"
       << ltm->tm_mday << "\t";
  data << "[INF] - ";
  data << std::this_thread::get_id() << " - "
       << mMessage << "\n";

  text = data.str();
}

I dont understand why logger in threads is work, but in main() function crashed. Using the exclusion method, I found out when the error is occurred:

  • when I use 5 (or more) threads
  • when test function is not empty
  • when in generateString use stringstream or ostringstream or string.append() (in last case application crash in std::string destructor in same place)

What say debugger in QtCreater.

Build in Ubuntu OS, gcc version 5.4.0, compilation flags: -std=c++17 -pthread -Wall

This is my git repository with error.

Aucun commentaire:

Enregistrer un commentaire