MMORPG大型游戏设计与开发(客户端架构 part5 of vegine)
客户端异常捕获,是一件必然的事情,特别是在开发的时候就更需要这些有利于找出问题原因的捷径。区别于服务器的是,客户端基本上是以界面为主,你很难在正常运行程序的情况下进行一些输出的监视,如一些日志的记录。开发中我们可以调用一些别的界面来监控输出,但发布的版本则不能。日志的记录在客户端也是必不可少的,但是客户端记录的日志一般都是必要的日志,毕竟客户端最后是放在别人的机器上,我们不能像服务器那边可以随意使用资源。如果客户端的日志过大,则会造成用户的不满,这种不满就决定了你应用的可行性,直观的说你的应用不能被用户所接受。所以在客户端产生异常奔溃的时候,往往会弹出一个提示框,然后将本次奔溃的日志发送到相应的异常资源收集服务器上,这样方便开发人员进行跟踪调试。
CODE
模块exception文件base.h
/** * PAP Engine ( -- ) * $Id base.h * @link -- for the canonical source repository * @copyright Copyright (c) 2013-2014 viticm( viticm@126.com ) * @license * @user viticm<viticm@126.com/viticm.ti@gmail.com> * @date 2014-3-17 10:57:14 * @uses vengine exception base functions */ #ifndef VENGINE_EXCEPTION_BASE_H_ #define VENGINE_EXCEPTION_BASE_H_ #include "vengine/config.h" //ref from http://www.codeproject.com/tools/minidump.asp //generate stack frame pointers for all functions - same as /Oy- in the project #pragma optimize("y", off) namespace vengine_exception { namespace base { VENGINE_API void process(PEXCEPTION_POINTERS exception, bool run_crashreport); VENGINE_API void showstring(const char* format, ...); VENGINE_API void showassert(const char* filename, uint16_t fileline, const char* exception); VENGINE_API int32_t processinner(PEXCEPTION_POINTERS exception, HWND hparentwnd, const char* title); }; //namespace base }; //namespace vengine_exception #define VENGINE_SHOW vengine_exception::base::showstring #define VENGINE_ASSERT(condition) \ if (!condition) { \ vengine_exception::base::showassert(__FILE__, \ __LINE__, \ #condition); \ } \ // do { \ // } while (0); #endif //VENGINE_EXCEPTION_BASE_H_
模块exception文件errorinfo
/** * PAP Engine ( -- ) * $Id errorinfo.h * @link -- for the canonical source repository * @copyright Copyright (c) 2013-2014 viticm( viticm@126.com ) * @license * @user viticm<viticm@126.com/viticm.ti@gmail.com> * @date 2014-3-17 12:02:16 * @uses vengine exception error info functions */ #include "vengine/config.h" namespace vengine_exception { #pragma optimize("y", off) namespace errorinfo { bool create_smallinfo_dumpfile(PEXCEPTION_POINTERS exception, char* filename, uint16_t lasterror); bool create_biginfo_dumpfile(PEXCEPTION_POINTERS exception, char* filename, uint16_t lasterror); bool create_dumphelp_file(PEXCEPTION_POINTERS exception, char* filename); }; //namespce errorinfo }; //namespace vengine_exception
方法解释
//捕获异常,第一个为异常指针,第二个是指是否运行crashreport(异常收集器) void process(PEXCEPTION_POINTERS exception, bool run_crashreport); void showstring(const char* format, ...); //异常抛出 //异常中断,第一个为中断的文件名,第二个为中断的行数,第三个为异常字符串 void showassert(const char* filename, uint16_t fileline, const char* exception); //异常捕获,区别于第一个方法的是,此异常为内部的,没有异常收集器 int32_t processinner(PEXCEPTION_POINTERS exception, HWND hparentwnd, const char* title); errorinfo::create_* //函数,用来创建异常信息文件
SIMPLE
天龙八部的异常收集:
总结
异常收集是客户端比较重要的一部分,因为开发过程中不会出现的问题,不一定在发布的时候出现,也不一定在别的机器上不会出现。异常收集已经成了应用常见的一个模块,几乎所有的应用都会有这样的工具,或前台或后台的收集。下一节要讲的是客户端变量模块。
作者:viticm
出处: http://www.cnblogs.com/lianyue/