我们正在生成一个可移植的代码(win+macOs),我们正在研究如何使代码更加鲁棒,因为它经常崩溃......(通常溢出或错误的初始化):-(

我读到 Google Chrome 浏览器对每个选项卡都使用一个进程,因此如果出现问题,程序不会完全崩溃,只会崩溃该选项卡。我认为这很简洁,所以我可以尝试一下!

所以我想知道是否有人有一些提示、帮助、阅读列表、评论或可以帮助我构建更多鲁布斯特 C++ 代码的东西(便携总是更好)。

在同一主题中,我还想知道是否有用于进程的可移植库(如 boost)?

非常感谢。

有帮助吗?

解决方案

我开发过许多多平台 C++ 应用程序(最大的代码有 150 万行,运行在 7 个平台上 - AIX、HP-UX PA-RISC、HP-UX Itanium、Solaris、Linux、Windows、OS X) 。实际上,您的帖子中有两个完全不同的问题。

  1. 不稳定。你的代码不稳定。修理它。

    • 使用单元测试在逻辑问题杀死你之前发现它们。
    • 如果崩溃的原因不明显,请使用调试器找出原因。
    • 使用 boost 和类似的库。特别是,指针类型将帮助您避免内存泄漏。
  2. 跨平台编码。

    • 再次强调,如果可能的话,请使用专门为此设计的库。特别是对于任何 GUI 位。
    • 使用标准(例如ANSI 与 gcc/MSVC、POSIX 线程与 Unix 特定线程模型等)尽可能多,即使它需要更多的工作。最小化特定于平台的代码意味着更少的整体工作以及更少的需要学习的 API。
    • 隔离,隔离,隔离。尽可能避免针对不同平台使用内联 #ifdef。相反,将特定于平台的代码粘贴到其自己的标头/源/类中,并使用您的构建系统和#includes 来获取正确的代码。这有助于保持代码的整洁和可读性。
    • 如果可能,请使用 C99 整数类型,而不是“long”、“int”、“short”等,否则当您从 32 位平台迁移到 64 位平台并且 long 突然发生变化时,它会咬住您从 4 字节到 8 字节。如果将其写入网络/磁盘/等,那么您将遇到平台之间的不兼容问题。

就我个人而言,我会首先稳定代码(不添加任何更多功能),然后处理跨平台问题,但这取决于您。请注意,Visual Studio 有一个出色的调试器(正是出于这个原因,上面提到的代码库被移植到 Windows)。

其他提示

Chrome 的答案更多的是关于故障缓解,而不是代码质量。Chrome 所做的事情就是承认失败。

  1. 更好的质量保证不仅仅是程序员测试自己的工作。
  2. 单元测试
  3. 回归测试
  4. 阅读其他公司使用的最佳实践。

坦率地说,如果您的软件经常由于溢出和错误的初始化而崩溃,那么您就会遇到一个非常基本的编程质量问题,并且该问题很难修复。这听起来很杂乱而且刻薄,这不是我的意图。我的观点是,不良代码的问题必须是您最关心的问题(我确信确实如此)。像 Chrome 或自由使用异常处理来捕获程序缺陷之类的东西只会分散你对真正问题的注意力。

你没有提到目标项目是什么;每个选项卡都有一个进程并不一定意味着更“健壮”的代码。无论可移植性如何,您都应该致力于通过测试编写可靠的代码 - 只需阅读有关编写良好的 C++ 代码的内容即可:)

至于可移植性部分,请确保从第一天起就在两个平台上进行测试,并确保在解决特定于平台的问题之前不会编写新代码。

你真的、真的不想做 Chrome 正在做的事情,它需要一个进程管理器,这对于你想要的东西来说可能有点过分了。

您应该研究使用 Boost 中的智能指针或其他为 C++ 提供引用计数或垃圾收集的工具。

或者,如果您经常崩溃,您可能需要考虑使用具有 C++ 绑定的脚本语言编写应用程序的非性能关键部分。

斯科特·迈耶斯的 有效的C++更有效的 C++ 非常好,读起来很有趣。

史蒂夫·麦康奈尔 代码完成 是许多人的最爱,包括杰夫·阿特伍德。

Boost 库可能是一个很好的选择。我工作的一个项目就使用它们。我自己只使用过WIN32线程。

我同意托拉克的观点。

错误的初始化或溢出是代码质量差的迹象。

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(例外,调试,断言等),但请使用它来停止代码知道有问题的那一刻。

尽可能避免使用 C API。使用 C++ 习惯用法(RAII 等)和库。

ETC..

附:如果您使用异常(这是一个不错的选择),请不要将它们隐藏在 catch 中。你只会让你的问题变得更糟,因为错误在那里,但程序会尝试继续,有时可能会崩溃,并同时破坏它接触到的任何东西。

您始终可以向程序添加异常处理以捕获这些类型的错误并忽略它们(尽管详细信息是特定于平台的)...但这是一把两刃剑。相反,请考虑让程序捕获异常并创建转储文件进行分析。

如果您的程序以意想不到的方式运行,您对内部状态了解多少?也许崩溃的例程/线程已经损坏了一些关键数据结构?也许如果您发现错误并尝试继续,用户将保存他们正在处理的任何内容并将损坏提交到磁盘?

除了编写更稳定的代码之外,这里还有一个可以回答您的问题的想法。

无论您使用的是进程还是线程。您可以编写一个小型/简单的看门狗程序。然后你的其他程序向该看门狗注册。如果任何进程死亡,或者线程死亡,看门狗可以重新启动它。当然,您需要进行一些测试,以确保不会不断重新启动同一个有问题的线程。IE:重新启动它 5 次,然后在第 5 次之后关闭整个程序并记录到文件/syslog。

使用调试符号构建您的应用程序,然后添加异常处理程序或配置 Dr Watson 来生成故障转储(运行 drwtsn32.exe /i 将其安装为调试器,无需 /i 来弹出配置对话框)。当您的应用程序崩溃时,您可以通过查看调用堆栈和变量来检查 Windbg 或 Visual Studio 中出错的位置。

谷歌搜索符号服务器以获取更多信息。

显然,您可以使用异常处理来使其更加健壮并使用智能指针,但修复错误是最好的。

我建议你编译一个linux版本并在下面运行它 瓦尔格林德.

Valgrind 将跟踪内存泄漏、未初始化的内存读取和许多其他代码问题。我强烈推荐它。

经过超过 15 年的 Windows 开发,我最近编写了我的第一个跨平台 C++ 应用程序 (Windows/Linux)。就是这样:

  • STL
  • 促进。特别是文件系统和线程库。
  • 基于浏览器的用户界面。该应用程序“使用”HTTP,其 UI 由 XHTML/CSS/JavaScript(Ajax 样式)组成。这些资源嵌入在服务器代码中,并在需要时提供给浏览器。
  • 大量的单元测试。不完全是 TDD,但也很接近。这实际上改变了我的发展方式。

我使用 NetBeans C++ 进行 Linux 构建,并且很快就拥有了完整的 Linux 移植版。

构建它的想法是,退出的唯一方法是程序崩溃,并且它随时可能崩溃。当您以这种方式构建它时,崩溃将永远不会/几乎永远不会丢失任何数据。我在一两年前读过一篇关于它的文章。可悲的是,我没有它的链接。

将其与某种故障转储结合起来,并通过电子邮件发送给您,以便您可以解决问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top