簡體   English   中英

C ++守護程序日志功能未寫入文件(分段錯誤?)

[英]C++ Daemon log function not writing to file (Segmentation Fault?)

首先,非常感謝您抽出寶貴的時間閱讀我的困境。

繼續下去;

我對c / c ++領域很陌生,但是我對其他語言有很多經驗。 我正在使用多客戶端套接字服務器,以后將用於各種用途。 作為我第一次使用c ++的實際工作,我遇到了一個問題。 基本上,我正在創建一個守護程序,它會自然地監聽客戶端,因為我從環境中刪除了該過程,因此您可以看到我可能希望如何記錄此小守護程序的輸出。 所以我設計了這個記錄器:

核心/ log.cpp

#include <iostream>
#include <string>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <fstream>

//define log levels
#define LOG_INFO  0
#define LOG_WARN  1
#define LOG_ERROR 2
#define LOG_CRIT  3
#define LOG_DEBUG 4

//Define functions
const std::string getDateTime();
void log(int, std::string);

//log file stream
std::ofstream logf;


const std::string getDateTime() {
 time_t    now = time(0);
 struct    tm tstruct;
 char      buf[80];
 tstruct = *localtime(&now);
 strftime(buf, sizeof(buf), "%Y.%m.%d_%H.%M.%S", &tstruct);
 return buf;
}

void log(int type, std::string message) {
 if (!logf.is_open()) {
  //attempt to open log file
  logf.open(("/var/log/dosocket/" + getDateTime() + ".log").c_str(), std::ios_base::app);
  if (!logf.is_open()) {
   //Failed to open
   std::cout << "FATEL: Failed to open log file!\n";
   exit(1);
  }
  //log type
  if(type == LOG_WARN) {
   logf << getDateTime() << " [WARNING]: " << message << "\n";
  }else if(type == LOG_INFO) {
   logf << getDateTime() << " [INFO]: " << message << "\n";
  }else if(type == LOG_DEBUG) {
   logf << getDateTime() << " [DEBUG]: " << message << "\n";
  }else if(type == LOG_ERROR) {
   logf << getDateTime() << " [ERROR]: " << message << "\n";
  }else if(type == LOG_CRIT) {
   logf << getDateTime() << " [CRITICAL]: " << message << "\n";
  }else{
   logf << getDateTime() << " [UNKNOWN]: " << message << "\n";
  }
 }
}

我在頂部保留了logf變量以使其保持全局。 我的想法是,這比打開文件流>>附加消息>>關閉流更好。 它只會記錄一次,但似乎再也不會記錄一次。 我不認為我保留的“全局”變量有問題,但我可能會誤會。

socket.cpp(已修改)

 pid_t pid, sid;

 log(LOG_INFO, "Entering daemon"); //<-- line is logged
 //fork 1
 pid  = fork(); // Only doing one fork as well
 if (pid < 0) {
  log(LOG_CRIT, "fork() failed");
  exit(EXIT_FAILURE);
 }
 if (pid > 0) {
  log(LOG_INFO, "fork() complete, parent exited"); <-- is logged if entering daemon is commented out
  exit(EXIT_SUCCESS);
 }


 //umask & setsid
 if ((sid = setsid()) < 0) {
  exit(EXIT_FAILURE);
 }
 umask(0);

 //chdir
 if ((chdir("/")) < 0) {
  exit(EXIT_FAILURE);
 }

 close(STDIN_FILENO);
 close(STDOUT_FILENO);
 close(STDERR_FILENO);

 FILE* stdlog = fopen("/var/log/dosocket/std.log", "a+");

 dup2(fileno(stdlog), STDOUT_FILENO);
 dup2(fileno(stdlog), STDERR_FILENO);
 //testing bit to try and log std file descriptors.

//main process
 int sockfd, newsockfd, portno;
 socklen_t clilen;
 char buffer[256];
 struct sockaddr_in serv_addr, cli_addr;
 int n;
 pid_t clipid;

 //create the socket
 log(LOG_INFO, "calling socket()"); <-- not logged
 sockfd = socket(AF_INET, SOCK_STREAM, 0);

我確定您可以在這里看到我的困惑。 任何幫助/想法表示贊賞。 謝謝!

getDateTime()返回的本地變量buf不正確。 作為局部變量,它將在堆棧上,因此一旦函數返回,內容可能無效。 您應該為該緩沖區分配新的內存。

另外,使用gdb(或其他調試器)來查看segfault。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM