1# HiCollie开发指导<a name="ZH-CN_TOPIC_0000001231255509"></a> 2 3 4## 概述<a name="section3432134085116"></a> 5 6HiCollie提供了软件看门狗功能。针对系统服务死锁、应用主线程阻塞,用户业务流程超时等故障,HiCollie提供了一套统一的用于故障检测和故障日志生成的框架,提供软件超时故障日志,辅助定位软件超时问题。 7 8## 接口说明<a name="section139261151145116"></a> 9 10**表 1** C++接口功能描述表 11 12<a name="table19452225011"></a> 13<table><thead align="left"><tr id="row1517803543518"><th class="cellrowborder" valign="top" width="19.698030196980305%" id="mcps1.2.4.1.1"><p id="p484763319529"><a name="p484763319529"></a><a name="p484763319529"></a>所属类</p> 14</th> 15<th class="cellrowborder" valign="top" width="35.82641735826417%" id="mcps1.2.4.1.2"><p id="p1684719339523"><a name="p1684719339523"></a><a name="p1684719339523"></a>接口定义</p> 16</th> 17<th class="cellrowborder" valign="top" width="44.47555244475552%" id="mcps1.2.4.1.3"><p id="p284773315220"><a name="p284773315220"></a><a name="p284773315220"></a>描述</p> 18</th> 19</tr> 20</thead> 21<tbody><tr id="row1361184632117"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p6700155032113"><a name="p6700155032113"></a><a name="p6700155032113"></a>XCollieChecker类接口</p> 22</td> 23<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p18699115019217"><a name="p18699115019217"></a><a name="p18699115019217"></a>virtual void CheckBlock()</p> 24</td> 25<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p18700175062115"><a name="p18700175062115"></a><a name="p18700175062115"></a>接口功能:卡死检测回调函数。</p> 26<p id="p13700125012216"><a name="p13700125012216"></a><a name="p13700125012216"></a>输入参数:无。</p> 27<p id="p13700650162114"><a name="p13700650162114"></a><a name="p13700650162114"></a>输出参数:无。</p> 28<p id="p3700850192115"><a name="p3700850192115"></a><a name="p3700850192115"></a>返回值:无。</p> 29</td> 30</tr> 31<tr id="row8945182185017"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p79451227506"><a name="p79451227506"></a><a name="p79451227506"></a>XCollieChecker类接口</p> 32</td> 33<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p647534064612"><a name="p647534064612"></a><a name="p647534064612"></a>virtual void CheckThreadBlock()</p> 34</td> 35<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p127630177475"><a name="p127630177475"></a><a name="p127630177475"></a>接口功能:线程卡死检测回调函数。</p> 36<p id="p18763111794719"><a name="p18763111794719"></a><a name="p18763111794719"></a>输入参数:无。</p> 37<p id="p87631176478"><a name="p87631176478"></a><a name="p87631176478"></a>输出参数:无。</p> 38<p id="p3764111718473"><a name="p3764111718473"></a><a name="p3764111718473"></a>返回值:无。</p> 39</td> 40</tr> 41<tr id="row149924222486"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p11643173114810"><a name="p11643173114810"></a><a name="p11643173114810"></a>XCollie类接口</p> 42</td> 43<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p16289114074812"><a name="p16289114074812"></a><a name="p16289114074812"></a>void RegisterXCollieChecker(const sptr<XCollieChecker> &checker, unsigned int type)</p> 44</td> 45<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p186437319482"><a name="p186437319482"></a><a name="p186437319482"></a>接口功能:线程卡死检测回调函数注册。</p> 46<p id="p112011591133"><a name="p112011591133"></a><a name="p112011591133"></a>输入参数:</p> 47<a name="ul7783192181413"></a><a name="ul7783192181413"></a><ul id="ul7783192181413"><li>checker:XCollieChecker实例指针。</li><li>type:卡死检测类型,取值设置为XCOLLIE_THREAD。</li></ul> 48<p id="p166439314482"><a name="p166439314482"></a><a name="p166439314482"></a>输出参数:无。</p> 49<p id="p564393112485"><a name="p564393112485"></a><a name="p564393112485"></a>返回值:无。</p> 50</td> 51</tr> 52<tr id="row594519275012"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p294512211505"><a name="p294512211505"></a><a name="p294512211505"></a>XCollie类接口</p> 53</td> 54<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p81561310145215"><a name="p81561310145215"></a><a name="p81561310145215"></a>int SetTimer(const std::string &name, unsigned int timeout, std::function<void (void *)> func, void *arg, unsigned int flag)</p> 55</td> 56<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p174279246538"><a name="p174279246538"></a><a name="p174279246538"></a>接口功能:添加定时器。</p> 57<p id="p1998141221410"><a name="p1998141221410"></a><a name="p1998141221410"></a>输入参数:</p> 58<a name="ul845512153147"></a><a name="ul845512153147"></a><ul id="ul845512153147"><li>name:定时器名称。</li><li>timeout:超时时间,单位为秒。</li><li>func:超时回调函数。</li><li>arg:超时回调函数参数指针。</li><li>flag:定时器操作类型。<p id="p1242762435310"><a name="p1242762435310"></a><a name="p1242762435310"></a>XCOLLIE_FLAG_DEFAULT // 其他三个选项功能之和</p> 59<p id="p1542712435312"><a name="p1542712435312"></a><a name="p1542712435312"></a>XCOLLIE_FLAG_NOOP // 仅调用超时回调函数</p> 60<p id="p15427112416531"><a name="p15427112416531"></a><a name="p15427112416531"></a>XCOLLIE_FLAG_LOG // 生成超时故障日志</p> 61<p id="p242762455314"><a name="p242762455314"></a><a name="p242762455314"></a>XCOLLIE_FLAG_RECOVERY // 进程退出</p> 62</li></ul> 63<p id="p15427102445311"><a name="p15427102445311"></a><a name="p15427102445311"></a>输出参数:无。</p> 64<p id="p144271424155316"><a name="p144271424155316"></a><a name="p144271424155316"></a>返回值:成功返回定时器标识,失败返回-1。</p> 65</td> 66</tr> 67<tr id="row1294692165010"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p19461929506"><a name="p19461929506"></a><a name="p19461929506"></a>XCollie类接口</p> 68</td> 69<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p119467215012"><a name="p119467215012"></a><a name="p119467215012"></a>bool UpdateTimer(int id, unsigned int timeout)</p> 70</td> 71<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p3831253185713"><a name="p3831253185713"></a><a name="p3831253185713"></a>接口功能:更新定时器。</p> 72<p id="p10649172815148"><a name="p10649172815148"></a><a name="p10649172815148"></a>输入参数:</p> 73<a name="ul1628783221411"></a><a name="ul1628783221411"></a><ul id="ul1628783221411"><li>id:定时器标识。</li><li>timeout:超时时间,单位为秒。</li></ul> 74<p id="p11831115375719"><a name="p11831115375719"></a><a name="p11831115375719"></a>输出参数:无。</p> 75<p id="p38311853105716"><a name="p38311853105716"></a><a name="p38311853105716"></a>返回值:成功返回true,失败返回false。</p> 76</td> 77</tr> 78<tr id="row594682175013"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p194614212504"><a name="p194614212504"></a><a name="p194614212504"></a>XCollie类接口</p> 79</td> 80<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p1435552713588"><a name="p1435552713588"></a><a name="p1435552713588"></a>void CancelTimer(int id)</p> 81</td> 82<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p06791131580"><a name="p06791131580"></a><a name="p06791131580"></a>接口功能:取消定时器。</p> 83<p id="p868013165815"><a name="p868013165815"></a><a name="p868013165815"></a>输入参数:定时器标识。</p> 84<p id="p12680537587"><a name="p12680537587"></a><a name="p12680537587"></a>输出参数:无。</p> 85<p id="p768015317586"><a name="p768015317586"></a><a name="p768015317586"></a>返回值:无。</p> 86</td> 87</tr> 88</tbody> 89</table> 90 91## 效果<a name="section1589120102458"></a> 92 93日志打印: 94 95``` 96timeout: TimeoutTimer start at 1611040305 to check 1s ago 97 98----------StacktraceCatcher CurrentTime:2021-01-19 15:11:45 Unexecuted(-1)(LogType:Stacktrace Pid:27689 Process:XCollieTimeoutModuleTest)---------- 99 100 101----- pid 27689 at 2021-01-19 15:11:45 ----- 102Cmd line: ./XCollieTimeoutModuleTest 103ABI: 'arm64' 104 105"XCollieTimeoutM" sysTid=27689 106 #01 pc 00000000000174cc /data/test/XCollieTimeoutModuleTest 107``` 108 109## 开发实例<a name="section13905646534"></a> 110 111### C++接口开发实例<a name="section9797199145316"></a> 112 113### 线程卡死监控<a name="section1734221332"></a> 114 115线程卡死监控功能需要开发者实现两个卡死检测回调函数,XCollieChecker类的CheckBlock和CheckThreadBlock接口函数。实现了该回调函数之后,开发者还需要通过XCollie类的RegisterXCollieChecker函数,将该回调函数的类实例成功注册。卡死监控线程会定时执行全部已成功注册的回调函数,检查线程逻辑完成标志位,判定已经成功注册的线程逻辑是否被卡死。 116 1171. 源代码开发 118 119 包含头文件: 120 121 ``` 122 #include "xcollie.h" 123 ``` 124 125 在业务代码中使用: 126 127 ``` 128 void MyXCollieChecker::CheckLock() 129 { 130 /* time consuming job */ 131 } 132 133 void MyXCollieChecker::CheckThreadBlock() 134 { 135 /* time consuming job */ 136 } 137 138 sptr<XCollieChecker> checker = new MyXCollieChecker("MyXCollieChecker"); 139 XCollie::GetInstance().RegisterXCollieChecker(checker, 140 (XCOLLIE_LOCK | XCOLLIE_THREAD)); 141 ...... 142 ``` 143 1442. 编译设置,在BUILD.gn里增加子系统SDK依赖: 145 146 ``` 147 external_deps = [ "hiviewdfx:libxcollie" ] 148 ``` 149 150 151### 超时监控<a name="section2186947140"></a> 152 153单个进程通过SetTimer接口函数添加定时器最多可以设置128个,超过上限则添加定时器操作会失败。 154 1551. 源代码开发 156 157 包含头文件: 158 159 ``` 160 #include "xcollie.h" 161 ``` 162 163 在业务代码中使用(添加/更新/取消): 164 165 ``` 166 std::function<void(void *)> callback = [](void *args) 167 { 168 /* dump helpful information */ 169 }; 170 171 int id = XCollie::GetInstance().SetTimer("MyXCollieTimer", 10, callback ,nullptr, XCOLLIE_FLAG_LOG); 172 /* time consuming job */ 173 XCollie::GetInstance().UpdateTimer(id, 5); 174 /* time consuming job */ 175 XCollie::GetInstance().CancelTimer(id); 176 ...... 177 ``` 178 1792. 编译设置,在BUILD.gn里增加子系统SDK依赖: 180 181 ``` 182 external_deps = [ "hiviewdfx:libxcollie" ] 183 ``` 184 185 186