快速上手
driver的启动
查看全部启动参数
使用以下命令启动cmmshell均可查看启动参数
cmmshell --help
cmmshell /H || cmmshell -H
cmmshell /h || cmmshell -h
cmmshell /? || cmmshell -?
常用的启动参数
下面将介绍一些常用的启动参数,更详 细的启动参数见文末。
/r
设置根目录/e(q)
启动脚本/m
可以带多个预加载的脚本,如果有多个用逗号隔开(,
)--mount
挂载目录/D
预定义宏--require
||--require-all
导入内置插件(用于兼容旧代码,详细说明见import
章节中的相关说明)/c1
开启命令行交互模式
其中/c1
常用于linux系统中,windows下是默认开启的。
下面给出一个例子更好的理解上述的其他参数,可以不用关注语法细节,使用的语法也非常简单,需要关注的是启动参数的使用方法。
目录结构如下:
sample-server
├─start_server.bat
├─server
| ├─preload.gsh
| └server.gs
├─etc
| └test.txt
├─bin
| └cmmshell.exe
start-server.bat 内容如下
.\bin\cmmshell.exe /r ./server/ /e /server.gs /m /preload.gsh --mount ./etc::/etc_m
可以看到这句批处理将根目录设置为./server/
, 后面/e
和 /m
都是相对于这个根目录来说,mount
是将当前目录下的etc
文件夹挂载到根目录下的etc。
preload.gsh 内容如下
write("load preload.gsh\n");
sever.gs 内容如下
write("sample server\n");
启动脚本后可以看到先输出了load preload.gsh
然后输出了sample server
, 也就是说预加载脚本和启动脚本都被执行了,且预加载脚本是在启动脚本之前执行的。
接下来我们来验证一下根目录是否被设置为./server以及etc是否有挂载在根目录下。
在控制台上敲一句'get_system_info()
,这里的'
用于控制台上的快捷打印,get_system_info()
可以返回driver现在的一些信息。查看输出中的root_path和mount_info即可。进一步验证etc是否成功挂载成根目录下的etc_m可以在控制台上敲一下下面这句话。
'file.exist("/etc_m/test.txt")
现在我们已经对启动参数以及简单的项目结构有一个整体的认知了,并且能对shell进行操作,接下来看看shell上的常用方法吧。
shell常用方法
-
man 用于查看函数说明
比如想查看array相关的函数,这时可以在控制台敲man("array")
或者敲man array
, 两种写法是等价的。可以看到函数的属性(包括定义在c++中还是定义在script中,是static函数还是member函数),参数列表以及描述。 -
cls
用于清空屏幕 -
。
||.
用于退出driver -
monkey.patch(program_name)
或monkey.patch("代码文件路径")
- 可以尝试通过
handle.get_all("program")
查询当前有哪些program - 然后通过
monkey.patch(program_name)
去热更新 update()
也可以用于热更新, 但是实现原理不太相同, update的逻辑更简单compile → destruct_object → load_static,但是对于有状态的对象,成员变量无法恢复,无法进行热更新。monkey.patch
更为通用。
- 可以尝试通过
-
find_object(handle|string name_or_id)
查找一个object -
get_obj_var(object ob, string var_name)
查看某个object的私有变量 -
set_obj_var(object ob, string var_name, mixed val)
设置某个私有变量的值 避免添加一个set函数->patch->删除这个set函数->patch这样的工作 -
child_objects(string | object name)
某个对象的所有实例 -
常规的输出操作为
write("xxxx")
或printf("xxxxx")
- 但是在shell中可以用'快捷打印'"xxx"
如何快速测试
在下一章中将会有很多需要测试的例子,快速测试并不需要写上面提到那种相对复杂的项目结构。下面介绍常用的两种方法,以如下这个简单的目录结构为例
sample-helloworld
├─test.gs
├─cmmshell.exe
一. 使用启动参数启动
启动语句
cmmshell.exe /r ./ /e /test.gs
二. 使用load_static
启动参数什么也不写,把cmmshell启动起来
在控制台上敲
load_static("/test.gs", this_domain())
全部启动参数简介
所有可选启动参数内容
/h
显示启动参数帮助信息/b
设置二进制文件名/c1
启用命令行/c2
启用命令行并在完成启动前开启输入/d
设置默认object文件名/m
设置宏文件名·/D
预定义宏/e[q]
设置虚拟器执行的启脚本,若使用/eq
则在启动脚 本执行完成后退出/l
设置log文件名/o
设置基础脚本 (在/e
设置的启动脚本执行前执行)/p
设置telnet端口/r
设置根路径/s
设置默认线程池大小/sm
设置GC static worker 数量/w
设置telnet的密码/v
显示版本信息--help
显示启动参数帮助信息--cpu[s]
设置可用cpu信息--call-stack-size %%d
设置函数调用上下文的深度--enable-color-error
将错误输出消息设置为红色--enable-compiler-debug
启用编译器调试,显示生成的汇编信息--enable-debugger [%%d]::[%%d]
允许嵌入式调试器工作,可选的是调试器端口和调试器状态. (1 表示随机端口),(1 或 0,表示调试器在启动时暂停--enable-gc-log
启用gc日志--enable-jit
启用jit (0 no-jit, 1 asmjit, 2 llvmjit)--enable-warmup
启用jit预热--enable-jit-debug
启用jit调试--enable-jit-log
启用jit日志--enable-multi-cpu
使用多CPU(可能导致性能不佳)--enable-system-command
启用efun "system"(存在安全隐患)--enable-opt-bytecode
启用解释执行优化--enable-coverage
启用覆盖率统计--gc changedset
使用changed set进行minor gc 标记--gc cardtable
使用card table进行minor gc 标记--gc changedset+cardtable
使用 no changed set & card table 进行minor gc 标记--gc full
仅使用full gc 不再进行minor gc--gc-force-full-gc
启动强制full gc--gc-lms-cache[d]
释放内存页面时每个 lms 的缓存删除页面大小(字节)--gc-global-cache[d]
释放内存页面时所有 lms 的缓存删除页面大小(字节)。\n"--gc-gray-page-size
gray page中的 units 数量(0 表示不使用gray page)--gc-max-dynamic-work-us
--gc-max-dynamic-worker[s]
动态工作线程的最大数量--gc-max-ub-pool[s]
单元/块池的最大数量--gc-min-gc-interval
gc间隔的最短时间(ms)--gc-quota-to-full-gc
提示 full GC(当old units大小增加超过限制时)--gc-quota-to-minor-gc
提示 minor GC (当young units大小增加超过限制时)--gc-max-quota-to-minor-gc
限制为 minor GC(当young units大小增加超过限制时)--gc-stat-recycle
在指定轮次后为调试打印回收信息--gc-time-to-long-live
为GC设置默认的参考值ttll--gc-thread-threshold
限制dynamic worker(在 GC 期间分配的大小超过限制时)--jit-mem-size
JIT 内存池保留大小 (MB)。 (默认值:1024)--lcs-buf-size
默认 LCS 缓冲区大小--no-internal-scripts
启动时不加载内部脚本--mount
挂载设备或路径(真实目录::挂载点)--call-coroutine[s]
调度器的最大协程数--max-device[s]
可以打开的最大设备数量--max-os-thread[s]
操作系统最大线程数--max-sync_object
调度器的最大同步对象数量--max-rudp
最大 rudp 连接数--max-socket
最大socket数量--optimize
设置优化选项 格式: opt1=0/1;opt2=0/1... (默认: eps_efun=1)--page-alloc
使用页面内存分配器--page-keep-committed
保持所有页面都已提交--pause-startup-script
等待某事完成然后开始执行启动脚本--publish
启用某些功能以通过指定的 pmake 文件发布--publish-builder
设置 pmake 构建 builder脚本--publish-loader
设置 pmake 价值 loader 脚本--quick-exit-on-windows
通过 TerminateProcess 在 Windows 上启用快速退出。 (默认值:true)--relinquish
设置调度器的放弃时间--require
添加需要的插件,格式:--require plugin1;plugin2;... 或者--require all--root-password
设置root密码--script-args
设置脚本参数,格式:--script-args "args..."--search-path
设置打开设备的搜索路径,格式:path1;path2;path3...--socket-coroutine
设置套接字协程数--stack-size %%d
堆栈大小--treat-warning-as-error
告诉编译器将警告视为错误--use-single-lms
使用单个本地内存存储以节省内存--use-large-page
使用大页面(intel 的页面大小为 2M)--with-malloc 1[xAll|xNonGC]
分配内存时做额外的malloc--use-client-mode
使用客户端模式--timer-scheduler
设置 TimerScheduler(level1_unit_num/level2_unit_num/max_timers)的值--parallel-scheduler
设置 ParallelScheduler(level1_unit_num/level2_unit_num/pool_size) 的值。--thread-scheduler
设置 ThreadScheduler(level1_unit_num/level2_unit_num/pool_size) 的值。--reverse-trace
设置报错或trace_call_stack() 调用栈输出是否反向--disable-dump-window
在 Windows 上 dump 时禁用消息框窗口。(默认值:false)\n--dead-code-warn
优化遇到死代码是否给出警告--general-opt
部分通用优化开关