将const char *传递给构造函数会给出null

时间:2017-12-10 17:03:39

标签: c++

我试图制作一个简单的记录器来记录文件,以便为我提供有关我的程序的调试信息。我想避免使用图书馆,所以我自己制作一个图书馆。

logging.cpp

#include <string.h> // String stuff
#include <time.h>   // Time

#include "logging.hpp"

// Cathooks main logging util
CatLogger g_CatLogging("/tmp/nekohook.log");
//CatLogger g_CatLogging;

CatLogger::CatLogger(const char* _file_path, bool _ptime) : ptime(_ptime) {
     file_path = _file_path;
}
CatLogger::~CatLogger() {   fclose(log_handle); }

void CatLogger::log(const char* fmt, ...) {

    // Basicly an init, because this cant be done on construct
    if (log_handle == nullptr) {
        log_handle = fopen(file_path, "w");
    }

    // Print our time if needed
    if (ptime) {
        // Get our time
        time_t current_time = time(0);
        struct tm* time_info = localtime(&current_time);

        // print it to a string
        char timeString[10];
        strftime(timeString, sizeof(timeString), "%H:%M:%S", time_info);

        // Print the time into the log
        fprintf(log_handle, "%% [%s] ", timeString);
    }

    // Get the string we want to log
    char buffer[1024];
    va_list list;
    va_start(list, fmt);
    vsprintf(buffer, fmt, list);
    va_end(list);

    // Write our log to the file
    fprintf(log_handle, "%s\n", file_path, buffer);
    fflush(log_handle);

    // Push result var to a console here, if i ever make a console api
}

logging.hpp

#include <stdarg.h> // ... arg
#include <stdio.h> // fopen(), fprint(), fputs()

class CatLogger {
public:
  CatLogger(const char* _file_path, bool _ptime = false);
  ~CatLogger();
  void log(const char* fmt, ...); // Use to log with
private:
  FILE* log_handle = 0; // Handle used to log to files with
  const char* file_path; // Path to log file
  const bool ptime; // Whether to print time
};

// Use this to log
extern CatLogger g_CatLogging;

当我使用日志功能时,它会失败。我不知道为什么。我做了一个虚拟函数,在运行时从输入的gdb获取信息时崩溃。我将file_path变量输入其中并返回0x0。我不确定为什么会发生这种情况,我已经制作了一个独立于库的样本可执行文件,我使用它并且它可以完美地工作。这可能是由于我链接库的方式还是缺少?

这是我正在处理的库,它直接指向日志文件。 https://github.com/oneechanhax/nekohook/blob/master/src/util/logging.cpp

由于fopen没有返回文件句柄,它在fprintf()上崩溃了,因为const char *由于某种原因没有被传递。

请告诉我一种方法来调试这个或者指出哪里出了问题,因为我不知道为自己做了什么。

编辑: 如果我在CatLogger::log

中替换以下内容
if (log_handle == nullptr) {
    log_handle = fopen(file_path, "w");
}

使用以下

if (log_handle == nullptr) {
    log_handle = fopen("/tmp/nekohook.log", "w");
}

它现在有效,但我现在无法更改其他日志类的日志位置......

EDIT2: 这是一些调试信息。不知怎的,const char *没有被保存到类中。这是我的主要问题......

example

构造后,字符串可能变为null ...

2 个答案:

答案 0 :(得分:0)

有很多潜在的错误。

if (log_handle == nullptr) {
    log_handle = fopen(file_path, "w");
    if(!log_handle) {
        perror("File opening failed"); // check your console output.
        return EXIT_FAILURE;
    }
}


// Get the string we want to log
char buffer[1024];
va_list list;
va_start(list, fmt);
vsprintf(buffer, fmt, list); // potential segmentation fault
va_end(list);

使用此代替

int vsnprintf( char* buffer, std::size_t buf_size, const char* format, va_list vlist ); //  (since C++11)

而且程序是多线程的。

答案 1 :(得分:-1)

这是一个静态初始化命令惨败的演员阵容,其中const char *在调用函数之前不会被初始化。 解决方案是首先将文件链接与其他文件进行比较,然后对象才能正常工作。