首先,感谢您花时间阅读我的困境。
用它;
我是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);
我相信你能在这里看到我的困惑。任何帮助/想法都表示赞赏。谢谢!
答案 0 :(得分:2)
在getDateTime()
您的返回本地变量buf
中,这是不正确的。作为局部变量,它将在堆栈上,因此一旦函数返回,内容可能无效。
您应该为该缓冲区分配新内存。
另外,使用gdb(或其他调试器)来查看segfault的位置。