开发自己的编译器和虚拟机(三)

类别:软件工程 点击:0 评论:0 推荐:

6. Make your VM debugable

如果你的VM不能用来debug,这对用户来说肯定是不被满意的。

1.    第一步, 让你的VM支持debug

很简单, 如果VM被设置为运行在debug状态, 那么在每运行一条指令后,检查VM状态, 如果需要停止, 就停下来等待debug command, 否则就继续运行。

如果在停止下, 用户就可以使用各种的debug command 进行调试,比如显示寄存器内容, 显示内存内容, 查看变量的值, 等等。

VM的run函数的流程图:

 

SE支持的调试命令:

命令

功能

格式

备注

go

取消单步

go

 

forward

向前执行

forward [指令数]

 

halt

停止正在调试的脚本

halt

 

mem

显示内存

mem [地址][字节数]

 

reg

显示寄存器内容

reg [寄存器]

 

sp

设置断点

sp [line]

 

dp

删除断点

dp [line]

 

bp

显示所有断点

bp

 

备注:

1)        寄存器有八个AX, BX, CX, DX, PSW(状态寄存器), IP(指令寄存器),

 XX, YX, ZX.(这三个寄存器与调用外部函数有关)

实现:

       long m_lDbgCmdID;           //调试命令

       long m_lDbgCmdP1;           //调试指令的参数1

       long m_lDbgCmdP2;           //调试指令的参数2

       char m_szDbgCmdP3[1024];    //调试指令的参数3

调试命令存放在 m_lDbgCmdID中。

共有三个参数,

两个为long型,存放在m_lDbgCmdP1和m_lDbgCmdP2中。

一个为字符串,存放在m_szDbgCmdP3中。

 

2.    你可以让你的用户更惊讶, 因为你支持Online debug, remote debug

为什么要支持online debug?

因为有些bug只有在真实环境中才容易被重现, 比如只有当server的压力达到一定程度后才会出现的许多情况: 当压力达到每秒几万个请求, 通信层的已接收包队列, 待处理包队列, 待发送队列达到巨大的长度, 当负责接受, 负责处理, 负责发送的线程池已经扩大到几倍以上了, 当CPU和内存已经百分百。

在这种情况下出现bug时,如果可以在线对发生问题的虚拟机进行debug就太爽了。

 

如果支持online debug?

开一个特殊端口, 使用相同的通信层, 在这个端口接受到的请求都加上debug标志,简单吧。不过,暂时的限制是, 整个系统只能有一个应用被debug, 因为debug命令的输入是存放在全局变量中, 只要多写一个debug命令的despather模块就可以解决这个问题。

 

为什么要支持remote debug?

很简单, 我想连上一台强大的server进行调试, 本地机器太烂了。

 

如何支持 remote debug?

Server端有一个端口专门接受debug 命令, 其实就是一个最简单的tcp

Server。 Client 通过tcp发送字符串,也就是调试命令,server端进行处理。 这样就实现了remote debug。

7.   跨平台

这完全可以是一个激动人心的时刻。

因为, 应用已经依赖于平台, 所以, 是否跨操作系统取决于平台。

这里, 我只谈script engine的跨平台。主要是windows, linux, AIX这三个平台。

Window没什么好说的, 第一个版本就是windows的, 当我把MFC和win32 sdk的函数封装掉后(就是用#IFDEF WIN32 ELSE …), 剩下的就只有那段汇编了, 因为其他都是用标准C++写的。顺便说一句,STL 太好了, 因为他是C++标准的一部分(不过在AIX上遇到过一些问题)

Linux上用GCC做编译器。.

AIX上用的是XLC。

GCC支持inline assemble language

XLC 不支持inline assemble language.

Linux的汇编和windows稍有不同, 只是格式方面的不同。

而AIX是运行在PowerPC上的, 是RISC 系统, 和X86有本质区别。

在我的DevLog for AIX里, 有一段就是关于在AIX上的写汇编时遇到的恶梦, 因为RISC太不熟悉了。

问题还在于, 关于PowerPC上的汇编编程的文档实在太少了, IBM的文档和MS相差太远了, 当然还是比SAP好多了。呵呵 :P

我的办法就是, 写最简单的C程序, 然后用 xlc –c –s 编译成汇编指令, 看他们是如何对应的, 来了解如何写AIX汇编,这看上去不可思议, 其实是最有效的方法。

呵呵,所以现在,scripts可以运行在NT, RedHat, 和AIX. 其实支持了Linux 和windows, 基本就已经支持了最主流的平台了。

而当你以后写程序时有跨平台的概念后, 写平台无关的程序就很简单, 而且会成为你的习惯。 写一个平台相关的程序反而会让你很不爽。

使用标准C++, 基本就足够了。

另外, 我的同事写了一个非常优秀的跨平台库, 基本所有你可能会用到的功能都包括了, Mutex, 信号量, thread,file I/O, socket server/client, log, config file, md5, des3,string operation。。。

 

 

8.   Runtime Security

因为, 脚本会调用外部dll的接口, 所以, 很有可能会crash掉,从而导致整个系统crash, 这非常容易发生, 为了提高系统的稳定性, 就必须将每个应用运行在不同的process中。

这一点是我一直想做但没有时间去做的。

因为有许多相关的问题要考虑, 所以没有一个月是很难做到的。 而项目的压力已经快把我们压的透不过气来, 根本没有精力去改进底层的系统。

1.    需要有一个dispater process来分配请求到相应的working process

2.    进程间的数据需要同步, 因为有可能两个进程访问同一个服务。

3.    Dispatcher还要负责监控进程,最基本的,当有进程crash,必须重启它。

4.    在这种环境下,如何实现remote debug 和online debug

 

By Jackie

http://jackie_juju.nease.net

本文地址:http://com.8s8s.com/it/it36990.htm