Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 臭名昭著的printf补丁_C++_C_Multithreading_Io - Fatal编程技术网

C++ 臭名昭著的printf补丁

C++ 臭名昭著的printf补丁,c++,c,multithreading,io,C++,C,Multithreading,Io,根据我的经验,在使用printf或任何其他std out日志进行调试时,我遇到了一些奇怪的行为 行为1: 一种常见的情况是,在多线程应用程序中使用printf来查找某些错误发生的原因,然后使用printf突然修复了C printfs的错误,在这些错误中进行了快速调用,从而产生了巨大的输出 在这种情况下,我认为Prttf增加了一些延迟,因此可能有一些低优先级线程没有CPU,所以我开始朝那个方向看。 我关注奇迹printf修复程序的另一个方向是同步,因为我推测对printf的调用虽然是多线程的,但在

根据我的经验,在使用printf或任何其他std out日志进行调试时,我遇到了一些奇怪的行为

行为1:

一种常见的情况是,在多线程应用程序中使用printf来查找某些错误发生的原因,然后使用printf突然修复了C printfs的错误,在这些错误中进行了快速调用,从而产生了巨大的输出

在这种情况下,我认为Prttf增加了一些延迟,因此可能有一些低优先级线程没有CPU,所以我开始朝那个方向看。 我关注奇迹printf修复程序的另一个方向是同步,因为我推测对printf的调用虽然是多线程的,但在系统后面是同步的,因此具有printf的不同线程通过等待彼此完成对I/O缓冲区的写入来实现同步

问题1:我关于第一个场景的两个假设正确吗

问题2:当这种情况发生时,我是否应该考虑其他方向

行为2:

这种情况很少发生,但当遇到这种情况时,即使是高级开发人员也会对自己提出疑问,我真的非常感谢对此的解释

事情是这样的:

代码不起作用。。。清理、编译、运行 代码仍然不起作用,所以您需要添加一个printf来查看为什么要清理、编译和运行 代码开始正常工作。。。。删除先前添加的printf clean、compile、run 代码现在可以正常工作了!!!!!!!!!!抓着头,难以置信地盯着。 在实践中,我多次使用此方法此方法修复CPU可能出现的pe挂接错误:

它实际上工作得非常好,以至于它成为了一个已知的修复,如果它从第一次尝试起就不起作用,你只需重复这个过程,直到它消失

请注意,代码被正确地清理了,它从来没有与旧的编译对象链接的问题

一个最流行的推测是编译后的代码是不同的,出于未知的原因,编译器是否根据某个文件的行(包括空格)具有一些随机性

问题3:是什么原因导致我的这种行为也容易被猜测?尽管代码相同,编译器能否生成不同的程序集

请注意,我所说的项目相当大,有多个静态库,因此,这些行为在小代码段上是不可复制的,尽管我听说场景2也发生在单个文件程序上。

Q1:只需从两个不同的printf中查找交错字符,就可以判断printf是否在幕后同步。如果没有交错,则printf正在同步。我希望这比占用CPU更有可能解决问题

问题2:我会寻找没有适当互斥保护的共享资源

问题3:编译器在优化过程中可能会使用随机数。例如,如果编译器有32个变量和8个寄存器要放入,它可能会掷骰子来决定哪些变量要放入寄存器。您可以通过禁用优化来测试此理论。没有优化,输出应该是一致的。你可以通过比较二进制文件来测试这个理论。

Q1:你可以通过查找两个不同printf的交错字符来判断printf是否在幕后同步。如果没有交错,则printf正在同步。我希望这比占用CPU更有可能解决问题

问题2:我会寻找没有适当互斥保护的共享资源

问题3:编译器在优化过程中可能会使用随机数。例如,如果编译器有32个变量和8个寄存器要放入,它可能会掷骰子来决定哪些变量要放入寄存器。您可以通过禁用优化来测试此理论。没有优化,输出应该是一致的。您可以通过比较二进制文件来测试这一理论。

printf的线程安全性在其他问题中进行了讨论,而且值得注意的是,任何越界函数调用都可能导致写回内存——引用David Butenhoff的话

实际上,大多数编译器不会试图保存 调用外部函数时的全局数据,因为它太 很难知道例程是否能够以某种方式访问 数据的地址

这两个方面都可能意味着由于未能正确使用同步指令而导致的未定义行为可能会通过调用printf以不同程度的可靠掩盖,这取决于您的体系结构、问题的确切性质等

正如您所说,调用printf所花费的时间也会影响比赛条件产生负面影响的频率

关于重新编译程序修复bug:首先,如果bug是间歇性的,在som之前观察它 改变而不是事后不一定能证明任何因果关系。可能还有其他因素,例如由于其他因素(如反病毒扫描、备份计划、其他用户等)导致的系统负载减少。。第二,可执行文件可能不同:编译器可能会注入一些类似于递增版本号或构建时间戳或其他一些系统数据的内容-例如,数据长度的更改可能会对其他数据的对齐产生连锁影响,并产生许多微妙的后果。您的编译器也可能使用地址随机化或其他技术,这可能会再次影响数据对齐,可能会掩盖错误或改变性能。

printf的线程安全性将在其他问题中讨论,而且值得注意的是,任何越位函数调用都可能导致写回内存-引用David Butenhoff的话

实际上,大多数编译器不会试图保存 调用外部函数时的全局数据,因为它太 很难知道例程是否能够以某种方式访问 数据的地址

这两个方面都可能意味着由于未能正确使用同步指令而导致的未定义行为可能会通过调用printf以不同程度的可靠掩盖,这取决于您的体系结构、问题的确切性质等

正如您所说,调用printf所花费的时间也会影响比赛条件产生负面影响的频率


关于重新编译程序修复bug:首先,如果bug最初是间歇性的,那么在某些更改之前而不是之后观察它并不一定证明有任何因果关系。可能还有其他因素,例如由于其他因素(如反病毒扫描、备份计划、其他用户等)导致的系统负载减少。。第二,可执行文件可能不同:编译器可能会注入一些类似于递增版本号或构建时间戳或其他一些系统数据的内容-例如,数据长度的更改可能会对其他数据的对齐产生连锁影响,并产生许多微妙的后果。您的编译器也可能正在使用地址随机或其他技术,这可能会再次影响数据对齐,可能会掩盖错误或改变性能。

请一次只回答一个问题。因此,它意味着可以搜索并将知识带给其他人。看起来您的代码有缺陷,原因是同步错误。您的代码可能基于不可预测的系统行为而运行/失败,这与printf无关。您必须检查共享变量、程序员在代码中所做的任何类型的睡眠或计时假设。@Jens Gustedt我理解您只发布一个问题的意思,但我相信这个问题能给社区带来的一般诀窍是为什么有时您似乎用printf解决问题。我给出了两个场景,也许行为1和行为2有不同的原因,但从一个开发者的角度来看,他刚刚输入了一个printf,然后神奇发生了。请一次只回答一个问题。因此,它意味着可以搜索并将知识带给其他人。看起来您的代码有缺陷,原因是同步错误。您的代码可能基于不可预测的系统行为而运行/失败,这与printf无关。您必须检查共享变量、程序员在代码中所做的任何类型的睡眠或计时假设。@Jens Gustedt我理解您只发布一个问题的意思,但我相信这个问题能给社区带来的一般诀窍是为什么有时您似乎用printf解决问题。我给出了两个场景,也许行为1和行为2有不同的原因,但从一个开发者的角度来看,他刚刚输入了一个printf,然后神奇发生了。