C++ 游戏服务器开发常用工具介绍

在软件开发过程中需要使用的工具类型实属众多,从需求建模到软件测试,从代码编译到工程管理,这些工具都对项目有着不可替代的作用。庄子有云,“吾生也有涯,而知也无涯,以有涯随无涯,殆已”。代入到项目开发中就是说,如果对知识点无差别的全面攻击,不仅会导致所学甚泛却无一深入的尴尬,也会占用太多的有效时间从而影响项目进度。作为一个C++游戏服务器开发者来说,我们时刻肩负着线上游戏开发和维护任务,可以优先学习对自己工作最常用且最重要的,解决实际问题最为紧迫。本文对一些常用工具给出了介绍和指引,包括调试器、内存泄露检查工具、代码覆盖工具、抓包工具、性能分析工具、静态代码检查工具、high cpu分析工具以及Lua脚本开发工具,旨在帮助经验不足的C++服务器开发工程师解决代码问题和提升代码质量,从而提升自己和团队的工作效率。

1 调试器

通常,调试(debugging)是指发现缺陷并改正的过程。如果代码中存在缺陷,我们首先要识别造成缺陷的根本原因(root cause),这个过程就称作调试。找到根本原因后,就可以修正缺陷。在软件开发周期中,调试并修正缺陷的时间可能远多于写代码的时间,有得心应手的工具可以节省调试时间无疑是非常重要的。

在linux下一般使用 GDB(GNU symbolic debugger)进行调试,它是一个受通用公共许可证即GPL保护的自由软件,可以调试多种语言。

用法参考:http://www.gnu.org/software/gdb/
下载地址:http://ftp.gnu.org/gnu/gdb/

对GDB有一定了解的人会发现,GDB对STL的调试比较困难,这里推荐一个GNU提供的调试工具 ,使用python实现,支持C++11特性。

用法参考:http://sourceware.org/gdb/wiki/STLSupport
下载地址:svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python

同时你可以使用一些前端工具如XXGDB,DDD等。它们都有图形化界面,因此使用更方便。也可以使用WinGdb,利用Visual Studio的IDE进行Linux远程调试。

下载地址:http://www.wingdb.com/

另外,如果你再程序中发现了和系统调用相关的问题,使用strace可以快速定位。strace能够跟踪进程执行时的系统调用和所接收的信号,并将相关调用信息放在输出流中。

下载地址:http://sourceforge.net/projects/strace/

在windows下一般使用 Visual Studio自带的调试工具,除此以外,也推荐使用WinDbg,它是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件。

用法参考:http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
下载地址:http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx

2 内存泄露检查工具

内存泄漏(memory leak)是很多C++代码中比较容易出现的问题。内存泄漏也称作“存储渗漏”,意思是说当你用动态存储分配函数动态开辟了一块内存空间,在使用完毕后忘记了释放,导致这块空间在进程结束以前都不再可用。偶尔发生的内存泄漏可能并不严重,但是以下情况会导致严重的系统故障:

  • 程序运行后置之不理,并且随着时间的流失消耗越来越多的内存;
  • 程序能够请求未被释放的内存(比如共享内存),甚至是在程序终止的时候;
  • 泄漏在发生在操作系统内部或者系统关键驱动中;
  • 内存非常有限,比如在嵌入式系统或便携设备中;
    我们可以使用内存泄露检查工具在测试环境下监视进程的运行并获取详细测试报告,然后对有内存泄漏的代码段各个击破,从而规避严重故障的风险。

在Linux环境下推荐使用valgrind,它是一款用来定位c/c++程序中内存相关错误的工具集,功能包括内存泄漏、使用未初始化的内存、读/写已释放的内存、读/写内存越界等
用法参考: http://valgrind.org/docs/manual/manual.html
下载地址:http://valgrind.org/downloads/current.html

Windows Leaks Detector是下专门用于解决windows环境下内存泄漏的工具,基于Win API调用钩子实现,能够探测任何Win32应用程序中的资源泄漏(内存,句柄等)。
用法参考:http://winleak.sourceforge.net/
下载地址:http://sourceforge.net/projects/winleak/

如果你安装了WinDbg, umdh工具也会被附带安装,和windbg.exe在同一级目录下。轻量级的umdh也可以用于定位内存泄露,使用起来非常简单。
用法参考:https://msdn.microsoft.com/en-us/library/windows/hardware/ff558947(v=vs.85).aspx

3 代码覆盖工具

代码覆盖率(code coverage rate)是反映测试用例对被测软件覆盖程度的重要指标,也是衡量测试工作进展情况的重要指标。在代码逻辑比较复杂的情况下,测试工作往往只能覆盖到显而易见的逻辑分支,而更多的深层次的逻辑分支则不容易被测试人员发现。为了保证测试的覆盖率,有些开发人员会尝试协助测试人员写出所有的测试用例,这不仅会牺牲大量的宝贵的开发时间,同时也拥有一定的难度,最重要原因就是因为测试难以量化。而代码覆盖工具就是用来量化代码测试的覆盖率,让测试人员可以直观的发现那些没有覆盖到的代码分支。

在Linux环境下推荐使用gcov,这是一个命令行控制台程序,随gcc一同发布,通常在/usr/bin/gcov路径下可以找到。
用法参考:https://gcc.gnu.org/onlinedocs/gcc/Gcov.html

在windows环境下推荐使用OpenCppCoverage,代码开源并且使用简单,只要有保留有pdb文件即可在运行时插桩进行测试,导出结果是一个有颜色标记的源码拷贝,对开发者来说相当直观。
用法参考:https://opencppcoverage.codeplex.com/documentation
下载地址: https://opencppcoverage.codeplex.com/

4 性能分析工具

软件的性能是软件质量的重要考察点,不论是服务端还是客户端程序,性能都是用户体验的关键,主要包括性能表现和稳定性两个方面。解决性能问题最基本的方法是开发者对代码进行review,同时也可以使用工具对代码进行性能分析(profiling)。

在Linux环境下推荐使用gprof,它是gnu binutils工具之一,默认情况下Linux系统中都带有这个工具,它能够精确地给出函数被调用的时间和次数和函数调用关系。
用法参考: http://www.cs.utah.edu/dept/old/texinfo/as/gprof_toc.html

在windows环境下可以使用visual studio自带的profiling工具,工具的界面入口 Config Properties -> Linker -> Advanced -> Profile,但是需要visual studio2008以上版本。如你使用的是更早的版本,可以使用C++ Profiler。
下载地址:http://www.semdesigns.com/Products/Profilers/CppProfiler.html

另一款颇有口碑的软件是AQTime,它能够收集程序运行时关键的性能信息和内存/资源分配信息,并提交概要报告和详细报告,还提供所有的程序优化处理工具,囊括了自定义过滤器、图形化的调层次结构一直到源代码浏览等内容,是完整的性能和调试工具集,功能非常强大。
用法参考:http://www.codework-solutions.com/testing-tools/aqtime-java-profiling/
下载地址: http://www.automatedqa.com/products/aqtime/index.asp

5 网络抓包工具

抓包(packet capture)就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作,也用来检查网络安全,也经常被用来进行数据截取等。在项目开发过程中,特别是B/S或C/S模型的项目中,服务器和客户端中间的交互相关问题很难定位,需要额外看懂很多源码,并且调试起来相当费时。网络抓包工具的设计目的就在于此,对于协议次数、协议顺序、协议内容是否都与编码和设计的预期一致这类问题,可以直接获取到二进制的tcp或者udp流的内容并导出到文本,方便开发者解决复杂交互问题。

在Linux环境下最常使用的是Tcpdump,它可以将网络中传送的数据包的“头”完全截获下来提供分析,支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助去掉无用的信息。
用法参考:http://www.tcpdump.org/
下载地址: http://www.tcpdump.org/#latest-release

在windows下最常用的是wireshark,它使用WinPCAP作为接口,直接与网卡进行数据报文交换,同样具有语法过滤功能。
用法参考:https://www.wireshark.org/#learnWS
下载地址:https://www.wireshark.org/#download

6 静态代码检查工具

静态代码检查(static code check)是指使用自动化工具软件对程序源代码进行检查,以分析程序行为的技术,应用于程序的正确性检查、安全缺陷检测、程序优化等。静态代码检查承诺无需开发人员费劲就能找出代码中已有的缺陷。当然,这些承诺并不是一定能兑现。尽管如此,好的静态分析工具仍然是工具箱中的无价之宝,因为它可以不需要运行就可以帮助你检查代码中的潜在风险。

在Linux环境下推荐使用cppcheck,它作为编译器的一种补充检查,cppcheck对产品的源代码执行严格的逻辑检查,包括自动变量检查、数组的边界检查、class类检查、过期的函数调用检查、常内存使用、释放检查、内存泄漏检查、操作系统资源释放检查、异常STL函数使用检查、代码格式错误、性能因素检查这些类型,覆盖范围非常全面。
用法参考:http://sourceforge.net/p/cppcheck/wiki/Home/
下载地址:http://cppcheck.sourceforge.net/

在windows环境下可以使用PC-Lint,功能可媲美cppcheck。
下载地址:http://www.gimpel.com/html/pcl.htm

由于PC-Lint是商业化的软件,不便于大家学习和使用,但是如果你只需要使用C语言进行开发,可以使用开源程序静态分析工具splint。
下载地址:http://www.splint.org/

另外,介绍一个Google使用的C++代码规范检查工具Cpplint。如果你当前也使用Google C++代码规范,那么你很有必要使用Cpplint,它是一个python脚本,使用简单的命令即可校验你的代码写是否符合规范。它支持linux和windows两种环境,并可以嵌入visual studio。
下载地址:https://github.com/google/styleguide

7 High CPU监控工具

High CPU监控工具可以用于监控和定位CPU占用比较高的进程和线程,获取当时的堆栈信息来定位代码段,相比profiling工具更加直观。

ProcDump是一个监视 CPU峰值命令行工具,适用于windows环境,以attach的方式进行使用,当达到预设的CPU峰值时会生成当时的转储文件。 ProcDump还可以对悬窗(hung window)和未处理异常(unhandled exception)进行监控,并可以基于系统性能计数器的值转储。它也可作为一般进程转储实用工具,可以在其他脚本(比如python)中嵌入。
下载地址:https://technet.microsoft.com/en-us/sysinternals/bb896653/

Windows环境下另一个推荐使用的工具是process explorer,它是由Sysinternals开发的Windows系统和应用程序监视工具,不仅结合了Filemon(文件监视器)和Regmon(注册表监视器)两工具的功能,还增加了多项重要的增强功能。包括稳定性和性能改进、强大的过滤选项、修正的进程树对话框(增加了进程存活时间图表)、可根据点击位置变换的右击菜单过滤条目、集成带源码存储的堆栈跟踪对话框、更快的堆栈跟踪、可在 64位 Windows 上加载 32位 日志文件的能力、监视映像(DLL和内核模式驱动程序)加载、系统引导时记录所有操作等。
用法参考:http://www.howtogeek.com/school/sysinternals-pro/lesson3/all/
下载地址:https://technet.microsoft.com/en-us/sysinternals/bb896653.aspx

Linux环境下没有发现整合好的对应工具,但可以使用pstack导出线程堆栈,为了辅助pstack捕获进程和cpu相关信息,还需要top、atop、pidstat、ps、pstree这类命令来监控定位High CPU程,最终达到的效果与windows下面的两款工具是一致的。
用法参考:https://docs.oracle.com/cd/E19683-01/816-0210/6m6nb7mih/index.html
下载地址:https://packages.debian.org/sid/pstack

8 Lua脚本开发工具

Lua脚本是一种与C/C++结合非常紧密的动态语言,自身就是由C代码实现的。由于它简单而又高效的特性,当前已经成功运用于各类行业软件中,在游戏开发领域更是有着其不可撼动的地位。作为游戏开发者,拥有一套高效易用的lua开发环境也同样重要。

由于Lua语法相对简单,很多编辑工具都能够为Lua提供语法高亮或者语法跳转功能,鲜有调试功能,调试Lua仅限于加入print函数重新运行,调试效率非常低。所以推荐使用Lua Studio,适用windows环境,IDE本身带有代码美观的功能,可以动态地以attach形式附着到任何进程中进行调试,并且自带脚本热点函数性能分析工具,功能比较全面。
下载地址:http://www.luastudio.net/

在Linux环境下可以使用Eclipse LDT,仍然具有调试功能。
下载地址:http://www.eclipse.org/ldt/

lua的静态检查工具只有Lua-Checker,但是对lua的写法有特殊要求,依赖bison且需要手动编译。
下载地址:https://code.google.com/p/lua-checker/

如果只是使用简单的Lua 语法检查,则可以使用lua自带的luac工具,命令如下:
luac -p *.lua

如果要对lua进行打包操作,则使用如下命令:
luac -o lua.o *.lua

如果需要使用各种网络库,可以使用luarocks , 使用方法类似于python 的pip/ez-install。
下载地址:https://luarocks.org/
迷茫是正常的,不怕学不会就怕不想学,大家可以加我的二千人群 487790381,每天直播课分享,实战项目教学,学习规范的代码风格。