作为chrome c ++和Portable的Super Robust-提示-帮助-评论
我们正在产生一个可移植的代码(win + macOs),我们正在研究如何使代码更加鲁棒,因为它经常崩溃...(通常是溢出或者错误的初始化)
我读到Google Chrome浏览器对每个选项卡都使用了一个进程,因此,如果出现问题,该程序将不会崩溃,只会崩溃。我认为这很整洁,所以我可以尝试一下!
所以我想知道是否有人提供了一些技巧,帮助,阅读列表,评论或者其他可以帮助我构建更多鲁棒的C ++代码的方法(便携式总是更好)。
在同一主题中,我还想知道是否存在用于过程的可移植库(例如boost)?
非常感谢。
解决方案
回答
我们没有提到目标项目是什么;每个选项卡都有一个进程并不一定意味着要有更多的"健壮"代码。无论可移植性如何,我们都应该以编写带有测试的可靠代码为目标,只是阅读有关编写良好的C ++代码的知识:)
至于可移植性部分,请确保从第一天起就在两个平台上进行测试,并确保在解决特定于平台的问题之前,不要编写任何新代码。
回答
我们确实真的不想做Chrome正在做的事情,它需要一个流程管理器,这对于我们想要的内容可能是过大的。
我们应该使用Boost或者其他工具的智能指针进行调查,该工具将为C ++提供引用计数或者垃圾回收。
另外,如果我们经常崩溃,则可能需要考虑使用具有C ++绑定的脚本语言编写应用程序的非性能关键部分。
回答
我们总是可以在程序中添加异常处理程序以捕获此类错误并忽略它们(尽管细节是特定于平台的)……但这几乎是两把利剑。而是考虑让程序捕获异常并创建转储文件以进行分析。
如果程序表现异常,我们对内部状态了解多少?也许崩溃的例程/线程破坏了某些关键数据结构?也许如果我们发现错误并尝试继续操作,那么用户将保存他们正在处理的所有内容并将损坏提交到磁盘吗?
回答
Scott Meyers的"有效C ++"和"更有效的C ++"非常好,而且阅读有趣。
史蒂夫·麦康奈尔(Steve McConnell)的《代码完成》(Code Complete)是包括杰夫·阿特伍德(Jeff Atwood)在内的许多人的最爱。
Boost库可能是一个很好的选择。我工作的一个项目就是使用它们。我自己仅使用WIN32线程。
回答
Chrome的答案更多是关于缓解故障,而不是代码质量。 Chrome做的就是承认失败。
- 更好的质量保证不仅是程序员测试自己的工作。
- 单元测试
- 回归测试
- 阅读其他公司使用的最佳做法。
直言不讳,如果软件经常由于溢出和错误的初始化而崩溃,那么我们将遇到一个非常基本的编程质量问题,这很难解决。这听起来有些杂乱无章,这不是我的意图。我的观点是,错误代码的问题必须是首要考虑(我确定是这样)。诸如Chrome或者Liberty之类的用于处理程序缺陷的异常处理之类的东西只会分散我们对实际问题的注意力。
回答
除了编写更稳定的代码外,这是一个回答我们问题的想法。
无论我们使用的是进程还是线程。我们可以编写一个小型/简单的看门狗程序。然后,其他程序向该看门狗注册。如果任何进程死亡或者线程死亡,则看门狗可以重新启动它。当然,我们需要进行一些测试,以确保我们不会继续重新启动同一越野车线程。即:重新启动5次,然后在5号之后,关闭整个程序并登录到文件/ syslog。
回答
使用调试符号构建应用,然后添加异常处理程序或者配置Dr Watson生成故障转储(运行drwtsn32.exe / i以将其安装为调试器,而无需使用/ i弹出配置对话框)。当应用崩溃时,我们可以通过查看调用堆栈和变量来检查在windbg或者Visual Studio中出了什么问题。
谷歌的符号服务器的更多信息。
显然,我们可以使用异常处理使它更健壮并使用智能指针,但是最好修复错误。
回答
以唯一的退出方式是程序崩溃并且随时可能崩溃的想法来构建它。当我们以这种方式进行构建时,崩溃永远不会/几乎永远不会丢失任何数据。我在一两年前读过一篇有关它的文章。可悲的是,我没有链接。
将其与某种故障转储结合使用,并通过电子邮件将其发送给我们,以便我们解决问题。
回答
我建议我们编译一个Linux版本并在Valgrind下运行它。
Valgrind将跟踪内存泄漏,未初始化的内存读取以及许多其他代码问题。我强烈推荐它。
回答
我同意Torlack。
错误的初始化或者溢出是代码质量低下的标志。
Google之所以这样做,是因为有时无法控制在页面中执行的代码(由于错误的插件等)。因此,如果我们使用的是低质量的插件(它确实会发生),那么Google解决方案可能会很适合我们。
但是,没有插件而崩溃的程序通常编写得很差,或者非常非常复杂,或者非常旧(并且浪费了大量的维护时间)。我们必须停止开发,并调查每一次崩溃。在Windows上,使用PDB(程序数据库)编译模块,并且每次崩溃时,都将调试器添加到它。
我们还必须添加内部测试。避免模式:
doSomethingBad(T * t) { if(t == NULL) return ; // do the processing. }
这是非常糟糕的设计,因为错误在那里,而我们这次只是避免它。但是没有此防护的下一个功能将崩溃。最好尽早崩溃以更接近错误。
相反,在Windows上(MacOS上必须有类似的API)
doSomethingBad(T * t) { if(t == NULL) ::DebugBreak() ; // it will call the debugger // do the processing. }
(不要直接使用此代码...将其放入定义中,以避免将其交付给客户端...)
我们可以选择适合自己的错误API(异常,DebugBreak,assert等),但是可以在代码知道有问题时立即停止使用。
尽可能避免使用C API。使用C ++习惯用法(RAII等)和库。
等等..
附注:如果我们使用例外(这是一个不错的选择),请不要将其隐藏在陷阱中。我们只会使问题变得更糟,因为那里存在错误,但是该程序将尝试继续运行,并且有时可能会崩溃,同时破坏它所碰到的所有内容。
回答
我已经开发了许多多平台C ++应用程序(最大的是150万行代码,并在7个平台上运行-AIX,HP-UX PA-RISC,HP-UX Itanium,Solaris,Linux,Windows,OS X)。实际上,帖子中有两个完全不同的问题。
- 如果不是很明显,请使用调试器找出导致崩溃的原因。
- 使用boost和类似的库。特别是,指针类型将避免内存泄漏。
- 即使需要更多工作,也应尽可能使用标准(例如ANSI与gcc / MSVC,POSIX线程与Unix特定的线程模型等)。最小化特定于平台的代码意味着更少的整体工作和更少的学习API。
- 隔离,隔离,隔离。尽可能避免在不同平台上使用内联#ifdef。而是将平台特定的代码粘贴到其自己的标头/源/类中,并使用构建系统和#includes获得正确的代码。这有助于保持代码的清洁和可读性。
- 尽可能使用C99整数类型,而不要使用" long"," int"," short"等-否则,当我们从32位平台迁移到64位平台并且long突然改变时,它会咬住我们从4个字节到8个字节。而且,如果将其写入网络/磁盘/等,那么我们将遇到平台之间的不兼容性。
就个人而言,我会先稳定代码(不添加任何其他功能),然后再处理跨平台问题,但这取决于我们。请注意,Visual Studio有一个出色的调试器(仅出于这个原因,上面提到的代码库已移植到Windows)。
回答
经过15多年的Windows开发,最近我写了我的第一个跨平台C ++应用程序(Windows / Linux)。这是如何做:
- STL
- 促进。特别是文件系统和线程库。
- 基于浏览器的UI。该应用程序执行HTTP,UI由XHTML / CSS / JavaScript(Ajax样式)组成。这些资源嵌入在服务器代码中,并在需要时提供给浏览器。
- 大量的单元测试。不完全是TDD,但是很接近。这实际上改变了我的发展方式。
我将NetBeans C ++用于Linux构建,并立即拥有了完整的Linux端口。