Visual Studio Code
- 安装扩展 PrintCode:打印源码
浏览器搜索 PrintCode,到 marketplace 安装。
配置:VS Code Printing is highly configurable. Settings can be modified by going to Code > Preferences > Settings > Extensions > PrintCode Configuration.
使用:F1,type PrintCode - 安装 Print extension:Rendered Markdown, coloured code.
ACL 入门
- acl库使用FAQ:入门;
-
ldd 查看依赖的库;
ldd -r
:执行数据和函数的重定位,报告丢失的对象和函数;
ldd --help
:显示帮助信息。 -
undefined symbol 问题的查找、定位与解决方法,不错。
使用c++filt symbol
定位错误在哪个C++文件中。
通过 c++filt 发现:
typeinfo for InterfaceWaBasePack
常见原因是虚函数未定义;
标记为 inline 的函数,编译时优化掉了,也会报告 undefined symbol。
- correct way to encode/embed version number in program code;在代码中如何标记版本?编译成执行程序输出版本。
- nm 查看符号清单;
GDB 调试
-
gdb <program> <core>
产生core文件后,使用上述命令查看原因。
编译debug版本:在 cmake 编译时-DCMAKE_BUILD_TYPE=Debug
。
进入调试界面后,使用backtrace
(bt
)、up
、down
等命令查看。 -
gdb -tui
可以分窗口显示调试命令和源代码,可以尝试。 - gdb常用调试命令
命令(快捷) | 含义 | 备注 |
---|---|---|
run (r ) <args> |
执行被调试的程序,自动在第一个断点处暂停执行。 | args 是运行参数。也可以通过 set args 命令设置 |
load |
不退出gdb,重新加载执行文件 | 当你重新编译代码后,比如动态库,使用该命令重新加载。 |
break (b ) |
在源代码指定处设置断点,设置后也可清除断点。 |
b 14 表示在当前文件的14行设置断点。b filename:linenum 表示在文件行设置断点。b A::f 表示在类 A 的 f 函数断点。b filename:function 表示在文件函数设置断点。 |
clear / delete | clear 清除当前断点 | delete 清除所有断点 |
next (n ) |
执行当前语句,然后到下一个语句 | 遇到函数调用,不会进入函数内部。 |
step (s ) |
执行当前语句,遇有调用函数,进入函数内部。 | 如果函数参数是一条语句,则也会进入函数参数。 |
return |
立即结束当前正在执行的函数 | 停止执行当前函数剩余部分,立即返回指定值。 |
finish (fin ) |
finish: Step out of current function with GDB. | Continue running until just after function in the selected stack frame returns. Print the returned value (if any). |
continue (c ) |
继续执行 | 继续执行直至遇到下一个断点或程序结束 |
print (p ) |
打印指定变量的值。 类似: display ,区别在于 display 在每个命令后都会执行一次,在需要持续关注某变量时相当有用。 |
p ret 表示打印 ret 变量值。若出现 <optimized out> 则需要设置 编译优化选项:在编译时 CFLAGS 指定 -O0不优化。 |
frame (f ) |
显示当前行 | |
where |
显示调用堆栈 | |
info source |
显示当前源文件的相关信息 |
info sources 全部文件 |
dir <dirname> |
指定源文件目录 |
strace
-
strace <程序名称>
Trace Linux Command System Calls
You can simply run a command with strace like this, here we are tracing of all system calls made by the df command. -
sudo strace -p <pid>
Trace Linux Process PID
If a process is already running, you can trace it by simply passing its PID as follows; this will fill your screen with continues output that shows system calls being made by the process, to end it, press [Ctrl + C]. -
sudo strace -o <program>
Redirect Trace Output to File
To write the trace messages sent to standard error to a file, use the -o option. This means that only the command output is printed on the screen as shown below. - Troubleshooting and Debugging Linux Processes
tui mode
-
How to automatically refresh gdb in tui mode?
在 TUI(Text User Interface)调试模式下,有的时候代码窗口会乱掉,使用 ~/.gdbinit 进行命令 hook 即可。文件内容如下,即可在 执行 next 命令后 refresh 窗口。在 tui 下,通过 tabset 4 可设置 tab width 为 4。
define hook-next
refresh
end
部署运维
-
acl 服务器模块的部署;
本文对于部署当中涉及到的目录结构及其相关文件有清晰描述。 - acl服务器模块的部署--示例;
- acl 日志记录方式介绍:日志分析极为重要。
100:2; 102:3; 103:4,其含义是日志将会记录类别为 100 的所有级别值小于2、类别为 101 的所有级别值小于 3 以及类别为 103 的所有级别值小于 4 的日志信息。关于记录类别需要注意:类别值最好是 >= 100,且 < 1000(当使用 acl_debug_init2 初始化时只要类别值 >= 100 即可,因为第二个参数指定了最大类别值),这是因为 acl 库内部一些保留的类别值都在 0 -- 100 之间。
acl 的 C 库
- lib_acl.a。
源码:lib_acl\src\stdlib),有如下文件:
acl_mylog.c => acl_msg.c => acl_debug.c 层层封装。 acl_unused
在 lib_acl/include/stdlib/acl_define.h
#define acl_unused attribute ((unused))
- ACL_JSON* json
typedef struct ACL_JSON ACL_JSON;
lib_acl\include\json\acl_json.h
lib_acl\src\json\acl_json.c
acl 的 C++ 库
- log文件
包含头文件:lib_acl_cpp\include\acl_cpp\stdlib\log.hpp
源代码文件:lib_acl_cpp\src\stdlib\log.cpp
- acl::string
包含头文件:lib_acl_cpp\include\acl_cpp\stdlib\string.hpp
源代码文件:lib_acl_cpp\src\stdlib\string.cpp
- acl::json_node
包含头文件:lib_acl_cpp\include\acl_cpp\stdlib\json.hpp
源代码文件:lib_acl_cpp\src\stdlib\json.cpp
- acl::HttpServletRequest、acl::HttpServletResponse
包含头文件:lib_acl_cpp\include\acl_cpp\http\HttpServletRequest.hpp
源代码文件:lib_acl_cpp\src\http\HttpServletRequest.cpp
一般在 stdafx.h 中定义:
typedef acl::HttpServletRequest request_t;
typedef acl::HttpServletResponse response_t;
- acl::master_fiber
lib_fiber/cpp/include/fiber
lib_fiber/cpp/src
bool run_alone(const char* addrs, const char* path = NULL);
addrs 监听的本机服务地址列表;path 指定配置文件路径。
编译
-
编译使用 acl 协程库;
这个示例简洁易懂,对于相关依赖库的描述清晰,堪称经典教材。
库的依赖关系:libfiber_cpp.a libacl_all.a libfiber.a
因为协程是采用了 hook 模式,必须 放到 acl 基础库后面才可以。
libacl_all 里包含了 lib_acl_cpp.a, lib_protocol.a, lib_acl.a
- 配置文件的读取:开发人员可以看看。
ACL 服务器编程模型
进程、线程、协程、非阻塞、触发器 5种。
process 是指进程服务模型;
fiber 是协程模型;
trigger 是定时器模型;
向上取整 (n-1)/M+1
1、求 n 除以 M 的向下取整
q = n / M
,标准的 C 语言整数除法运算符 / 就是向下取整。
2、求 n 除以 M 的向上取整。
int q = (n-1)/M+1
就是向上取整。
3、向上取整的证明
下文使用 <> 表示向上取整,[] 表示向下取整。
<n/M> = [(n-1)/M]+1(n,M 都为正整数)
不失一般性。我们设 n = kM+r(k≧0整数,0≦r<M)。k和r不会同时为0,否则n为0了)。
当 k = 0 时(r>0),则n为小于M的正整数,两边都为1。
当 k > 0 时:
(1)当r = 0时:
左边:<n/M> = <(kM+0)/M> = k
右边:[(n-1)/M]+1 = [(kM+0-1)/M]+1 = [(k-1)M+M)-1)/M]+1
= [k-1+(M-1)/M]+1 = k+[(M-1)/M] = k
(1)当r > 0时。
左边:<n/M> = <(Mk+r)/M >= <k+r/M>= k+<r/M> = k+1
右边:[(n-1)/M]+1 = [(Mk+r-1)/M]+1 = [k+(r-1)/M]+1 = k+1+[(r-1)/M]=k+1
综上。命题得证。
三方库
- mbedtls:TLS 库;
渊源
- ACL 技术渊源:协作半驻留式服务器程序开发框架 --- 基于 Postfix 服务器框架改造、基于POSTFIX的服务器框架的服务器程序设计
通过这些文章,可以了解进程池服务器框架模型和工作进程框架模版种类。
更多参考: 郑树新@CSDN
网友评论