├── .github
└── workflows
│ └── ccpp.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── _config.yml
├── build.sh
├── dep
└── lua-5.3.6.tar.gz
├── src
├── CMakeLists.txt
└── plua.cpp
├── test
├── call.png
├── mem_ALLOC_SIZE.png
├── test_cpu.lua
└── test_mem.lua
└── tools
├── flamegraph.pl
├── plua.go
├── png.go
├── pprof
└── show.sh
/.github/workflows/ccpp.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v1
12 |
13 | - name: prepare-lua
14 | run: |
15 | sudo apt-get install libreadline-dev -y
16 | sudo wget https://www.lua.org/ftp/lua-5.3.4.tar.gz
17 | sudo tar -xf lua-5.3.4.tar.gz
18 | cd lua-5.3.4
19 | sudo make linux
20 | sudo make install
21 |
22 | - name: make
23 | run: |
24 | sudo ./build.sh
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 | build
4 | cmake-build-debug
5 | debug
6 | bin
7 | obj
8 | tags
9 | .vscode
10 | init
11 | tatus
12 | v_init
13 | GPATH
14 | GRTAGS
15 | GTAGS
16 | proto_md5
17 | CMakeSettings.json
18 |
19 | *~
20 | .*.swp
21 | .vs/
22 | .a
23 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 | project(PLUA_PROJECT)
3 |
4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g3 -std=c++11 -DNDEBUG -O3 ")
5 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
6 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
7 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
8 | add_subdirectory(src)
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 zhao xin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pLua
2 |
3 | [
](https://github.com/esrrhs/pLua)
4 | [
](https://github.com/esrrhs/pLua)
5 | [
](https://github.com/esrrhs/pLua/actions)
6 |
7 | Lua 性能分析工具
8 |
9 | ## 简介
10 | 类似于gperftools,可分析Lua程序的热点及内存分配情况
11 |
12 |
13 | ## 特性
14 | - 简单,只需几行代码,即可输出结果,或通过[hookso](https://github.com/esrrhs/hookso)注入,不用修改代码
15 | - 准确,相比lua hook,定时采样的方式更能准确捕获lua执行的热点,使用ITIMER_PROF剔除sleep等堆栈
16 | - 轻量,因为是采样的,相比直接按行lua hook,能最小程度影响宿主程序的运行
17 | - 直观,输出调用图,能直观的看到热点和调用关系,可兼容[gperftools](https://github.com/gperftools/gperftools)的pprof工具,可生成[火焰图](https://github.com/brendangregg/FlameGraph)
18 |
19 | ## 编译
20 | * 安装lua
21 | * 编译插件libplua.so及tools
22 | ```shell
23 | # ./build.sh
24 | ```
25 | * 安装火焰图的依赖项
26 | ```shell
27 | # yum install perl-open.noarch
28 | ```
29 |
30 | ## 使用
31 | #### 获取CPU采样数据
32 | * 修改Lua code
33 | ``` lua
34 | -- 引入libplua.so
35 | local p = require "libplua"
36 | -- 开启采样
37 | -- 参数1:采样时间(秒),0表示一直采样
38 | -- 参数2:采样结果文件
39 | p.start(0, "call.pro")
40 |
41 | do_some_thing()
42 |
43 | -- 结束采样,输出结果文件
44 | p.stop()
45 |
46 | ```
47 | * 或者用[hookso](https://github.com/esrrhs/hookso)注入
48 | ```shell
49 | a) 首先获取进程中的Lua_State指针,比如进程的xxx.so调用了lua_settop(L)函数,那么就取第一个参数
50 | # ./hookso arg $PID xxx.so lua_settop 1
51 | 123456
52 |
53 | b) 加载libplua.so
54 | # ./hookso dlopen $PID ./libplua.so
55 |
56 | c) 执行libplua.so的lrealstart手动开启,等价于lrealstart(L, 0, "./call.pro")
57 | # ./hookso call $PID libplua.so lrealstart i=123456 i=0 s="./call.pro"
58 |
59 | c) 执行libclua.so的lrealstop手动关闭,等价于lrealstop(L)
60 | # ./hookso call $PID libplua.so lrealstop i=123456
61 | ```
62 | #### 获取内存采样数据
63 | * 修改Lua code
64 | ``` lua
65 | -- 引入libplua.so
66 | local p = require "libplua"
67 | -- 开启采样
68 | -- 参数1:采样时间(秒),0表示一直采样
69 | -- 参数2:采样结果文件名,会生成2个采样文件,分别代表内存分配大小、内存占用大小
70 | p.start_mem(0, "mem.pro")
71 |
72 | do_some_thing()
73 |
74 | -- 结束采样,输出结果文件
75 | p.stop_mem()
76 |
77 | ```
78 | * 或者用[hookso](https://github.com/esrrhs/hookso)注入
79 | ```shell
80 | a) 首先获取进程中的Lua_State指针,比如进程的xxx.so调用了lua_settop(L)函数,那么就取第一个参数
81 | # ./hookso arg $PID xxx.so lua_settop 1
82 | 123456
83 |
84 | b) 加载libplua.so
85 | # ./hookso dlopen $PID ./libplua.so
86 |
87 | c) 执行libplua.so的lrealstartmem手动开启,等价于lrealstartmem(L, 0, "./call.pro")
88 | # ./hookso call $PID libplua.so lrealstartmem i=123456 i=0 s="./call.pro"
89 |
90 | c) 执行libclua.so的lrealstopmem手动关闭,等价于lrealstopmem(L)
91 | # ./hookso call $PID libplua.so lrealstopmem i=123456
92 | ```
93 |
94 | ## 示例
95 | #### 运行test目录下的lua
96 | ```shell
97 | # lua test_cpu.lua
98 | # lua test_mem.lua
99 | ```
100 |
101 | #### 生成可视化结果
102 | 使用tools目录下的show.sh脚本生成gperftools风格png及火焰图
103 | ```shell
104 | # cd tools
105 | # ./show.sh ../test
106 | ```
107 |
108 | #### 查看test_cpu.lua的热点
109 | 
110 |
111 | #### 查看test_mem.lua的内存采样
112 | * 内存分配大小
113 | 
114 |
115 | ## 其他
116 | [lua全家桶](https://github.com/esrrhs/lua-family-bucket)
117 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | dir=$(cd `dirname $0`;pwd)
3 | projectdir=$dir
4 | builddir="$projectdir/build"
5 | rundir="$projectdir/bin"
6 | luadir="$projectdir/dep/lua-5.3.6"
7 | lua="$projectdir/dep/lua-5.3.6.tar.gz"
8 |
9 | if [ -f "$lua" ] && [ ! -d "$luadir" ]; then
10 | cd $projectdir/dep && tar zxvf $lua
11 | cd $projectdir && cp $projectdir/dep/lua-5.3.6/src/*.h $projectdir/src
12 | fi
13 |
14 | if [ ! -d "$rundir" ]; then
15 | mkdir -p $rundir && cd $rundir
16 | fi
17 |
18 | if [ -d "$builddir" ]; then
19 | rm $builddir -rf
20 | mkdir -p $builddir && cd $builddir
21 | else
22 | mkdir -p $builddir && cd $builddir
23 | fi
24 |
25 | cmake ../
26 | make
27 |
28 | cd ../tools
29 | GO111MODULE=off go build plua.go
30 | GO111MODULE=off go build png.go
31 |
32 | chmod a+x pprof
33 | chmod a+x *.pl
34 | chmod a+x *.sh
35 |
--------------------------------------------------------------------------------
/dep/lua-5.3.6.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/esrrhs/pLua/c734adc80b9cbc18136a0aa6ae9b47dec9f13e11/dep/lua-5.3.6.tar.gz
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | project(plua)
2 | aux_source_directory(./ plua_src)
3 | add_library(plua SHARED ${plua_src})
4 | TARGET_LINK_LIBRARIES(plua)
5 |
--------------------------------------------------------------------------------
/src/plua.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include