C : сбой приложения с помощью функции прерывания () при ведении журнала

#c #windows #multithreading #mutex #abort

#c #Windows #многопоточность #мьютекс #прервать

Вопрос:

вот мой код, который выполняется в Windows:

Log.h

 #include <iostream>
#include <sstream>
#include <fstream>
#include <shared_mutex>
#include <thread>
#include <iomanip>

class Log {
public:
    static std::ofstream myfile;
    static std::shared_mutex m_smutex;

    static bool isLogEnabled();
    static void close() {
        Log::myfile.close();
    }
    template< typename... Args >
    static void debug(const char* format, Args... args) {
        std::unique_lock<std::shared_mutex> lock(Log::m_smutex);

        if (isLogEnabled()) {
            if (!Log::myfile.is_open()) {
                Log::myfile.open("C:\tmp\log.txt", std::ios_base::app);
            }
            ...
            Log::myfile.close();
        }
        else {
            if (Log::myfile.is_open()) {
                Log::myfile.flush();
                Log::myfile.close();
            }
        }
    }
};
 

Вы можете видеть, что я удалил большую часть кода (…), потому что я сузил проблему.

Log.cpp

 #include <Windows.h>
#include "Log.h"

std::ofstream LogLine::myfile;
std::shared_mutex LogLine::m_smutex;
bool LogLine::isLogEnabled() {
    CHAR regeditPath[MAX_PATH] = { 0 };
    CHAR variable[] = "DEBUG_LOGS";
    GetEnvironmentVariableA(variable, regeditPath, MAX_PATH);

    return GetLastError() == ERROR_ENVVAR_NOT_FOUND ? false : true;
}
 

Процесс должен выполняться всегда, поэтому я открываю и закрываю файл каждый раз, когда что-то регистрирую. Я хочу иметь возможность удалять журналы, даже когда процесс все еще запущен. Возможно, это глупо, потому что может быть флаг, который позволил бы мне удалять журналы, пока файл открыт каким-либо процессом.

Пример использования:

 Log::debug("little test %d", 10);
 

Как вы можете видеть, я использую мьютекс, потому что хочу вызывать debug функцию из разных потоков. Проблема в том, что через некоторое время я получаю код ошибки Abort() has been called , но не могу понять, почему.

P.S Я создал этот код внутри пользовательского поставщика учетных данных, чтобы включить отладку, но я проверяю в Интернете, и кажется, что там никто не использует ведение журнала. Это потому, что это запрещено? Может быть, это причина сбоя?

Комментарии:

1. Не по теме, но GetLastError() == ERROR_ENVVAR_NOT_FOUND ? false : true это многословный GetLastError() != ERROR_ENVVAR_NOT_FOUND

2. Вы пытались перехватывать исключения? Необработанное исключение может быть причиной завершения работы программы. Здесь приведены некоторые другие возможные причины: en.cppreference.com/w/cpp/error/terminate

3. Почему вы так уверены, что регистратор является основной причиной ваших проблем?

4. @molbdnilo Если я удалю все внутри debug функции, кроме блокировки мьютекса, все будет работать нормально

5. Во-первых, вы не проверили, что файл был успешно открыт. Вместо того, чтобы держать его открытым, вы пытались открывать / закрывать его каждый раз, когда записываете в него?