C ++守护进程日志功能无法写入文件(分段错误?)

时间:2014-06-02 03:44:43

标签: c++ c linux sockets logging

首先,感谢您花时间阅读我的困境。

用它;

我是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变量以保持全局。我的想法是,这比打开文件流&gt;&gt;追加消息&gt;&gt;关闭流更好地调用日志函数。它将记录一次,但它似乎再也不会这样做。我不相信它与全球&#34;我保持变量,但我可能会弄错。

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);

我相信你能在这里看到我的困惑。任何帮助/想法都表示赞赏。谢谢!

1 个答案:

答案 0 :(得分:2)

getDateTime()您的返回本地变量buf中,这是不正确的。作为局部变量,它将在堆栈上,因此一旦函数返回,内容可能无效。 您应该为该缓冲区分配新内存。

另外,使用gdb(或其他调试器)来查看segfault的位置。