程序崩溃时流的C++行为
behavior of C++ ofstream in the event of program crash
我正在尝试调试一个运行时错误,该错误导致我的程序在执行过程中冻结。我创建了一个日志系统,在执行过程中编写一个简单的日志文本文件。
我只需使用带有std::string类型消息的ofstream对象的流插入(<<)运算符就可以将信息写入日志文件。
void foo(){
// ... Code block 1 ...
// myLogger.Write (timestamp, "Code block1 successfully executed");
// ... Code block 2 ... PROGRAM FREEZE AND CRASH!
}
我的问题是:假设我的程序冻结了,我需要从任务管理器中终止它的进程,我能相信我的日志系统在崩溃点之前已经可靠地写入了所有消息吗?
或者,参考上述代码,如果代码块2导致我的程序冻结,我能相信"代码块1成功执行"消息在任何情况下都会出现在我的日志文件中吗?
附言:我在Windows上,我感到担心的原因是,在某些奇怪的情况下,我不完全信任操作系统在文件权限方面的行为。我的程序确实有对该文件的读/写权限,但我不知道在崩溃期间会发生什么奇怪的事情。也许我只是多疑,如果是,请告诉我。
有没有更好的方法来检测崩溃发生在哪个代码块中?
"我能相信"代码块1成功执行"消息在任何情况下都会出现在我的日志文件中吗?"
不,当执行该语句时,您不能相信任何东西最终都会写入日志文件,而您的程序实际上处于某种异常状态。
由于flush()
调用隐含了要写入的行,所以机会会更好,但仍然无法保证。这取决于您的程序所满足的特殊条件。
考虑一种情况,您的程序由于未定义的行为而崩溃,该行为意外地弄乱了Logger
类实例使用的缓冲区或数据中的某些内容。此外,如果您遇到了内存不足的情况,则无法保证后续执行的代码,即使它被正确捕获。
另请注意:
多线程应用程序上下文中的日志记录系统通常不需要同步刷新。flush()
的同步调用可能会改变实际应用的线程的行为,并隐藏/模糊竞争条件,这些条件将在日志记录关闭后立即出现
如果您想确保您的文本已写入日志文件,您需要使用std::endl,它会执行一次刷新,写入用于输出设备的任何缓冲区。
例如:
std::cout << "write me!n"; // no flush
std::cout << "write me!" << std::endl; // buffer flushed
- 理解boost::asio-async_read在无需读取内容时的行为
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- arr[-1]在c++中的奇怪行为
- 继承期间显示未知行为的子类
- 如何在c++中使用引用实现类似python的行为
- G锁定铸造到基础上会释放模拟行为
- 在C++中对T*类型执行std::move的意外行为
- std::当在256字节边界上写入整数时,流的奇怪行为
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 奇怪的构造函数行为
- 重载运算符new[]的行为取决于析构函数
- 不同语言中相同代码的不同行为
- 处理除以零会导致<csignal>意外行为
- 试图理解类对象的行为
- c++11评估顺序(未定义的行为)
- 从结构寻址时,MMAP变量的行为很奇怪
- 我可以做些什么来消除或最小化这种将提供相同功能和行为的代码重复
- 读取文件时运行时的未知行为
- strncpy之后的char数组的错误行为
- 此增量后语句是否会导致未定义的行为?