{"id":167,"date":"2024-09-18T20:59:37","date_gmt":"2024-09-18T12:59:37","guid":{"rendered":"https:\/\/newstrong.xyz\/?p=167"},"modified":"2024-09-18T20:59:37","modified_gmt":"2024-09-18T12:59:37","slug":"%e5%be%ae%e4%bf%a1android%e5%ae%a2%e6%88%b7%e7%ab%af%e7%9a%84anr%e7%9b%91%e6%8e%a7%e6%96%b9%e6%a1%88","status":"publish","type":"post","link":"https:\/\/newstrong.top\/index.php\/2024\/09\/18\/%e5%be%ae%e4%bf%a1android%e5%ae%a2%e6%88%b7%e7%ab%af%e7%9a%84anr%e7%9b%91%e6%8e%a7%e6%96%b9%e6%a1%88\/","title":{"rendered":"\u5fae\u4fe1Android\u5ba2\u6237\u7aef\u7684ANR\u76d1\u63a7\u65b9\u6848"},"content":{"rendered":"<p><meta itemprop=\"headline\" content=\"\u5fae\u4fe1Android\u5ba2\u6237\u7aef\u7684ANR\u76d1\u63a7\u65b9\u6848\"> <meta itemprop=\"keywords\" content=\"Android\"> <meta itemprop=\"datePublished\" content=\"2021-08-07T15:17:47.000Z\"> <meta itemprop=\"image\" content=\"https:\/\/p1-jj.byteimg.com\/tos-cn-i-t2oaga2asx\/gold-assets\/icon\/icon-128.png~tplv-t2oaga2asx-image.image\"> <\/p>\n<div itemprop=\"author\" itemscope=\"itemscope\" itemtype=\"http:\/\/schema.org\/Person\">\n<meta itemprop=\"name\" content=\"\u7528\u62377563717074065\"> <meta itemprop=\"url\" content=\"https:\/\/juejin.cn\/user\/3193395837676829\">\n<\/div>\n<div itemprop=\"publisher\" itemscope=\"itemscope\" itemtype=\"http:\/\/schema.org\/Organization\">\n<meta itemprop=\"name\" content=\"\u6398\u91d1\"> <\/p>\n<div itemprop=\"logo\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\">\n<meta itemprop=\"url\" content=\"https:\/\/p1-jj.byteimg.com\/tos-cn-i-t2oaga2asx\/gold-assets\/icon\/icon-white-180.png~tplv-t2oaga2asx-image.image\"> <meta itemprop=\"width\" content=\"180\"> <meta itemprop=\"height\" content=\"180\">\n<\/div>\n<\/div>\n<p class=\"article-title\" data-v-0140422c>\n\u5fae\u4fe1Android\u5ba2\u6237\u7aef\u7684ANR\u76d1\u63a7\u65b9\u6848\n<\/p>\n<div class=\"author-info-block block-hidden\" data-v-0140422c>\n<div class=\"author-info-box\" data-v-0140422c>\n<div class=\"author-name\" data-v-0140422c><span class=\"name\" style=\"max-width:160px;\" data-v-65b50b51 data-v-1800aadb><br \/>\n    \u7528\u62377563717074065<br \/>\n  <\/span>    <\/div>\n<div class=\"meta-box\" data-v-0140422c>\n<time datetime=\"2021-08-07T15:17:47.000Z\" title=\"Sat Aug 07 2021 15:17:47 GMT+0000 (Coordinated Universal Time)\" class=\"time\" data-v-0140422c><br \/>\n                    2021-08-07<br \/>\n                  <\/time> <svg width=\"16\" height=\"16\" viewbox=\"0 0 16 16\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"read-icon\" data-v-0140422c><path d=\"M7.90078 2.80078C4.49278 2.80078 1.74745 6.11672 0.800781 7.77469C1.74745 9.58339 4.49278 13.2008 7.90078 13.2008C11.3088 13.2008 14.0541 9.58339 15.0008 7.77469C14.0541 6.11672 11.3088 2.80078 7.90078 2.80078Z\" stroke=\"currentColor\" data-v-0140422c><\/path><circle cx=\"7.89922\" cy=\"8.00078\" r=\"2.2\" stroke=\"currentColor\" data-v-0140422c><\/circle><\/svg> <span class=\"views-count\" data-v-0140422c><br \/>\n                    1,527<br \/>\n                  <\/span> <span class=\"read-time\" data-v-0140422c><svg width=\"16\" height=\"16\" viewbox=\"0 0 16 16\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" data-v-0140422c><rect width=\"16\" height=\"16\" fill=\"none\" data-v-0140422c><\/rect><circle cx=\"8\" cy=\"8\" r=\"5.65625\" stroke=\"#8A919F\" data-v-0140422c><\/circle><path d=\"M7.69141 5.18652V8.30924H10.8141\" stroke=\"#8A919F\" stroke-linecap=\"round\" stroke-linejoin=\"round\" data-v-0140422c><\/path><\/svg><br \/>\n                    \u9605\u8bfb12\u5206\u949f<br \/>\n                  <\/span>\n<\/div>\n<\/div>\n<div style=\"flex:1;\" data-v-0140422c><\/div>\n<\/div>\n<div id=\"article-root\" itemprop=\"articleBody\" class=\"main\" data-v-0140422c>\n<div class=\"article-viewer markdown-body cache result\">\n<style>.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:16px;overflow-x:hidden;color:#252933}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.5;margin-top:35px;margin-bottom:10px;padding-bottom:5px}.markdown-body h1{font-size:24px;line-height:38px;margin-bottom:5px}.markdown-body h2{font-size:22px;line-height:34px;padding-bottom:12px;border-bottom:1px solid #ececec}.markdown-body h3{font-size:20px;line-height:28px}.markdown-body h4{font-size:18px;line-height:26px}.markdown-body h5{font-size:17px;line-height:24px}.markdown-body h6{font-size:16px;line-height:24px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img{max-width:100%}.markdown-body hr{border:none;border-top:1px solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break-word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size:12px;padding:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;color:#333;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border-bottom:1px solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth-child(2n){background-color:#fcfcfc}.markdown-body td,.markdown-body th{padding:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown-body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:\"\"}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px}.markdown-body .contains-task-list{padding-left:0}.markdown-body .task-list-item{list-style:none}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}<\/style>\n<style data-highlight data-highlight-key=\"juejin\">.markdown-body pre,.markdown-body pre>code.hljs{color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number,.hljs-tag .hljs-attr,.hljs-template-variable,.hljs-variable{color:teal}.hljs-doctag,.hljs-string{color:#d14}.hljs-section,.hljs-selector-id,.hljs-title{color:#900;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type{color:#458;font-weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-link,.hljs-regexp{color:#009926}.hljs-bullet,.hljs-symbol{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}<\/style>\n<p>mp.weixin.qq.com\/s?__biz=MzA\u2026<\/p>\n<p>\u5fae\u4fe1\u516c\u4f17\u53f7\uff0cWeMobileDev 2021\u5e747\u670819\u65e5\u53d1\u5e03\u7684 \u5fae\u4fe1Android\u5ba2\u6237\u7aef\u7684ANR\u76d1\u63a7\u65b9\u6848<\/p>\n<p>\u8be5\u65b9\u6848\u7684\u6240\u6709\u4ee3\u7801\u5df2\u7ecf\u5728Matrix(github.com\/Tencent\/mat\u2026<\/p>\n<h1 data-id=\"heading-0\">1.SignalAnrTracer onAlive\u65b9\u6cd5\u91cc\u8c03\u7528nativeInitSignalAnrDetective\u65b9\u6cd5\u76d1\u542cSIGQUIT\u4fe1\u53f7<\/h1>\n<pre><code class=\"hljs language-java\" lang=\"java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title class_\">SignalAnrTracer<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title class_\">Tracer<\/span> {\n    <span class=\"hljs-comment\">\/\/region \u53c2\u6570<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">String<\/span> <span class=\"hljs-variable\">TAG<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">\"SignalAnrTracer\"<\/span>;\n    <span class=\"hljs-comment\">\/\/\u68c0\u6d4banr\u7ebf\u7a0b\u540d\u5b57<\/span>\n    <span class=\"hljs-comment\">\/\/\u76d1\u63a7\u5230SIGQUIT\u540e\uff0c\u6211\u4eec\u572820\u79d2\u5185\uff0820\u79d2\u662fANR dump\u7684timeout\u65f6\u95f4\uff09\u4e0d\u65ad\u8f6e\u8be2\u81ea\u5df1\u662f\u5426\u6709NOT_RESPONDING flag<\/span>\n    <span class=\"hljs-comment\">\/\/\u4e00\u65e6\u53d1\u73b0\u6709\u8fd9\u4e2aflag\uff0c\u90a3\u4e48\u9a6c\u4e0a\u5c31\u53ef\u4ee5\u8ba4\u5b9a\u53d1\u751f\u4e86\u4e00\u6b21ANR\u3002<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">String<\/span> <span class=\"hljs-variable\">CHECK_ANR_STATE_THREAD_NAME<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">\"Check-ANR-State-Thread\"<\/span>;\n    <span class=\"hljs-comment\">\/\/\u68c0\u6d4bNOT_RESPONDING flag\u95f4\u9694\u65f6\u95f4<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">int<\/span> <span class=\"hljs-variable\">CHECK_ERROR_STATE_INTERVAL<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">500<\/span>;\n    <span class=\"hljs-comment\">\/\/dump\u6700\u957f\u65f6\u95f420s<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">int<\/span> <span class=\"hljs-variable\">ANR_DUMP_MAX_TIME<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">20000<\/span>;\n    <span class=\"hljs-comment\">\/\/\u68c0\u6d4berror\u6b21\u6570<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">int<\/span> <span class=\"hljs-variable\">CHECK_ERROR_STATE_COUNT<\/span> <span class=\"hljs-operator\">=<\/span>\n            ANR_DUMP_MAX_TIME \/ CHECK_ERROR_STATE_INTERVAL;\n    <span class=\"hljs-comment\">\/\/\u524d\u53f0\u6d88\u606f\uff0c\u8d85\u65f62s\u7684\u65f6\u5019\uff0c\u8bf4\u660e\u5361\u4f4f\u4e86<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">long<\/span> <span class=\"hljs-variable\">FOREGROUND_MSG_THRESHOLD<\/span> <span class=\"hljs-operator\">=<\/span> -<span class=\"hljs-number\">2000<\/span>;\n    <span class=\"hljs-comment\">\/\/\u540e\u53f0\u6d88\u606f\uff0c\u8d85\u65f62s\u7684\u65f6\u5019\uff0c\u8bf4\u660e\u5361\u4f4f\u4e86<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">long<\/span> <span class=\"hljs-variable\">BACKGROUND_MSG_THRESHOLD<\/span> <span class=\"hljs-operator\">=<\/span> -<span class=\"hljs-number\">10000<\/span>;\n    <span class=\"hljs-comment\">\/\/\u662f\u5426hasInstance<\/span>\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">boolean<\/span> <span class=\"hljs-variable\">hasInstance<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">false<\/span>;\n    <span class=\"hljs-comment\">\/\/\u662f\u5426\u662f\u524d\u53f0\u72b6\u6001<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">boolean<\/span> <span class=\"hljs-variable\">currentForeground<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">false<\/span>;\n    <span class=\"hljs-comment\">\/\/anr trace \u6587\u4ef6\u8def\u5f84<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">String<\/span> <span class=\"hljs-variable\">sAnrTraceFilePath<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">\"\"<\/span>;\n    <span class=\"hljs-comment\">\/\/    \u8fd9\u4e2aHook Trace\u7684\u65b9\u6848\uff0c\u4e0d\u4ec5\u4ec5\u53ef\u4ee5\u7528\u6765\u67e5ANR\u95ee\u9898\uff0c\u4efb\u4f55\u65f6\u5019\u6211\u4eec\u90fd\u53ef\u4ee5\u624b\u52a8\u5411\u81ea\u5df1\u53d1\u9001\u4e00\u4e2aSIGQUIT\u4fe1\u53f7\uff0c<\/span>\n<span class=\"hljs-comment\">\/\/    \u4ece\u800chook\u5230\u5f53\u65f6\u7684Trace\u3002Trace\u7684\u5185\u5bb9\u5bf9\u4e8e\u6211\u4eec\u6392\u67e5\u7ebf\u7a0b\u6b7b\u9501\uff0c\u7ebf\u7a0b\u5f02\u5e38\uff0c\u8017\u7535\u7b49\u95ee\u9898\u90fd\u975e\u5e38\u6709\u5e2e\u52a9\u3002<\/span>\n    <span class=\"hljs-comment\">\/\/\u6253\u5370trace \u6587\u4ef6\u8def\u5f84 \uff0c\u81ea\u5df1\u89e6\u53d1\u7684<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">String<\/span> <span class=\"hljs-variable\">sPrintTraceFilePath<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">\"\"<\/span>;\n    <span class=\"hljs-comment\">\/\/\u76d1\u542c<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> SignalAnrDetectedListener sSignalAnrDetectedListener;\n    <span class=\"hljs-comment\">\/\/sApplication<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> Application sApplication;\n    <span class=\"hljs-comment\">\/\/\u662f\u5426\u521d\u59cb\u5316\u4e86<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">boolean<\/span> <span class=\"hljs-variable\">hasInit<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">false<\/span>;\n    <span class=\"hljs-comment\">\/\/anr\u53d1\u751f\u65f6\u95f4\uff0c\u8d1f\u503c<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">long<\/span> <span class=\"hljs-variable\">anrMessageWhen<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">0L<\/span>;\n    <span class=\"hljs-comment\">\/\/anr\u53d1\u751f\u65f6\u4e3b\u7ebf\u7a0b\u5904\u7406\u7684\u6d88\u606f<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">String<\/span> <span class=\"hljs-variable\">anrMessageString<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">\"\"<\/span>;\n    <span class=\"hljs-comment\">\/\/endregion<\/span>\n\n    <span class=\"hljs-keyword\">static<\/span> {\n        <span class=\"hljs-comment\">\/\/\u52a0\u8f7dtrace-canary lib<\/span>\n        System.loadLibrary(<span class=\"hljs-string\">\"trace-canary\"<\/span>);\n    }\n\n    <span class=\"hljs-comment\">\/\/region \u6784\u9020\u51fd\u6570<\/span>\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title function_\">SignalAnrTracer<\/span><span class=\"hljs-params\">(TraceConfig traceConfig)<\/span> {\n        hasInstance = <span class=\"hljs-literal\">true<\/span>;\n        sAnrTraceFilePath = traceConfig.anrTraceFilePath;\n        sPrintTraceFilePath = traceConfig.printTraceFilePath;\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title function_\">SignalAnrTracer<\/span><span class=\"hljs-params\">(Application application)<\/span> {\n        hasInstance = <span class=\"hljs-literal\">true<\/span>;\n        sApplication = application;\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title function_\">SignalAnrTracer<\/span><span class=\"hljs-params\">(Application application, String anrTraceFilePath, String printTraceFilePath)<\/span> {\n        hasInstance = <span class=\"hljs-literal\">true<\/span>;\n        sAnrTraceFilePath = anrTraceFilePath;\n        sPrintTraceFilePath = printTraceFilePath;\n        sApplication = application;\n    }\n    <span class=\"hljs-comment\">\/\/endregion<\/span>\n\n    <span class=\"hljs-comment\">\/**\n     * AnrDumper.cc\u91cc handleSignal\n     *\/<\/span>\n    <span class=\"hljs-meta\">@RequiresApi(api = Build.VERSION_CODES.M)<\/span>\n    <span class=\"hljs-meta\">@Keep<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">onANRDumped<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-comment\">\/\/\u662f\u5426\u662f\u524d\u53f0<\/span>\n        currentForeground = AppForegroundUtil.isInterestingToUser();\n        <span class=\"hljs-comment\">\/\/\u662f\u5426\u662f\u4e3b\u7ebf\u7a0b\u5835\u585e\u4e86\uff0c\u9700\u8981report<\/span>\n        <span class=\"hljs-type\">boolean<\/span> <span class=\"hljs-variable\">needReport<\/span> <span class=\"hljs-operator\">=<\/span> isMainThreadBlocked();\n\n        <span class=\"hljs-comment\">\/\/\u6709\u4e24\u79cd\u60c5\u51b5\uff0c\u4e3b\u7ebf\u7a0b\u6d88\u606f\u5df2\u7ecf\u5835\u4f4f\u4e86\uff0c\u6216\u8005\u5f00\u542f\u4e00\u4e2a\u7ebf\u7a0b\u68c0\u6d4b\u72b6\u6001 NOT_RESPONDING<\/span>\n        <span class=\"hljs-comment\">\/\/\u9700\u8981report<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (needReport) {\n            report(<span class=\"hljs-literal\">false<\/span>);\n        } <span class=\"hljs-keyword\">else<\/span> {\n<span class=\"hljs-comment\">\/\/            \u76d1\u63a7\u5230SIGQUIT\u540e\uff0c\u6211\u4eec\u572820\u79d2\u5185\uff0820\u79d2\u662fANR dump\u7684timeout\u65f6\u95f4\uff09\u4e0d\u65ad\u8f6e\u8be2\u81ea\u5df1\u662f\u5426\u6709NOT_RESPONDING flag<\/span>\n<span class=\"hljs-comment\">\/\/            \uff0c\u4e00\u65e6\u53d1\u73b0\u6709\u8fd9\u4e2aflag\uff0c\u90a3\u4e48\u9a6c\u4e0a\u5c31\u53ef\u4ee5\u8ba4\u5b9a\u53d1\u751f\u4e86\u4e00\u6b21ANR\u3002<\/span>\n            <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">Thread<\/span>(<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">Runnable<\/span>() {\n                <span class=\"hljs-meta\">@Override<\/span>\n                <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">run<\/span><span class=\"hljs-params\">()<\/span> {\n                    <span class=\"hljs-comment\">\/\/\u5f00\u542f\u4e86\u4e00\u4e2a\u7ebf\u7a0b\u68c0\u67e5<\/span>\n                    checkErrorStateCycle();\n                }\n            }, CHECK_ANR_STATE_THREAD_NAME).start();\n        }\n    }\n\n    <span class=\"hljs-meta\">@Keep<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">onANRDumpTrace<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-keyword\">try<\/span> {\n            MatrixUtil.printFileByLine(TAG, sAnrTraceFilePath);\n        } <span class=\"hljs-keyword\">catch<\/span> (Throwable t) {\n            MatrixLog.e(TAG, <span class=\"hljs-string\">\"onANRDumpTrace error: %s\"<\/span>, t.getMessage());\n        }\n    }\n    <span class=\"hljs-comment\">\/\/endregion<\/span>\n\n    <span class=\"hljs-meta\">@Keep<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">onPrintTrace<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-keyword\">try<\/span> {\n            MatrixUtil.printFileByLine(TAG, sPrintTraceFilePath);\n        } <span class=\"hljs-keyword\">catch<\/span> (Throwable t) {\n            MatrixLog.e(TAG, <span class=\"hljs-string\">\"onPrintTrace error: %s\"<\/span>, t.getMessage());\n        }\n    }\n\n    <span class=\"hljs-comment\">\/**\n     * <span class=\"hljs-doctag\">@param<\/span> fromProcessErrorState false\u4ee3\u8868\u4e3b\u7ebf\u7a0b\u963b\u585e\u4e86\n     *\/<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">report<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">boolean<\/span> fromProcessErrorState)<\/span> {\n        <span class=\"hljs-keyword\">try<\/span> {\n            <span class=\"hljs-type\">String<\/span> <span class=\"hljs-variable\">stackTrace<\/span> <span class=\"hljs-operator\">=<\/span> Utils.getMainThreadJavaStackTrace();\n            <span class=\"hljs-keyword\">if<\/span> (sSignalAnrDetectedListener != <span class=\"hljs-literal\">null<\/span>) {\n                sSignalAnrDetectedListener.onAnrDetected(stackTrace, anrMessageString, anrMessageWhen, fromProcessErrorState);\n                <span class=\"hljs-keyword\">return<\/span>;\n            }\n\n            <span class=\"hljs-type\">TracePlugin<\/span> <span class=\"hljs-variable\">plugin<\/span> <span class=\"hljs-operator\">=<\/span> Matrix.with().getPluginByClass(TracePlugin.class);\n            <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-literal\">null<\/span> == plugin) {\n                <span class=\"hljs-keyword\">return<\/span>;\n            }\n\n            <span class=\"hljs-type\">String<\/span> <span class=\"hljs-variable\">scene<\/span> <span class=\"hljs-operator\">=<\/span> AppMethodBeat.getVisibleScene();\n\n            <span class=\"hljs-type\">JSONObject<\/span> <span class=\"hljs-variable\">jsonObject<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">JSONObject<\/span>();\n            jsonObject = DeviceUtil.getDeviceInfo(jsonObject, Matrix.with().getApplication());\n            jsonObject.put(SharePluginInfo.ISSUE_STACK_TYPE, Constants.Type.SIGNAL_ANR);\n            jsonObject.put(SharePluginInfo.ISSUE_SCENE, scene);\n            jsonObject.put(SharePluginInfo.ISSUE_THREAD_STACK, stackTrace);\n            jsonObject.put(SharePluginInfo.ISSUE_PROCESS_FOREGROUND, currentForeground);\n\n            <span class=\"hljs-type\">Issue<\/span> <span class=\"hljs-variable\">issue<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">Issue<\/span>();\n            issue.setTag(SharePluginInfo.TAG_PLUGIN_EVIL_METHOD);\n            issue.setContent(jsonObject);\n            plugin.onDetectIssue(issue);\n            MatrixLog.e(TAG, <span class=\"hljs-string\">\"happens real ANR : %s \"<\/span>, jsonObject.toString());\n\n        } <span class=\"hljs-keyword\">catch<\/span> (JSONException e) {\n            MatrixLog.e(TAG, <span class=\"hljs-string\">\"[JSONException error: %s\"<\/span>, e);\n        }\n    }\n\n    <span class=\"hljs-comment\">\/\/\u901a\u8fc7\u6d88\u606f\u65f6\u95f4\uff0c\u6765\u5224\u65ad\u662f\u5426\u5230\u8d85\u51fa\u9608\u503c<\/span>\n    <span class=\"hljs-meta\">@RequiresApi(api = Build.VERSION_CODES.M)<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">boolean<\/span> <span class=\"hljs-title function_\">isMainThreadBlocked<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-keyword\">try<\/span> {\n            <span class=\"hljs-type\">MessageQueue<\/span> <span class=\"hljs-variable\">mainQueue<\/span> <span class=\"hljs-operator\">=<\/span> Looper.getMainLooper().getQueue();\n            <span class=\"hljs-type\">Field<\/span> <span class=\"hljs-variable\">field<\/span> <span class=\"hljs-operator\">=<\/span> mainQueue.getClass().getDeclaredField(<span class=\"hljs-string\">\"mMessages\"<\/span>);\n            field.setAccessible(<span class=\"hljs-literal\">true<\/span>);\n            <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">Message<\/span> <span class=\"hljs-variable\">mMessage<\/span> <span class=\"hljs-operator\">=<\/span> (Message) field.get(mainQueue);\n            <span class=\"hljs-keyword\">if<\/span> (mMessage != <span class=\"hljs-literal\">null<\/span>) {\n                anrMessageString = mMessage.toString();\n                <span class=\"hljs-type\">long<\/span> <span class=\"hljs-variable\">when<\/span> <span class=\"hljs-operator\">=<\/span> mMessage.getWhen();\n                <span class=\"hljs-keyword\">if<\/span> (when == <span class=\"hljs-number\">0<\/span>) {\n                    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n                }\n                <span class=\"hljs-type\">long<\/span> <span class=\"hljs-variable\">time<\/span> <span class=\"hljs-operator\">=<\/span> when - SystemClock.uptimeMillis();\n                anrMessageWhen = time;\n                <span class=\"hljs-type\">long<\/span> <span class=\"hljs-variable\">timeThreshold<\/span> <span class=\"hljs-operator\">=<\/span> BACKGROUND_MSG_THRESHOLD;\n                <span class=\"hljs-keyword\">if<\/span> (currentForeground) {\n                    timeThreshold = FOREGROUND_MSG_THRESHOLD;\n                }\n                <span class=\"hljs-keyword\">return<\/span> time &lt; timeThreshold;\n            }\n        } <span class=\"hljs-keyword\">catch<\/span> (Exception e) {\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n        }\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n    }\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">checkErrorStateCycle<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-type\">int<\/span> <span class=\"hljs-variable\">checkErrorStateCount<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">0<\/span>;\n        <span class=\"hljs-comment\">\/\/\u5f00\u542f\u4e00\u4e2a\u5faa\u73af\u68c0\u6d4b<\/span>\n        <span class=\"hljs-keyword\">while<\/span> (checkErrorStateCount &lt; CHECK_ERROR_STATE_COUNT) {\n            <span class=\"hljs-keyword\">try<\/span> {\n                checkErrorStateCount++;\n                <span class=\"hljs-type\">boolean<\/span> <span class=\"hljs-variable\">myAnr<\/span> <span class=\"hljs-operator\">=<\/span> checkErrorState();\n                <span class=\"hljs-keyword\">if<\/span> (myAnr) {\n                    report(<span class=\"hljs-literal\">true<\/span>);\n                    <span class=\"hljs-keyword\">break<\/span>;\n                }\n\n                Thread.sleep(CHECK_ERROR_STATE_INTERVAL);\n            } <span class=\"hljs-keyword\">catch<\/span> (Throwable t) {\n                MatrixLog.e(TAG, <span class=\"hljs-string\">\"checkErrorStateCycle error, e : \"<\/span> + t.getMessage());\n                <span class=\"hljs-keyword\">break<\/span>;\n            }\n        }\n    }\n\n    <span class=\"hljs-comment\">\/\/\u7528\u6765\u5224\u65adanr\u53d1\u751f\u4e86<\/span>\n<span class=\"hljs-comment\">\/\/    \u5728ANR\u5f39\u7a97\u524d\uff0c\u4f1a\u6267\u884c\u5230makeAppNotRespondingLocked\u65b9\u6cd5\u4e2d\uff0c\u5728\u8fd9\u91cc\u4f1a\u7ed9\u53d1\u751fANR\u8fdb\u7a0b\u6807\u8bb0\u4e00\u4e2aNOT_RESPONDING\u7684flag\u3002<\/span>\n<span class=\"hljs-comment\">\/\/    \u800c\u8fd9\u4e2aflag\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7ActivityManager\u6765\u83b7\u53d6\uff1a<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-type\">boolean<\/span> <span class=\"hljs-title function_\">checkErrorState<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-keyword\">try<\/span> {\n            <span class=\"hljs-type\">Application<\/span> <span class=\"hljs-variable\">application<\/span> <span class=\"hljs-operator\">=<\/span>\n                    sApplication == <span class=\"hljs-literal\">null<\/span> ? Matrix.with().getApplication() : sApplication;\n            <span class=\"hljs-type\">ActivityManager<\/span> <span class=\"hljs-variable\">am<\/span> <span class=\"hljs-operator\">=<\/span> (ActivityManager) application\n                    .getSystemService(Context.ACTIVITY_SERVICE);\n            <span class=\"hljs-comment\">\/\/\u4eceActivityManager \u83b7\u53d6ProcessErrorStateInfo<\/span>\n            List procs = am.getProcessesInErrorState();\n            <span class=\"hljs-keyword\">if<\/span> (procs == <span class=\"hljs-literal\">null<\/span>) <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n\n            <span class=\"hljs-keyword\">for<\/span> (ActivityManager.ProcessErrorStateInfo proc : procs) {\n                MatrixLog.i(TAG, <span class=\"hljs-string\">\"[checkErrorState] found Error State proccessName = %s, proc.condition = %d\"<\/span>, proc.processName, proc.condition);\n\n                <span class=\"hljs-keyword\">if<\/span> (proc.uid != android.os.Process.myUid()\n                        &amp;&amp; proc.condition == ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING) {\n                    MatrixLog.i(TAG, <span class=\"hljs-string\">\"maybe received other apps ANR signal\"<\/span>);\n                }\n\n                <span class=\"hljs-keyword\">if<\/span> (proc.pid != android.os.Process.myPid()) <span class=\"hljs-keyword\">continue<\/span>;\n\n                <span class=\"hljs-keyword\">if<\/span> (proc.condition != ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING) {\n                    <span class=\"hljs-keyword\">continue<\/span>;\n                }\n                <span class=\"hljs-comment\">\/\/\u53ea\u6709\u662f\u81ea\u5df1\u8fdb\u7a0b\uff0c\u5e76\u4e14\u662fNOT_RESPONDING\u7684\u65f6\u5019\uff0c\u624d\u8fd4\u56detrue<\/span>\n                <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">true<\/span>;\n            }\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n        } <span class=\"hljs-keyword\">catch<\/span> (Throwable t) {\n            MatrixLog.e(TAG, <span class=\"hljs-string\">\"[checkErrorState] error : %s\"<\/span>, t.getMessage());\n        }\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ok<\/span>\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">printTrace<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-keyword\">if<\/span> (!hasInstance) {\n            MatrixLog.e(TAG, <span class=\"hljs-string\">\"SignalAnrTracer has not been initialize\"<\/span>);\n            <span class=\"hljs-keyword\">return<\/span>;\n        }\n        <span class=\"hljs-keyword\">if<\/span> (sPrintTraceFilePath.equals(<span class=\"hljs-string\">\"\"<\/span>)) {\n            MatrixLog.e(TAG, <span class=\"hljs-string\">\"PrintTraceFilePath has not been set\"<\/span>);\n            <span class=\"hljs-keyword\">return<\/span>;\n        }\n        nativePrintTrace();\n    }\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">native<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">nativeInitSignalAnrDetective<\/span><span class=\"hljs-params\">(String anrPrintTraceFilePath, String printTraceFilePath)<\/span>;\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">native<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">nativeFreeSignalAnrDetective<\/span><span class=\"hljs-params\">()<\/span>;\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">native<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">nativePrintTrace<\/span><span class=\"hljs-params\">()<\/span>;\n\n    <span class=\"hljs-meta\">@Override<\/span>\n    <span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">onAlive<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-built_in\">super<\/span>.onAlive();\n        <span class=\"hljs-keyword\">if<\/span> (!hasInit) {\n            <span class=\"hljs-comment\">\/\/\u8c03\u7528native\u65b9\u6cd5\u542f\u52a8\u76d1\u542c<\/span>\n            nativeInitSignalAnrDetective(sAnrTraceFilePath, sPrintTraceFilePath);\n            <span class=\"hljs-comment\">\/\/\u4e3b\u8981\u7528\u6765\u5224\u65ad\u662f\u5426\u662f\u524d\u53f0<\/span>\n            AppForegroundUtil.INSTANCE.init();\n            hasInit = <span class=\"hljs-literal\">true<\/span>;\n        }\n    }\n\n    <span class=\"hljs-meta\">@Override<\/span>\n    <span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">onDead<\/span><span class=\"hljs-params\">()<\/span> {\n        <span class=\"hljs-built_in\">super<\/span>.onDead();\n        <span class=\"hljs-comment\">\/\/free anr\u68c0\u6d4b<\/span>\n        nativeFreeSignalAnrDetective();\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">setSignalAnrDetectedListener<\/span><span class=\"hljs-params\">(SignalAnrDetectedListener listener)<\/span> {\n        sSignalAnrDetectedListener = listener;\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title class_\">SignalAnrDetectedListener<\/span> {\n        <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title function_\">onAnrDetected<\/span><span class=\"hljs-params\">(String stackTrace, String mMessageString, <span class=\"hljs-type\">long<\/span> mMessageWhen, <span class=\"hljs-type\">boolean<\/span> fromProcessErrorState)<\/span>;\n    }\n}\n<\/code><\/pre>\n<h1 data-id=\"heading-1\">2.MatrixTracer.cc<\/h1>\n<h2 data-id=\"heading-2\">2.1 JNI_OnLoad\u521d\u59cb\u5316\uff0c\u53cc\u5411\u7ed1\u5b9a\u51fd\u6570<\/h2>\n<h2 data-id=\"heading-3\">2.2 nativeInitSignalAnrDetective\uff0c\u5f00\u542f\u68c0\u6d4b\uff0c\u771f\u6b63\u68c0\u6d4b\u7684\u5730\u65b9\u5728AnrDumper.cc<\/h2>\n<h2 data-id=\"heading-4\">2.3 AnrDumper.cc \u91cchandleSignal\u91cc\u8c03\u7528MatrixTracer anrDumpCallback \uff0c\u8868\u793aanr\u53ef\u80fd\u53d1\u751f\u4e86\uff0c\u901a\u77e5SignalAnrTracer\u68c0\u6d4bui\u7ebf\u7a0b\u662f\u5426block\u6216\u8005\u72b6\u6001\u4e3aNOT_RESPONDING\u3002\u5e76\u8c03\u7528hookAnrTraceWrite\u65b9\u6cd5\uff0c\u5f00\u542fhook\uff0c\u4e3a\u4e86\u627e\u5230write trace\u7684\u70b9<\/h2>\n<h2 data-id=\"heading-5\">2.4 my_connect,my_open\u662f\u5f00\u59cbsocket\u901a\u4fe1\u4e86\uff0c\u4e3b\u8981\u4e3a\u4e86\u68c0\u6d4bsocket\u901a\u4fe1\u4e4b\u540e\u7684write\u65b9\u6cd5<\/h2>\n<h2 data-id=\"heading-6\">2.5 my_write\u662f\u6211\u4eec\u7684write\u65b9\u6cd5<\/h2>\n<pre><code class=\"hljs language-scss\" lang=\"scss\"><span class=\"hljs-selector-id\">#define<\/span> PROP_VALUE_MAX  <span class=\"hljs-number\">92<\/span>                      <span class=\"hljs-comment\">\/\/\u7528\u4e8e\u6c42getApiLevel<\/span>\n<span class=\"hljs-selector-id\">#define<\/span> PROP_SDK_NAME \"ro<span class=\"hljs-selector-class\">.build<\/span><span class=\"hljs-selector-class\">.version<\/span><span class=\"hljs-selector-class\">.sdk<\/span>\"    <span class=\"hljs-comment\">\/\/\u7528\u4e8e\u6c42getApiLevel<\/span>\n<span class=\"hljs-selector-id\">#define<\/span> HOOK_CONNECT_PATH \"\/dev\/socket\/tombstoned_java_trace\"   <span class=\"hljs-comment\">\/\/socket\u6587\u4ef6\u5730\u5740<\/span>\n<span class=\"hljs-selector-id\">#define<\/span> HOOK_OPEN_PATH \"\/data\/anr\/traces<span class=\"hljs-selector-class\">.txt<\/span>\"                   <span class=\"hljs-comment\">\/\/socket\u6587\u4ef6\u5730\u5740<\/span>\n\nusing namespace MatrixTracer;\n\nstatic std::optional sAnrDumper; <span class=\"hljs-comment\">\/\/AnrDumper\uff0c\u662f\u81ea\u5b9a\u4e49\u7684SignalHandler<\/span>\nstatic bool isTraceWrite = false;           <span class=\"hljs-comment\">\/\/isTraceWrite my_connect my_open\u8bbe\u7f6e\u4e3atrue\uff0cmy_write\u8bbe\u7f6e\u4e3afalse<\/span>\nstatic bool fromMyPrintTrace = false;       <span class=\"hljs-comment\">\/\/fromMyPrintTrace \u662f\u5426\u662f\u81ea\u5df1\u60f3\u6253\u7684<\/span>\nstatic bool isHooking = false;              <span class=\"hljs-comment\">\/\/\u662f\u5426hooking\uff0cunHookAnrTraceWrite\u8bbe\u7f6e\u4e3afalse<\/span>\nstatic std::string anrTracePathstring;      <span class=\"hljs-comment\">\/\/\u65b0\u7684anrTracePathstring\uff0c\u7cfb\u7edf\u7528\u7684<\/span>\nstatic std::string printTracePathstring;    <span class=\"hljs-comment\">\/\/\u65b0\u7684printTracePathstring\uff0c\u6211\u81ea\u5df1\u60f3\u6253\u5370\u7684\u65f6\u5019\u7528\u7684<\/span>\nstatic int signalCatcherTid;                <span class=\"hljs-comment\">\/\/signalCatcherTid\u7684\u7ebf\u7a0bid<\/span>\n\n<span class=\"hljs-comment\">\/\/\u4e00\u4e2a\u7ed3\u6784\u4f53\uff0c\u7528\u6765\u4fdd\u5b58java\u5c42 \u7c7b\uff0c\u65b9\u6cd5\u5730\u5740<\/span>\nstatic struct StacktraceJNI {\n    jclass AnrDetective;                    <span class=\"hljs-comment\">\/\/SignalAnrTracer<\/span>\n    jclass ThreadPriorityDetective;\n    jmethodID AnrDetector_onANRDumped;      <span class=\"hljs-comment\">\/\/SignalAnrTracer \u91cc\u7684<\/span>\n    jmethodID AnrDetector_onANRDumpTrace;   <span class=\"hljs-comment\">\/\/SignalAnrTracer \u91cc\u7684<\/span>\n    jmethodID AnrDetector_onPrintTrace;     <span class=\"hljs-comment\">\/\/SignalAnrTracer \u91cc\u7684<\/span>\n\n    jmethodID ThreadPriorityDetective_onMainThreadPriorityModified;\n    jmethodID ThreadPriorityDetective_onMainThreadTimerSlackModified;\n} gJ;\n\n<span class=\"hljs-comment\">\/\/region MainThreadPriorityModified\u76f8\u5173\u7684\u4e1c\u897f<\/span>\nint (*original_setpriority)(int __which, id_t __who, int __priority);\n\nint <span class=\"hljs-built_in\">my_setpriority<\/span>(int __which, id_t __who, int __priority) {\n\n    if (__priority &lt;= <span class=\"hljs-number\">0<\/span>) {\n        return <span class=\"hljs-built_in\">original_setpriority<\/span>(__which, __who, __priority);\n    }\n    if (__who == <span class=\"hljs-number\">0<\/span> &amp;&amp; getpid() == <span class=\"hljs-built_in\">gettid<\/span>()) {\n        JNIEnv *env = JniInvocation::<span class=\"hljs-built_in\">getEnv<\/span>();\n        env-&gt;<span class=\"hljs-built_in\">CallStaticVoidMethod<\/span>(gJ.ThreadPriorityDetective,\n                                  gJ.ThreadPriorityDetective_onMainThreadPriorityModified,\n                                  __priority);\n    } else if (__who == getpid()) {\n        JNIEnv *env = JniInvocation::<span class=\"hljs-built_in\">getEnv<\/span>();\n        env-&gt;<span class=\"hljs-built_in\">CallStaticVoidMethod<\/span>(gJ.ThreadPriorityDetective,\n                                  gJ.ThreadPriorityDetective_onMainThreadPriorityModified,\n                                  __priority);\n    }\n\n    return <span class=\"hljs-built_in\">original_setpriority<\/span>(__which, __who, __priority);\n}\n\nint (*original_prctl)(int option, unsigned long arg2, unsigned long arg3,\n                      unsigned long arg4, unsigned long arg5);\n\nint <span class=\"hljs-built_in\">my_prctl<\/span>(int option, unsigned long arg2, unsigned long arg3,\n             unsigned long arg4, unsigned long arg5) {\n\n    if (option == PR_SET_TIMERSLACK) {\n        if (gettid() == <span class=\"hljs-built_in\">getpid<\/span>() &amp;&amp; arg2 &gt; <span class=\"hljs-number\">50000<\/span>) {\n            JNIEnv *env = JniInvocation::<span class=\"hljs-built_in\">getEnv<\/span>();\n            env-&gt;<span class=\"hljs-built_in\">CallStaticVoidMethod<\/span>(gJ.ThreadPriorityDetective,\n                                      gJ.ThreadPriorityDetective_onMainThreadTimerSlackModified,\n                                      arg2);\n\n        }\n    }\n\n    return <span class=\"hljs-built_in\">original_prctl<\/span>(option, arg2, arg3, arg4, arg5);\n}\n<span class=\"hljs-comment\">\/\/endregion<\/span>\n\n<span class=\"hljs-comment\">\/**\n *\n * @param content \u5185\u5bb9\n * @param filePath \u6587\u4ef6\u5730\u5740\n *\/<\/span>\nvoid <span class=\"hljs-built_in\">writeAnr<\/span>(const std::string &amp;content, const std::string &amp;filePath) {\n    <span class=\"hljs-comment\">\/\/unhook write<\/span>\n    <span class=\"hljs-built_in\">unHookAnrTraceWrite<\/span>();\n    std::stringstream <span class=\"hljs-built_in\">stringStream<\/span>(content);\n    std::string to;\n    std::ofstream outfile;\n    outfile<span class=\"hljs-selector-class\">.open<\/span>(filePath);\n    outfile &lt;&lt; <span class=\"hljs-attribute\">content<\/span>;\n}\n\n<span class=\"hljs-comment\">\/\/region my_connect  original_connect<\/span>\nint (*original_connect)(int __fd, const struct sockaddr *__addr, socklen_t __addr_length);\n\nint <span class=\"hljs-built_in\">my_connect<\/span>(int __fd, const struct sockaddr *__addr, socklen_t __addr_length) {\n    if (__addr != nullptr) {\n        <span class=\"hljs-comment\">\/\/hook connect\u65b9\u6cd5\uff0c\u68c0\u6d4bsockaddr\u5730\u5740\u662f\u5426\u4e3aHOOK_CONNECT_PATH\uff0c\u8868\u660e\u662fsignal\u68c0\u6d4b\u7ebf\u7a0b<\/span>\n        if (strcmp(__addr-&gt;sa_data, HOOK_CONNECT_PATH) == <span class=\"hljs-number\">0<\/span>) {\n            <span class=\"hljs-comment\">\/\/\u8bbe\u7f6esignal\u68c0\u6d4b\u7ebf\u7a0bid<\/span>\n            signalCatcherTid = <span class=\"hljs-built_in\">gettid<\/span>();\n            <span class=\"hljs-comment\">\/\/\u6807\u8bb0\u5f00\u59cb\u6253\u5370<\/span>\n            isTraceWrite = true;\n        }\n    }\n    return <span class=\"hljs-built_in\">original_connect<\/span>(__fd, __addr, __addr_length);\n}\n<span class=\"hljs-comment\">\/\/endregion<\/span>\n\n<span class=\"hljs-comment\">\/\/region my_open original_open<\/span>\nint (*original_open)(const char *pathname, int flags, mode_t mode);\n\nint <span class=\"hljs-built_in\">my_open<\/span>(const char *pathname, int flags, mode_t mode) {\n    if (pathname != nullptr) {\n        <span class=\"hljs-comment\">\/\/hook connect\u65b9\u6cd5\uff0c\u68c0\u6d4bsockaddr\u5730\u5740\u662f\u5426\u4e3aHOOK_OPEN_PATH\uff0c\u8868\u660e\u662fsignal\u68c0\u6d4b\u7ebf\u7a0b<\/span>\n        if (strcmp(pathname, HOOK_OPEN_PATH) == <span class=\"hljs-number\">0<\/span>) {\n            <span class=\"hljs-comment\">\/\/\u8bbe\u7f6esignal\u68c0\u6d4b\u7ebf\u7a0bid<\/span>\n            signalCatcherTid = <span class=\"hljs-built_in\">gettid<\/span>();\n            <span class=\"hljs-comment\">\/\/\u6807\u8bb0\u5f00\u59cb\u6253\u5370<\/span>\n            isTraceWrite = true;\n        }\n    }\n    return <span class=\"hljs-built_in\">original_open<\/span>(pathname, flags, mode);\n}\n<span class=\"hljs-comment\">\/\/endregion<\/span>\n\n<span class=\"hljs-comment\">\/\/region original_write my_write<\/span>\nssize_t (*original_write)(int fd, const void *const __pass_object_size0 buf, size_t count);\n\nssize_t <span class=\"hljs-built_in\">my_write<\/span>(int fd, const void *const buf, size_t count) {\n    <span class=\"hljs-comment\">\/\/\u5982\u679c\u6807\u8bb0\u4e3aisTraceWrite\u4e3atrue\uff0c\u7b2c\u4e00\u4e2asignalCatcher\u7ebf\u7a0b\uff0cwrite\u8c03\u7528\u5373\u4e3a\u6253\u5370trace\u7684\u5730\u65b9<\/span>\n    if (isTraceWrite &amp;&amp; gettid() == signalCatcherTid) {\n        isTraceWrite = false;\n        signalCatcherTid = <span class=\"hljs-number\">0<\/span>;\n        if (buf != nullptr) {\n            std::string targetFilePath;\n            if (fromMyPrintTrace) {\n                targetFilePath = printTracePathstring;\n            } else {\n                targetFilePath = anrTracePathstring;\n            }\n            if (!targetFilePath.empty()) {\n                char *<span class=\"hljs-attribute\">content<\/span> = (char *) buf;\n                <span class=\"hljs-built_in\">writeAnr<\/span>(content, targetFilePath);\n                if (!fromMyPrintTrace) {\n                    <span class=\"hljs-built_in\">anrDumpTraceCallback<\/span>();\n                } else {\n                    <span class=\"hljs-built_in\">printTraceCallback<\/span>();\n                }\n                fromMyPrintTrace = false;\n            }\n        }\n    }\n    return <span class=\"hljs-built_in\">original_write<\/span>(fd, buf, count);\n}\n<span class=\"hljs-comment\">\/\/endregion<\/span>\n\n<span class=\"hljs-comment\">\/\/\u8c03\u7528java\u7684onANRDumped\uff0cAnrDumper.cc \u91cchandleSignal\u91cc\u8c03\u7528anrCallback\u7136\u540e\u8c03\u7528\u8fd9\u4e2aanrDumpCallback\u56de\u8c03<\/span>\nbool <span class=\"hljs-built_in\">anrDumpCallback<\/span>() {\n    JNIEnv *env = JniInvocation::<span class=\"hljs-built_in\">getEnv<\/span>();\n    if (!env) return false;\n    env-&gt;<span class=\"hljs-built_in\">CallStaticVoidMethod<\/span>(gJ.AnrDetective, gJ.AnrDetector_onANRDumped);\n    return true;\n}\n\n<span class=\"hljs-comment\">\/\/\u8c03\u7528java\u7684onANRDumpTrace\uff0cmy_write\u91cc\u8c03\u7528<\/span>\nbool <span class=\"hljs-built_in\">anrDumpTraceCallback<\/span>() {\n    JNIEnv *env = JniInvocation::<span class=\"hljs-built_in\">getEnv<\/span>();\n    if (!env) return false;\n    env-&gt;<span class=\"hljs-built_in\">CallStaticVoidMethod<\/span>(gJ.AnrDetective, gJ.AnrDetector_onANRDumpTrace);\n    return true;\n}\n\n<span class=\"hljs-comment\">\/\/\u8c03\u7528java\u7684onPrintTrace\uff0cmy_write\u91cc\u8c03\u7528<\/span>\nbool <span class=\"hljs-built_in\">printTraceCallback<\/span>() {\n    JNIEnv *env = JniInvocation::<span class=\"hljs-built_in\">getEnv<\/span>();\n    if (!env) return false;\n    env-&gt;<span class=\"hljs-built_in\">CallStaticVoidMethod<\/span>(gJ.AnrDetective, gJ.AnrDetector_onPrintTrace);\n    return true;\n}\n\n<span class=\"hljs-comment\">\/\/ok<\/span>\nint <span class=\"hljs-built_in\">getApiLevel<\/span>() {\n    char buf<span class=\"hljs-selector-attr\">[PROP_VALUE_MAX]<\/span>;\n    int len = <span class=\"hljs-built_in\">__system_property_get<\/span>(PROP_SDK_NAME, buf);\n    if (len &lt;= <span class=\"hljs-number\">0<\/span>)\n        return <span class=\"hljs-number\">0<\/span>;\n\n    return <span class=\"hljs-built_in\">atoi<\/span>(buf);\n}\n\n<span class=\"hljs-comment\">\/**\n * @param isSiUser true\u4e3a\u81ea\u5df1\u7684\u8fdb\u7a0b\n * AnrDumper.cc \u91cchandleSignal\u91cc\u8c03\u7528anrCallback\u65b9\u6cd5\uff0c\u6216\u8005\u8c03\u7528siUserCallback\uff0c\u7136\u540e\u8c03\u7528\u8fd9\u4e2ahookAnrTraceWrite\u56de\u8c03\n *\/<\/span>\nvoid <span class=\"hljs-built_in\">hookAnrTraceWrite<\/span>(bool isSiUser) {\n    int apiLevel = <span class=\"hljs-built_in\">getApiLevel<\/span>();\n    if (apiLevel &lt; <span class=\"hljs-number\">19<\/span>) {\n        return;\n    }\n\n    <span class=\"hljs-comment\">\/\/isSiUser\u4e3atrue\uff0c\u8868\u793a\u81ea\u5df1\u8fdb\u7a0b\u53d1\u7684\u65f6\u5019\u662f\u901a\u8fc7kill\u53d1\u7684\uff0c\u6b64\u5904\u4e0d\u7b26\u5408\u903b\u8f91\uff0c\u8fd4\u56de<\/span>\n    if (!fromMyPrintTrace &amp;&amp; isSiUser) {\n        return;\n    }\n\n    if (isHooking) {\n        return;\n    }\n\n    isHooking = true;\n\n    if (apiLevel &gt;= <span class=\"hljs-number\">27<\/span>) {\n        void *libcutils_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"\/system\/lib64\/libcutils.so\");\n        if (!libcutils_info) {\n            libcutils_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"\/system\/lib\/libcutils.so\");\n        }\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libcutils_info, \"connect\", (void *) my_connect,\n                          (void **) (&amp;original_connect));\n    } else {\n        void *libart_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"libart.so\");\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libart_info, \"open\", (void *) my_open, (void **) (&amp;original_open));\n    }\n\n    if (apiLevel &gt;= <span class=\"hljs-number\">30<\/span> || apiLevel == <span class=\"hljs-number\">25<\/span> || apiLevel == <span class=\"hljs-number\">24<\/span>) {\n        void *libc_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"libc.so\");\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libc_info, \"write\", (void *) my_write, (void **) (&amp;original_write));\n    } else if (apiLevel == <span class=\"hljs-number\">29<\/span>) {\n        void *libbase_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"\/system\/lib64\/libbase.so\");\n        if (!libbase_info) {\n            libbase_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"\/system\/lib\/libbase.so\");\n        }\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libbase_info, \"write\", (void *) my_write, (void **) (&amp;original_write));\n        <span class=\"hljs-built_in\">xhook_elf_close<\/span>(libbase_info);\n    } else {\n        void *libart_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"libart.so\");\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libart_info, \"write\", (void *) my_write, (void **) (&amp;original_write));\n    }\n}\n\n<span class=\"hljs-comment\">\/\/unhook<\/span>\nvoid <span class=\"hljs-built_in\">unHookAnrTraceWrite<\/span>() {\n    int apiLevel = <span class=\"hljs-built_in\">getApiLevel<\/span>();\n    if (apiLevel &gt;= <span class=\"hljs-number\">27<\/span>) {\n        void *libcutils_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"\/system\/lib64\/libcutils.so\");\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libcutils_info, \"connect\", (void *) original_connect, nullptr);\n    } else {\n        void *libart_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"libart.so\");\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libart_info, \"open\", (void *) original_connect, nullptr);\n    }\n\n    if (apiLevel &gt;= <span class=\"hljs-number\">30<\/span> || apiLevel == <span class=\"hljs-number\">25<\/span> || apiLevel == <span class=\"hljs-number\">24<\/span>) {\n        void *libc_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"libc.so\");\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libc_info, \"write\", (void *) original_write, nullptr);\n    } else if (apiLevel == <span class=\"hljs-number\">29<\/span>) {\n        void *libbase_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"\/system\/lib64\/libbase.so\");\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libbase_info, \"write\", (void *) original_write, nullptr);\n    } else {\n        void *libart_info = <span class=\"hljs-built_in\">xhook_elf_open<\/span>(\"libart.so\");\n        <span class=\"hljs-built_in\">xhook_hook_symbol<\/span>(libart_info, \"write\", (void *) original_write, nullptr);\n    }\n    isHooking = false;\n}\n\n<span class=\"hljs-comment\">\/\/\u521d\u59cb\u5316\uff0c\u5f00\u542f\u68c0\u6d4bSignalanr\u68c0\u6d4b\uff0c\u771f\u6b63\u68c0\u6d4b\u7684\u5730\u65b9\u5728AnrDumper.cc<\/span>\nstatic void\n<span class=\"hljs-built_in\">nativeInitSignalAnrDetective<\/span>(JNIEnv *env, jclass, jstring anrTracePath, jstring printTracePath) {\n    <span class=\"hljs-comment\">\/\/anr\u53d1\u751f\u65f6\uff0c\u6253\u5370path<\/span>\n    const char *anrTracePathChar = env-&gt;<span class=\"hljs-built_in\">GetStringUTFChars<\/span>(anrTracePath, nullptr);\n    <span class=\"hljs-comment\">\/\/\u624b\u52a8\u53d1\u9001SIGQUIT\uff0c\u6253\u5370\u7684trace\u5730\u5740<\/span>\n    const char *printTracePathChar = env-&gt;<span class=\"hljs-built_in\">GetStringUTFChars<\/span>(printTracePath, nullptr);\n    anrTracePathstring = std::<span class=\"hljs-built_in\">string<\/span>(anrTracePathChar);\n    printTracePathstring = std::<span class=\"hljs-built_in\">string<\/span>(printTracePathChar);\n    <span class=\"hljs-comment\">\/\/\u5f00\u542f\u68c0\u6d4b\uff0c\u771f\u6b63\u68c0\u6d4b\u7684\u5730\u65b9\u5728AnrDumper.cc<\/span>\n    sAnrDumper<span class=\"hljs-selector-class\">.emplace<\/span>(anrTracePathChar, printTracePathChar, anrDumpCallback);\n}\n\n<span class=\"hljs-comment\">\/\/Free Signal Anr Detective \u91cd\u7f6e\uff0c\u91ca\u653e<\/span>\nstatic void <span class=\"hljs-built_in\">nativeFreeSignalAnrDetective<\/span>(JNIEnv *env, jclass) {\n    <span class=\"hljs-comment\">\/\/\u91cd\u7f6e\uff0c\u91ca\u653e<\/span>\n    sAnrDumper<span class=\"hljs-selector-class\">.reset<\/span>();\n}\n\n<span class=\"hljs-comment\">\/\/region MainThreadPriority\u76f8\u5173 \uff0c\u5148\u4e0d\u770b<\/span>\nstatic void <span class=\"hljs-built_in\">nativeInitMainThreadPriorityDetective<\/span>(JNIEnv *env, jclass) {\n    <span class=\"hljs-built_in\">xhook_register<\/span>(\".*\\.so$\", \"setpriority\", (void *) my_setpriority,\n                   (void **) (&amp;original_setpriority));\n    <span class=\"hljs-built_in\">xhook_register<\/span>(\".*\\.so$\", \"prctl\", (void *) my_prctl, (void **) (&amp;original_prctl));\n    <span class=\"hljs-built_in\">xhook_refresh<\/span>(true);\n}\n<span class=\"hljs-comment\">\/\/endregion<\/span>\n\n<span class=\"hljs-comment\">\/\/\u81ea\u5df1\u6253\u5370trace\uff0c\u53d1\u9001\u81ea\u5df1\u7684\u8fdb\u7a0b\u53d1\u9001SIGQUIT<\/span>\nstatic void <span class=\"hljs-built_in\">nativePrintTrace<\/span>() {\n    fromMyPrintTrace = true;\n    <span class=\"hljs-built_in\">kill<\/span>(getpid(), SIGQUIT);\n}\n\ntemplate<typename t std::size_t sz>\/\/todo\nstatic inline constexpr std::size_t <span class=\"hljs-built_in\">NELEM<\/span>(const <span class=\"hljs-built_in\">T<\/span>(&amp;)[sz]) { return sz; }<span class=\"hljs-comment\">\/\/todo<\/span>\n\n<span class=\"hljs-comment\">\/\/JNINativeMethod \u6570\u7ec4 anr\u76f8\u5173\u7684<\/span>\nstatic const JNINativeMethod ANR_METHODS<span class=\"hljs-selector-attr\">[]<\/span> = {\n        {\"nativeInitSignalAnrDetective\", \"(Ljava\/lang\/String;Ljava\/lang\/String;)V\", (void *) nativeInitSignalAnrDetective},\n        {\"nativeFreeSignalAnrDetective\", \"()V\",                                     (void *) nativeFreeSignalAnrDetective},\n        {\"nativePrintTrace\",             \"()V\",                                     (void *) nativePrintTrace},\n};\n\n<span class=\"hljs-comment\">\/\/MainThreadPriority\u76f8\u5173\u7684\uff0c\u5148\u4e0d\u770b<\/span>\nstatic const JNINativeMethod THREAD_PRIORITY_METHODS<span class=\"hljs-selector-attr\">[]<\/span> = {\n        {\"nativeInitMainThreadPriorityDetective\", \"()V\", (void *) nativeInitMainThreadPriorityDetective},\n};\n\n<span class=\"hljs-comment\">\/\/JNI_OnLoad \u521d\u59cb\u5316jni\u73af\u5883<\/span>\nJNIEXPORT jint JNICALL <span class=\"hljs-built_in\">JNI_OnLoad<\/span>(JavaVM *vm, void *) {\n    JniInvocation::<span class=\"hljs-built_in\">init<\/span>(vm);\n\n    JNIEnv *env;\n    <span class=\"hljs-comment\">\/\/\u83b7\u53d6env\u73af\u5883\uff0c\u5982\u679cenv\u73af\u5883\u6ca1\u6709\u83b7\u53d6\u6210\u529f\uff0c\u8fd4\u56de-1<\/span>\n    if (vm-&gt;GetEnv(reinterpret_cast<void>(&amp;env), JNI_VERSION_1_6) != JNI_OK)\n        return -<span class=\"hljs-number\">1<\/span>;\n\n    <span class=\"hljs-comment\">\/\/\u83b7\u53d6SignalAnrTracer\u53d8\u4e3ajclass<\/span>\n    jclass anrDetectiveCls = env-&gt;<span class=\"hljs-built_in\">FindClass<\/span>(\"com\/tencent\/matrix\/trace\/tracer\/SignalAnrTracer\");\n    if (!anrDetectiveCls)\n        return -<span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-comment\">\/\/\u4fdd\u5b58SignalAnrTracer\u4e3ajclass<\/span>\n    gJ<span class=\"hljs-selector-class\">.AnrDetective<\/span> = static_cast<jclass>(env-&gt;NewGlobalRef(anrDetectiveCls));\n    <span class=\"hljs-comment\">\/\/\u4fdd\u5b58\u65b9\u6cd5<\/span>\n    gJ<span class=\"hljs-selector-class\">.AnrDetector_onANRDumped<\/span> =\n            env-&gt;<span class=\"hljs-built_in\">GetStaticMethodID<\/span>(anrDetectiveCls, \"onANRDumped\", \"()V\");\n    gJ<span class=\"hljs-selector-class\">.AnrDetector_onANRDumpTrace<\/span> =\n            env-&gt;<span class=\"hljs-built_in\">GetStaticMethodID<\/span>(anrDetectiveCls, \"onANRDumpTrace\", \"()V\");\n    gJ<span class=\"hljs-selector-class\">.AnrDetector_onPrintTrace<\/span> =\n            env-&gt;<span class=\"hljs-built_in\">GetStaticMethodID<\/span>(anrDetectiveCls, \"onPrintTrace\", \"()V\");\n\n    <span class=\"hljs-comment\">\/\/\u6ce8\u518cnative\u65b9\u6cd5\uff0c\u4f7f\u5f97java\u53ef\u4ee5\u8c03\u7528native<\/span>\n    if (env-&gt;RegisterNatives(\n            anrDetectiveCls, ANR_METHODS, static_cast<jint>(NELEM(ANR_METHODS))) != <span class=\"hljs-number\">0<\/span>)\n        return -<span class=\"hljs-number\">1<\/span>;\n\n    <span class=\"hljs-comment\">\/\/\u5220\u9664anrDetectiveCls<\/span>\n    env-&gt;<span class=\"hljs-built_in\">DeleteLocalRef<\/span>(anrDetectiveCls);\n\n    jclass threadPriorityDetectiveCls = env-&gt;<span class=\"hljs-built_in\">FindClass<\/span>(\n            \"com\/tencent\/matrix\/trace\/tracer\/ThreadPriorityTracer\");\n    if (!threadPriorityDetectiveCls)\n        return -<span class=\"hljs-number\">1<\/span>;\n    gJ<span class=\"hljs-selector-class\">.ThreadPriorityDetective<\/span> = static_cast<jclass>(env-&gt;NewGlobalRef(threadPriorityDetectiveCls));\n    gJ<span class=\"hljs-selector-class\">.ThreadPriorityDetective_onMainThreadPriorityModified<\/span> =\n            env-&gt;<span class=\"hljs-built_in\">GetStaticMethodID<\/span>(threadPriorityDetectiveCls, \"onMainThreadPriorityModified\",\n                                   \"(I)V\");\n    gJ<span class=\"hljs-selector-class\">.ThreadPriorityDetective_onMainThreadTimerSlackModified<\/span> =\n            env-&gt;<span class=\"hljs-built_in\">GetStaticMethodID<\/span>(threadPriorityDetectiveCls, \"onMainThreadTimerSlackModified\",\n                                   \"(J)V\");\n\n    if (env-&gt;RegisterNatives(\n            threadPriorityDetectiveCls, THREAD_PRIORITY_METHODS,\n            static_cast<jint>(NELEM(THREAD_PRIORITY_METHODS))) != <span class=\"hljs-number\">0<\/span>)\n        return -<span class=\"hljs-number\">1<\/span>;\n\n    env-&gt;<span class=\"hljs-built_in\">DeleteLocalRef<\/span>(threadPriorityDetectiveCls);\n\n    return JNI_VERSION_1_6;\n}   <span class=\"hljs-comment\">\/\/ namespace MatrixTracer<\/span>\n<\/jint><\/jclass><\/jint><\/jclass><\/void><\/typename><\/code><\/pre>\n<h1 data-id=\"heading-7\">3.AnrDumper.h \u5b9a\u4e49AnrDumper\uff0c\u7ee7\u627fSignalHandler<\/h1>\n<pre><code class=\"hljs language-arduino\" lang=\"arduino\"><span class=\"hljs-keyword\">namespace<\/span> MatrixTracer {\n\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title class_\">AnrDumper<\/span> : <span class=\"hljs-keyword\">public<\/span> SignalHandler {\n <span class=\"hljs-keyword\">public<\/span>:\n    <span class=\"hljs-comment\">\/\/\u5b9a\u4e49\u56de\u8c03\u65b9\u6cd5<\/span>\n    <span class=\"hljs-keyword\">using<\/span> DumpCallbackFunction = std::function&lt;<span class=\"hljs-built_in\">bool<\/span>()&gt;;\n\n    <span class=\"hljs-built_in\">AnrDumper<\/span>(<span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">char<\/span>* anrTraceFile, <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">char<\/span>* printTraceFile, DumpCallbackFunction&amp;&amp; callback);<span class=\"hljs-comment\">\/\/&amp;&amp;\u5f15\u7528\u3002\u8fd9\u4e2a\u529f\u80fd\u662fC++\u7684\u8865\u5145\uff0c\u5e38\u7528\u5728\u51fd\u6570\u4f20\u53c2\uff08C\u4e2d\u4e00\u822c\u7528\u6307\u9488\uff09\u3001\u4e34\u65f6\u53d8\u91cf\u5f15\u7528\u7b49\u3002<\/span>\n    <span class=\"hljs-keyword\">virtual<\/span> ~<span class=\"hljs-built_in\">AnrDumper<\/span>();\n\n <span class=\"hljs-keyword\">private<\/span>:\n    <span class=\"hljs-comment\">\/\/\u5904\u7406signal\u5730\u65b9<\/span>\n    <span class=\"hljs-function\">Result <span class=\"hljs-title\">handleSignal<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">int<\/span> sig, <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">siginfo_t<\/span> *info, <span class=\"hljs-type\">void<\/span> *uc)<\/span> <span class=\"hljs-keyword\">final<\/span><\/span>;\n    <span class=\"hljs-type\">const<\/span> DumpCallbackFunction mCallback;\n};\n}   <span class=\"hljs-comment\">\/\/ namespace MatrixTracer<\/span>\n\n<span class=\"hljs-meta\">#<span class=\"hljs-keyword\">endif<\/span>  <span class=\"hljs-comment\">\/\/ LAGDETECTOR_LAG_DETECTOR_MAIN_CPP_ANRDUMPER_H_<\/span><\/span>\n<\/code><\/pre>\n<h1 data-id=\"heading-8\">4.AnrDumper.cc handleSignal\u65b9\u6cd5\u76d1\u542c SIGQUIT\u4fe1\u53f7\uff0c\u5e76\u6839\u636e\u5176\u4ed6\u8fdb\u7a0b\u8fd8\u662f\u81ea\u5df1\u8fdb\u7a0b\u6765\u8c03\u7528anrCallback \u6216\u8005siUserCallback\uff0c<\/h1>\n<h2 data-id=\"heading-9\">4.1 anr\u662fsystem_server\u8fdb\u7a0b\u53d1\u6765\u7684SIGQUIT\uff0canrCallback\u4ee3\u8868\u53ef\u80fd\u53d1\u751f\u4e86anr\uff0c\u4e4b\u540e\u4f1a\u8c03\u7528anrDumpCallback\uff0c\u8ba9SignalAnrTracer\u68c0\u6d4bui\u7ebf\u7a0b\u662f\u5426block\u6216\u8005\u72b6\u6001\u4e3aNOT_RESPONDING<\/h2>\n<pre><code class=\"hljs language-arduino\" lang=\"arduino\"><span class=\"hljs-meta\">#<span class=\"hljs-keyword\">define<\/span> SIGNAL_CATCHER_THREAD_NAME <span class=\"hljs-string\">\"Signal Catcher\"<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-keyword\">define<\/span> SIGNAL_CATCHER_THREAD_SIGBLK 0x1000 <span class=\"hljs-comment\">\/\/\u5f97\u5230SignalCatcherThreadId\uff0ctodo \u6ca1\u770b\u660e\u767d<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-keyword\">define<\/span> O_WRONLY 00000001<\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-keyword\">define<\/span> O_CREAT 00000100<\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-keyword\">define<\/span> O_TRUNC 00001000<\/span>\n\n<span class=\"hljs-keyword\">namespace<\/span> MatrixTracer {\n   <span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">sigset_t<\/span> old_sigSet;\n   <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">char<\/span> *mAnrTraceFile;\n   <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">char<\/span> *mPrintTraceFile;\n\n<span class=\"hljs-comment\">\/\/\u5efa\u7acb\u4e86Signal Handler\u4e4b\u540e\uff0c\u6211\u4eec\u53d1\u73b0\u5728\u540c\u65f6\u6709sigwait\u548csignal handler\u7684\u60c5\u51b5\u4e0b\uff0c<\/span>\n<span class=\"hljs-comment\">\/\/ \u4fe1\u53f7\u6ca1\u6709\u8d70\u5230\u6211\u4eec\u7684signal handler\u800c\u662f\u4f9d\u7136\u88ab\u7cfb\u7edf\u7684Signal Catcher\u7ebf\u7a0b\u6355\u83b7\u5230\u4e86\uff0c\u8fd9\u662f\u4ec0\u4e48\u539f\u56e0\u5462\uff1f<\/span>\n<span class=\"hljs-comment\">\/\/<\/span>\n<span class=\"hljs-comment\">\/\/\u539f\u6765\u662fAndroid\u9ed8\u8ba4\u628aSIGQUIT\u8bbe\u7f6e\u6210\u4e86BLOCKED\uff0c\u6240\u4ee5\u53ea\u4f1a\u54cd\u5e94sigwait\u800c\u4e0d\u4f1a\u8fdb\u5165\u5230\u6211\u4eec\u8bbe\u7f6e\u7684handler\u65b9\u6cd5\u4e2d\u3002<\/span>\n<span class=\"hljs-comment\">\/\/ \u6211\u4eec\u901a\u8fc7pthread_sigmask\u6216\u8005sigprocmask\u628aSIGQUIT\u8bbe\u7f6e\u4e3aUNBLOCK\uff0c\u90a3\u4e48\u518d\u6b21\u6536\u5230SIGQUIT\u65f6\uff0c\u5c31\u4e00\u5b9a\u4f1a\u8fdb\u5165\u5230\u6211\u4eec\u7684handler\u65b9\u6cd5\u4e2d\u3002\u9700\u8981\u8fd9\u6837\u8bbe\u7f6e\uff1a<\/span>\n   AnrDumper::<span class=\"hljs-built_in\">AnrDumper<\/span>(<span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">char<\/span> *anrTraceFile, <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">char<\/span> *printTraceFile,\n                        AnrDumper::DumpCallbackFunction &amp;&amp;callback) : <span class=\"hljs-built_in\">mCallback<\/span>(callback) {\n       <span class=\"hljs-comment\">\/\/ must unblocked SIGQUIT, otherwise the signal handler can not capture SIGQUIT<\/span>\n       <span class=\"hljs-comment\">\/\/ \u5fc5\u987bunblock\uff0c\u5426\u5219signal handler\u65e0\u6cd5\u63a5\u6536\u5230\u4fe1\u53f7\uff0c\u800c\u662f\u7531signal_cahcher\u7ebf\u7a0b\u4e2d\u7684sigwait\u63a5\u6536\u4fe1\u53f7\uff0c\u8d70\u4e00\u822c\u7684ANR\u6d41\u7a0b<\/span>\n       mAnrTraceFile = anrTraceFile;\n       mPrintTraceFile = printTraceFile;\n       <span class=\"hljs-type\">sigset_t<\/span> sigSet;\n       <span class=\"hljs-built_in\">sigemptyset<\/span>(&amp;sigSet);\n       <span class=\"hljs-built_in\">sigaddset<\/span>(&amp;sigSet, SIGQUIT);\n       <span class=\"hljs-built_in\">pthread_sigmask<\/span>(SIG_UNBLOCK, &amp;sigSet, &amp;old_sigSet);\n   }\n\n   <span class=\"hljs-comment\">\/\/\u5f97\u5230SignalCatcherThreadId\uff0ctodo \u6ca1\u770b\u660e\u767d<\/span>\n   <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">int<\/span> <span class=\"hljs-title\">getSignalCatcherThreadId<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n       <span class=\"hljs-type\">char<\/span> taskDirPath[<span class=\"hljs-number\">128<\/span>];\n       DIR *taskDir;\n       <span class=\"hljs-type\">long<\/span> <span class=\"hljs-type\">long<\/span> sigblk;\n       <span class=\"hljs-type\">int<\/span> signalCatcherTid = <span class=\"hljs-number\">-1<\/span>;\n       <span class=\"hljs-type\">int<\/span> firstSignalCatcherTid = <span class=\"hljs-number\">-1<\/span>;\n\n       <span class=\"hljs-built_in\">snprintf<\/span>(taskDirPath, <span class=\"hljs-built_in\">sizeof<\/span>(taskDirPath), <span class=\"hljs-string\">\"\/proc\/%d\/task\"<\/span>, <span class=\"hljs-built_in\">getpid<\/span>());\n       <span class=\"hljs-keyword\">if<\/span> ((taskDir = <span class=\"hljs-built_in\">opendir<\/span>(taskDirPath)) == <span class=\"hljs-literal\">nullptr<\/span>) {\n           <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">-1<\/span>;\n       }\n       <span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title class_\">dirent<\/span> *dent;\n       <span class=\"hljs-type\">pid_t<\/span> tid;\n       <span class=\"hljs-keyword\">while<\/span> ((dent = <span class=\"hljs-built_in\">readdir<\/span>(taskDir)) != <span class=\"hljs-literal\">nullptr<\/span>) {\n           tid = <span class=\"hljs-built_in\">atoi<\/span>(dent-&gt;d_name);\n           <span class=\"hljs-keyword\">if<\/span> (tid &lt;= <span class=\"hljs-number\">0<\/span>) {\n               <span class=\"hljs-keyword\">continue<\/span>;\n           }\n\n           <span class=\"hljs-type\">char<\/span> threadName[<span class=\"hljs-number\">1024<\/span>];\n           <span class=\"hljs-type\">char<\/span> commFilePath[<span class=\"hljs-number\">1024<\/span>];\n           <span class=\"hljs-built_in\">snprintf<\/span>(commFilePath, <span class=\"hljs-built_in\">sizeof<\/span>(commFilePath), <span class=\"hljs-string\">\"\/proc\/%d\/task\/%d\/comm\"<\/span>, <span class=\"hljs-built_in\">getpid<\/span>(), tid);\n\n           Support::<span class=\"hljs-built_in\">readFileAsString<\/span>(commFilePath, threadName, <span class=\"hljs-built_in\">sizeof<\/span>(threadName));\n\n           <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">strncmp<\/span>(SIGNAL_CATCHER_THREAD_NAME, threadName,\n                       <span class=\"hljs-built_in\">sizeof<\/span>(SIGNAL_CATCHER_THREAD_NAME) - <span class=\"hljs-number\">1<\/span>) != <span class=\"hljs-number\">0<\/span>) {\n               <span class=\"hljs-keyword\">continue<\/span>;\n           }\n\n           <span class=\"hljs-keyword\">if<\/span> (firstSignalCatcherTid == <span class=\"hljs-number\">-1<\/span>) {\n               firstSignalCatcherTid = tid;\n           }\n\n           sigblk = <span class=\"hljs-number\">0<\/span>;\n           <span class=\"hljs-type\">char<\/span> taskPath[<span class=\"hljs-number\">128<\/span>];\n           <span class=\"hljs-built_in\">snprintf<\/span>(taskPath, <span class=\"hljs-built_in\">sizeof<\/span>(taskPath), <span class=\"hljs-string\">\"\/proc\/%d\/status\"<\/span>, tid);\n\n           <span class=\"hljs-function\">ScopedFileDescriptor <span class=\"hljs-title\">fd<\/span><span class=\"hljs-params\">(open(taskPath, O_RDONLY, <span class=\"hljs-number\">0<\/span>))<\/span><\/span>;\n           <span class=\"hljs-function\">LineReader <span class=\"hljs-title\">lr<\/span><span class=\"hljs-params\">(fd.get())<\/span><\/span>;\n           <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">char<\/span> *line;\n           <span class=\"hljs-type\">size_t<\/span> len;\n           <span class=\"hljs-keyword\">while<\/span> (lr.<span class=\"hljs-built_in\">getNextLine<\/span>(&amp;line, &amp;len)) {\n               <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-number\">1<\/span> == <span class=\"hljs-built_in\">sscanf<\/span>(line, <span class=\"hljs-string\">\"SigBlk: %\"<\/span> SCNx64, &amp;sigblk)) {\n                   <span class=\"hljs-keyword\">break<\/span>;\n               }\n               lr.<span class=\"hljs-built_in\">popLine<\/span>(len);\n           }\n           <span class=\"hljs-keyword\">if<\/span> (SIGNAL_CATCHER_THREAD_SIGBLK != sigblk) {\n               <span class=\"hljs-keyword\">continue<\/span>;\n           }\n           signalCatcherTid = tid;\n           <span class=\"hljs-keyword\">break<\/span>;\n       }\n       <span class=\"hljs-built_in\">closedir<\/span>(taskDir);\n\n       <span class=\"hljs-keyword\">if<\/span> (signalCatcherTid == <span class=\"hljs-number\">-1<\/span>) {\n           signalCatcherTid = firstSignalCatcherTid;\n       }\n       <span class=\"hljs-keyword\">return<\/span> signalCatcherTid;\n   }\n\n<span class=\"hljs-comment\">\/\/\u6211\u4eec\u901a\u8fc7Signal Handler\u62a2\u5230\u4e86SIGQUIT\u540e\uff0c\u539f\u672c\u7684Signal Catcher\u7ebf\u7a0b\u4e2d\u7684sigwait\u5c31\u4e0d\u518d\u80fd\u6536\u5230SIGQUIT\u4e86\uff0c<\/span>\n<span class=\"hljs-comment\">\/\/ \u539f\u672c\u7684dump\u5806\u6808\u7684\u903b\u8f91\u5c31\u65e0\u6cd5\u5b8c\u6210\u4e86\uff0c\u6211\u4eec\u4e3a\u4e86ANR\u7684\u6574\u4e2a\u903b\u8f91\u548c\u6d41\u7a0b\u8ddf\u539f\u6765\u5b8c\u5168\u4e00\u81f4\uff0c\u9700\u8981\u5728Signal Handler\u91cc\u9762\u91cd\u65b0\u5411Signal Catcher\u7ebf\u7a0b\u53d1\u9001\u4e00\u4e2aSIGQUIT\uff1a<\/span>\n   <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title\">sendSigToSignalCatcher<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n       <span class=\"hljs-comment\">\/\/\u904d\u5386\/proc\/[pid]\u76ee\u5f55\uff0c\u627e\u5230SignalCatcher\u7ebf\u7a0b\u7684tid<\/span>\n       <span class=\"hljs-type\">int<\/span> tid = <span class=\"hljs-built_in\">getSignalCatcherThreadId<\/span>();\n       <span class=\"hljs-built_in\">syscall<\/span>(SYS_tgkill, <span class=\"hljs-built_in\">getpid<\/span>(), tid, SIGQUIT);\n   }\n\n   <span class=\"hljs-comment\">\/\/SIGQUIT\u53d1\u751f\u4e86\uff0c\u5176\u4ed6\u8fdb\u7a0b\u53d1\u6765\u7684\uff0canr\u662fsystem_server\u8fdb\u7a0b\u53d1\u6765\u7684\u6d88\u606f\uff0c\u4e0d\u662f\u81ea\u5df1\u8fdb\u7a0b\u53d1\u6765\u7684<\/span>\n   <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> *<span class=\"hljs-title\">anrCallback<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">void<\/span> *arg)<\/span> <\/span>{\n       <span class=\"hljs-comment\">\/\/anr\u53ef\u80fd\u53d1\u751f\u4e86\uff0c\u901a\u77e5SignalAnrTracer\u68c0\u6d4bui\u7ebf\u7a0b\u662f\u5426block\u6216\u8005\u72b6\u6001\u4e3aNOT_RESPONDING<\/span>\n       <span class=\"hljs-built_in\">anrDumpCallback<\/span>();\n\n       <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">strlen<\/span>(mAnrTraceFile) &gt; <span class=\"hljs-number\">0<\/span>) {\n           <span class=\"hljs-comment\">\/\/\u5f00\u59cbhook write socket<\/span>\n           <span class=\"hljs-built_in\">hookAnrTraceWrite<\/span>(<span class=\"hljs-literal\">false<\/span>);\n       }\n       <span class=\"hljs-comment\">\/\/\u8f6c\u53d1SIGQUIT<\/span>\n       <span class=\"hljs-built_in\">sendSigToSignalCatcher<\/span>();\n       <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">nullptr<\/span>;\n   }\n\n   <span class=\"hljs-comment\">\/\/SIGQUIT\u53d1\u751f\u4e86\uff0c\u81ea\u5df1\u8fdb\u7a0b\u53d1\u6765\u7684\uff0c\u4e0d\u662fanr<\/span>\n   <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> *<span class=\"hljs-title\">siUserCallback<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">void<\/span> *arg)<\/span> <\/span>{\n       <span class=\"hljs-comment\">\/\/\u8fd9\u91cc\u6ca1\u6709\u8c03\u7528anrDumpCallback\uff0c\u56e0\u4e3a\u662f\u81ea\u5df1\u89e6\u53d1\u7684<\/span>\n       <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">strlen<\/span>(mPrintTraceFile) &gt; <span class=\"hljs-number\">0<\/span>) {\n           <span class=\"hljs-comment\">\/\/\u5f00\u59cbhook write socket<\/span>\n           <span class=\"hljs-built_in\">hookAnrTraceWrite<\/span>(<span class=\"hljs-literal\">true<\/span>);\n       }\n       <span class=\"hljs-comment\">\/\/\u8f6c\u53d1SIGQUIT<\/span>\n       <span class=\"hljs-built_in\">sendSigToSignalCatcher<\/span>();\n       <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">nullptr<\/span>;\n   }\n\n<span class=\"hljs-comment\">\/\/\u53e6\u5916\uff0cSignal Handler\u56de\u8c03\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570siginfo_t\uff0c\u4e5f\u5305\u542b\u4e86\u4e00\u4e9b\u6709\u7528\u7684\u4fe1\u606f\uff0c\u8be5\u7ed3\u6784\u4f53\u7684\u7b2c\u4e09\u4e2a\u5b57\u6bb5si_code\u8868\u793a\u8be5\u4fe1\u53f7\u88ab<\/span>\n<span class=\"hljs-comment\">\/\/ \u53d1\u9001\u7684\u65b9\u6cd5\uff0cSI_USER\u8868\u793a\u4fe1\u53f7\u662f\u901a\u8fc7kill\u53d1\u9001\u7684\uff0cSI_QUEUE\u8868\u793a\u4fe1\u53f7\u662f\u901a\u8fc7sigqueue\u53d1\u9001\u7684\u3002\u4f46\u5728Android\u7684ANR\u6d41\u7a0b\u4e2d\uff0c<\/span>\n<span class=\"hljs-comment\">\/\/ \u9ad8\u7248\u672c\u4f7f\u7528\u7684\u662fsigqueue\u53d1\u9001\u7684\u4fe1\u53f7\uff0c\u67d0\u4e9b\u4f4e\u7248\u672c\u4f7f\u7528\u7684\u662fkill\u53d1\u9001\u7684\u4fe1\u53f7\uff0c\u5e76\u4e0d\u7edf\u4e00\u3002<\/span>\n<span class=\"hljs-comment\">\/\/<\/span>\n<span class=\"hljs-comment\">\/\/\u800c\u7b2c\u4e94\u4e2a\u5b57\u6bb5\uff08\u6781\u5c11\u6570\u673a\u578b\u4e0a\u662f\u7b2c\u56db\u4e2a\u5b57\u6bb5\uff09si_pid\u8868\u793a\u7684\u662f\u53d1\u9001\u8be5\u4fe1\u53f7\u7684\u8fdb\u7a0b\u7684pid\uff0c\u8fd9\u91cc\u9002\u7528\u51e0\u4e4e\u6240\u6709Android\u7248\u672c\u548c\u673a\u578b\u7684<\/span>\n<span class=\"hljs-comment\">\/\/ \u4e00\u4e2a\u6761\u4ef6\u662f\uff1a\u5982\u679c\u53d1\u9001\u4fe1\u53f7\u7684\u8fdb\u7a0b\u662f\u81ea\u5df1\u7684\u8fdb\u7a0b\uff0c\u90a3\u4e48\u4e00\u5b9a\u4e0d\u662f\u4e00\u4e2aANR\u3002\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u6761\u4ef6\u6392\u9664\u81ea\u5df1\u53d1\u9001SIGQUIT\uff0c<\/span>\n<span class=\"hljs-comment\">\/\/ \u800c\u5bfc\u81f4\u8bef\u62a5\u7684\u60c5\u51b5\u3002<\/span>\n   <span class=\"hljs-function\">SignalHandler::Result <span class=\"hljs-title\">AnrDumper::handleSignal<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">int<\/span> sig, <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">siginfo_t<\/span> *info, <span class=\"hljs-type\">void<\/span> *uc)<\/span> <\/span>{\n       <span class=\"hljs-comment\">\/\/ Only process SIGQUIT, which indicates an ANR.<\/span>\n       <span class=\"hljs-keyword\">if<\/span> (sig != SIGQUIT) <span class=\"hljs-keyword\">return<\/span> NOT_HANDLED;\n       <span class=\"hljs-comment\">\/\/Got An ANR<\/span>\n       <span class=\"hljs-type\">int<\/span> fromPid1 = info-&gt;_si_pad[<span class=\"hljs-number\">3<\/span>];\n       <span class=\"hljs-type\">int<\/span> fromPid2 = info-&gt;_si_pad[<span class=\"hljs-number\">4<\/span>];\n       <span class=\"hljs-type\">int<\/span> myPid = <span class=\"hljs-built_in\">getpid<\/span>();\n\n       <span class=\"hljs-type\">pthread_t<\/span> thd;\n\n       <span class=\"hljs-keyword\">if<\/span> (fromPid1 != myPid &amp;&amp; fromPid2 != myPid) {\n           <span class=\"hljs-comment\">\/\/\u4e00\u4e2a\u6761\u4ef6\u662f\uff1a\u5982\u679c\u53d1\u9001\u4fe1\u53f7\u7684\u8fdb\u7a0b\u662f\u81ea\u5df1\u7684\u8fdb\u7a0b\uff0c\u90a3\u4e48\u4e00\u5b9a\u4e0d\u662f\u4e00\u4e2aANR\u3002\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u6761\u4ef6\u6392\u9664\u81ea\u5df1\u53d1\u9001SIGQUIT\uff0c<\/span>\n           <span class=\"hljs-built_in\">pthread_create<\/span>(&amp;thd, <span class=\"hljs-literal\">nullptr<\/span>, anrCallback, <span class=\"hljs-literal\">nullptr<\/span>);\n       } <span class=\"hljs-keyword\">else<\/span> {\n           <span class=\"hljs-comment\">\/\/\u81ea\u5df1\u7684\u8fdb\u7a0b<\/span>\n           <span class=\"hljs-built_in\">pthread_create<\/span>(&amp;thd, <span class=\"hljs-literal\">nullptr<\/span>, siUserCallback, <span class=\"hljs-literal\">nullptr<\/span>);\n       }\n       <span class=\"hljs-built_in\">pthread_detach<\/span>(thd);\n\n       <span class=\"hljs-keyword\">return<\/span> HANDLED_NO_RETRIGGER;\n   }\n\n   <span class=\"hljs-comment\">\/\/\u6ca1\u7528\u5230<\/span>\n   <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> *<span class=\"hljs-title\">anr_trace_callback<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">void<\/span> *args)<\/span> <\/span>{\n       <span class=\"hljs-built_in\">anrDumpTraceCallback<\/span>();\n       <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">nullptr<\/span>;\n   }\n\n   <span class=\"hljs-comment\">\/\/\u6ca1\u7528\u5230<\/span>\n   <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> *<span class=\"hljs-title\">print_trace_callback<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">void<\/span> *args)<\/span> <\/span>{\n       <span class=\"hljs-built_in\">printTraceCallback<\/span>();\n       <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">nullptr<\/span>;\n   }\n\n   AnrDumper::~<span class=\"hljs-built_in\">AnrDumper<\/span>() {\n       <span class=\"hljs-built_in\">pthread_sigmask<\/span>(SIG_SETMASK, &amp;old_sigSet, <span class=\"hljs-literal\">nullptr<\/span>);\n   }\n\n}   <span class=\"hljs-comment\">\/\/ namespace MatrixTracer<\/span>\n<\/code><\/pre>\n<h1 data-id=\"heading-10\">5.\u6211\u4eec\u7684SignalHandler\u7c7b<\/h1>\n<h2 data-id=\"heading-11\">5.1 signalHandler\u65b9\u6cd5\u4e3b\u8981\u662f\u6536\u5230\u4e86\u4fe1\u53f7<\/h2>\n<h2 data-id=\"heading-12\">5.2 handleSignal\u5904\u7406\u4fe1\u53f7<\/h2>\n<pre><code class=\"hljs language-arduino\" lang=\"arduino\"><span class=\"hljs-keyword\">namespace<\/span> MatrixTracer {\n\n    <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title class_\">SignalHandler<\/span> {\n    <span class=\"hljs-keyword\">public<\/span>:\n        <span class=\"hljs-built_in\">SignalHandler<\/span>();\n\n        <span class=\"hljs-keyword\">virtual<\/span> ~<span class=\"hljs-built_in\">SignalHandler<\/span>();<span class=\"hljs-comment\">\/\/\u6790\u6784\u51fd\u6570\uff1a<\/span>\n<span class=\"hljs-comment\">\/\/    \u5f53\u4e00\u4e2a\u7c7b\u7684\u5bf9\u8c61\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\uff0c\u6790\u6784\u51fd\u6570\u5c06\u88ab\u8c03\u7528(\u7cfb\u7edf\u81ea\u52a8\u8c03\u7528)\u3002\u6790\u6784\u51fd\u6570\u7684\u540d\u5b57\u548c\u7c7b\u540d\u4e00\u6837\uff0c\u4e0d\u8fc7\u8981\u5728\u524d\u9762\u52a0\u4e0a ~ \u3002<\/span>\n<span class=\"hljs-comment\">\/\/    \u5bf9\u4e00\u4e2a\u7c7b\u6765\u8bf4\uff0c\u53ea\u80fd\u5141\u8bb8\u4e00\u4e2a\u6790\u6784\u51fd\u6570\uff0c\u6790\u6784\u51fd\u6570\u4e0d\u80fd\u6709\u53c2\u6570\uff0c\u5e76\u4e14\u4e5f\u6ca1\u6709\u8fd4\u56de\u503c\u3002<\/span>\n<span class=\"hljs-comment\">\/\/    \u6790\u6784\u51fd\u6570\u7684\u4f5c\u7528\u662f\u5b8c\u6210\u4e00\u4e2a\u6e05\u7406\u5de5\u4f5c\uff0c\u5982\u91ca\u653e\u4ece\u5806\u4e2d\u5206\u914d\u7684\u5185\u5b58\u3002<\/span>\n\n    <span class=\"hljs-keyword\">protected<\/span>:\n        <span class=\"hljs-keyword\">enum<\/span> <span class=\"hljs-title class_\">Result<\/span> {\n            NOT_HANDLED = <span class=\"hljs-number\">0<\/span>, HANDLED, HANDLED_NO_RETRIGGER\n        };<span class=\"hljs-comment\">\/\/retrigger<\/span>\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">virtual<\/span> Result <span class=\"hljs-title\">handleSignal<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">int<\/span> sig, <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">siginfo_t<\/span> *info, <span class=\"hljs-type\">void<\/span> *uc)<\/span> <\/span>= <span class=\"hljs-number\">0<\/span>;\n\n    <span class=\"hljs-keyword\">private<\/span>:\n        <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title\">signalHandler<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">int<\/span> sig, <span class=\"hljs-type\">siginfo_t<\/span> *info, <span class=\"hljs-type\">void<\/span> *uc)<\/span><\/span>;\n\n        <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">bool<\/span> <span class=\"hljs-title\">installHandlersLocked<\/span><span class=\"hljs-params\">()<\/span><\/span>;\n\n        <span class=\"hljs-comment\">\/\/https:\/\/blog.csdn.net\/lmb1612977696\/article\/details\/80035487<\/span>\n        <span class=\"hljs-built_in\">SignalHandler<\/span>(<span class=\"hljs-type\">const<\/span> SignalHandler &amp;) = <span class=\"hljs-keyword\">delete<\/span>;<span class=\"hljs-comment\">\/\/\u7981\u6b62\u751f\u6210\u8be5\u51fd\u6570\uff0c\u9ed8\u8ba4\u62f7\u8d1d\u6784\u9020\u51fd\u6570<\/span>\n        SignalHandler &amp;<span class=\"hljs-keyword\">operator<\/span>=(<span class=\"hljs-type\">const<\/span> SignalHandler &amp;) = <span class=\"hljs-keyword\">delete<\/span>;<span class=\"hljs-comment\">\/\/\u7981\u6b62\u751f\u6210\u8be5\u51fd\u6570\uff0c\u9ed8\u8ba4\u8d4b\u503c\u51fd\u6570<\/span>\n    };\n\n}   <span class=\"hljs-comment\">\/\/ namespace MatrixTracer<\/span>\n\n<span class=\"hljs-meta\">#<span class=\"hljs-keyword\">endif<\/span>  <span class=\"hljs-comment\">\/\/ LAGDETECTOR_LAG_DETECTOR_MAIN_CPP_SIGNALHANDLER_H_<\/span><\/span>\n<span class=\"hljs-number\">6.<\/span>SignalHandler.cc\n<span class=\"hljs-number\">6.1<\/span> installHandlersLocked \u901a\u8fc7\u53ef\u4ee5sigaction\u65b9\u6cd5\uff0c\u5efa\u7acb\u4e00\u4e2aSignal Handler,sa_sigaction\u65b9\u6cd5\u5730\u5740\u8bbe\u7f6e\u4e3a\u6211\u4eec\u7684signalHandler\u65b9\u6cd5\n<span class=\"hljs-number\">6.2<\/span> signalHandler \u4fe1\u53f7\u5904\u7406\u7684\u5730\u65b9\uff0c\u8f6c\u53d1\u7ed9\u5404SignalHandler\u7684handleSignal\n<span class=\"hljs-comment\">\/\/\u7ebf\u7a0b\u540d\u5b57\uff0ctodo\uff0c\u5f97\u5230SignalCatcherThreadId\uff0ctodo \u6ca1\u770b\u660e\u767d<\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-keyword\">define<\/span> SIGNAL_CATCHER_THREAD_NAME <span class=\"hljs-string\">\"Signal Catcher\"<\/span><\/span>\n<span class=\"hljs-comment\">\/\/\u9000\u51fa\u7ebf\u7a0b\u6807\u8bb0\uff0ctodo\uff0c\u5f97\u5230SignalCatcherThreadId\uff0ctodo \u6ca1\u770b\u660e\u767d<\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-keyword\">define<\/span> SIGNAL_CATCHER_THREAD_SIGBLK 0x1000<\/span>\n\n<span class=\"hljs-keyword\">namespace<\/span> MatrixTracer {\n<span class=\"hljs-comment\">\/\/\u4fe1\u53f7<\/span>\n    <span class=\"hljs-type\">const<\/span> <span class=\"hljs-type\">int<\/span> TARGET_SIG = SIGQUIT;<span class=\"hljs-comment\">\/\/3<\/span>\n<span class=\"hljs-comment\">\/\/\u4f7f\u7528sigaction\u65b9\u6cd5\u6ce8\u518csignal handler\u8fdb\u884c\u5f02\u6b65\u76d1\u542c\uff0csOldHandlers\u662f\u4fdd\u5b58\u8001\u7684sigaction<\/span>\n    <span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title class_\">sigaction<\/span> sOldHandlers;<span class=\"hljs-comment\">\/\/todo<\/span>\n    <span class=\"hljs-type\">bool<\/span> sHandlerInstalled = <span class=\"hljs-literal\">false<\/span>;\n\n<span class=\"hljs-comment\">\/\/ The global signal handler stack. This is needed because there may exist<\/span>\n<span class=\"hljs-comment\">\/\/ multiple SignalHandler instances in a process. Each will have itself<\/span>\n<span class=\"hljs-comment\">\/\/ registered in this stack.<\/span>\n    <span class=\"hljs-type\">static<\/span> std::vector<signalhandler> *sHandlerStack = <span class=\"hljs-literal\">nullptr<\/span>;<span class=\"hljs-comment\">\/\/todo<\/span>\n<span class=\"hljs-comment\">\/\/ C++11\u4e2d\u65b0\u589e\u4e86<mutex>\uff0c\u5b83\u662fC++\u6807\u51c6\u7a0b\u5e8f\u5e93\u4e2d\u7684\u4e00\u4e2a\u5934\u6587\u4ef6\uff0c\u5b9a\u4e49\u4e86C++11\u6807\u51c6\u4e2d\u7684\u4e00\u4e9b\u4e92\u65a5\u8bbf\u95ee\u7684\u7c7b\u4e0e\u65b9\u6cd5\u7b49\u3002\u5176\u4e2dstd::mutex\u5c31\u662flock\u3001unlock\u3002std::lock_guard\u4e0estd::mutex\u914d\u5408\u4f7f\u7528\uff0c\u628a\u9501\u653e\u5230lock_guard\u4e2d\u65f6\uff0cmutex\u81ea\u52a8\u4e0a\u9501\uff0clock_guard\u6790\u6784\u65f6\uff0c\u540c\u65f6\u628amutex\u89e3\u9501\u3002mutex\u53c8\u79f0\u4e92\u65a5\u91cf\u3002<\/mutex><\/span>\n    <span class=\"hljs-type\">static<\/span> std::mutex sHandlerStackMutex;<span class=\"hljs-comment\">\/\/todo<\/span>\n    <span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">bool<\/span> sStackInstalled = <span class=\"hljs-literal\">false<\/span>;\n<span class=\"hljs-comment\">\/\/ InstallAlternateStackLocked will store the newly installed stack in new_stack<\/span>\n<span class=\"hljs-comment\">\/\/ and (if it exists) the previously installed stack in old_stack.<\/span>\n    <span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">stack_t<\/span> sOldStack;<span class=\"hljs-comment\">\/\/todo<\/span>\n    <span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">stack_t<\/span> sNewStack;<span class=\"hljs-comment\">\/\/todo<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title\">installAlternateStackLocked<\/span><span class=\"hljs-params\">()<\/span> <\/span>{<span class=\"hljs-comment\">\/\/todo<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (sStackInstalled)\n            <span class=\"hljs-keyword\">return<\/span>;\n        <span class=\"hljs-comment\">\/\/\u91cd\u7f6e<\/span>\n        <span class=\"hljs-built_in\">memset<\/span>(&amp;sOldStack, <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-built_in\">sizeof<\/span>(sOldStack));\n        <span class=\"hljs-built_in\">memset<\/span>(&amp;sNewStack, <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-built_in\">sizeof<\/span>(sNewStack));\n        <span class=\"hljs-type\">static<\/span> <span class=\"hljs-keyword\">constexpr<\/span> <span class=\"hljs-type\">unsigned<\/span> kSigStackSize = std::<span class=\"hljs-built_in\">max<\/span>(<span class=\"hljs-number\">16384<\/span>, SIGSTKSZ);\n        <span class=\"hljs-comment\">\/\/\u53d6\u5230\u8001\u7684sOldStack<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">sigaltstack<\/span>(<span class=\"hljs-literal\">nullptr<\/span>, &amp;sOldStack) == <span class=\"hljs-number\">-1<\/span> || !sOldStack.ss_sp ||\n            sOldStack.ss_size &lt; kSigStackSize) {\n            sNewStack.ss_sp = <span class=\"hljs-built_in\">calloc<\/span>(<span class=\"hljs-number\">1<\/span>, kSigStackSize);\n            sNewStack.ss_size = kSigStackSize;\n            <span class=\"hljs-comment\">\/\/\u8bbe\u7f6e\u65b0\u7684sNewStack<\/span>\n            <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">sigaltstack<\/span>(&amp;sNewStack, <span class=\"hljs-literal\">nullptr<\/span>) == <span class=\"hljs-number\">-1<\/span>) {\n                <span class=\"hljs-built_in\">free<\/span>(sNewStack.ss_sp);\n                <span class=\"hljs-keyword\">return<\/span>;\n            }\n        }\n\n        sStackInstalled = <span class=\"hljs-literal\">true<\/span>;\n        <span class=\"hljs-built_in\">ALOGV<\/span>(<span class=\"hljs-string\">\"Alternative stack installed.\"<\/span>);\n    }\n\n<span class=\"hljs-comment\">\/\/ Runs before crashing: normal context.<\/span>\n<span class=\"hljs-comment\">\/\/    \u6211\u4eec\u901a\u8fc7\u53ef\u4ee5sigaction\u65b9\u6cd5\uff0c\u5efa\u7acb\u4e00\u4e2aSignal Handler\uff1aok<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-type\">bool<\/span> <span class=\"hljs-title\">SignalHandler::installHandlersLocked<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">if<\/span> (sHandlerInstalled) {\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n        }\n        <span class=\"hljs-comment\">\/\/ Fail if unable to store all the old handlers.<\/span>\n        <span class=\"hljs-comment\">\/\/\u53d6\u5230\u8001\u7684sOldHandlers<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">sigaction<\/span>(TARGET_SIG, <span class=\"hljs-literal\">nullptr<\/span>, &amp;sOldHandlers) == <span class=\"hljs-number\">-1<\/span>) {\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n        }\n\n        <span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title class_\">sigaction<\/span> sa{};<span class=\"hljs-comment\">\/\/sigaction\u7ed3\u6784\u4f53<\/span>\n        sa.sa_sigaction = signalHandler;<span class=\"hljs-comment\">\/\/\u65b9\u6cd5\u5730\u5740\uff0c\u6536\u5230\u4fe1\u53f7\u7684\u5730\u65b9<\/span>\n        sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTART;\n        <span class=\"hljs-comment\">\/\/\u6211\u4eec\u901a\u8fc7\u53ef\u4ee5sigaction\u65b9\u6cd5\uff0c\u5efa\u7acb\u4e00\u4e2aSignal Handler<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">sigaction<\/span>(TARGET_SIG, &amp;sa, <span class=\"hljs-literal\">nullptr<\/span>) == <span class=\"hljs-number\">-1<\/span>) {<span class=\"hljs-comment\">\/\/sigaction\u65b9\u6cd5\uff0c\u5c06sa\u8bbe\u7f6e\u4e3aSignal Handler<\/span>\n            <span class=\"hljs-built_in\">ALOGV<\/span>(<span class=\"hljs-string\">\"Signal handler cannot be installed\"<\/span>);\n\n            <span class=\"hljs-comment\">\/\/ At this point it is impractical to back out changes, and so failure to<\/span>\n            <span class=\"hljs-comment\">\/\/ install a signal is intentionally ignored.<\/span>\n        }\n\n        sHandlerInstalled = <span class=\"hljs-literal\">true<\/span>;\n        <span class=\"hljs-built_in\">ALOGV<\/span>(<span class=\"hljs-string\">\"Signal handler installed.\"<\/span>);\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">true<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/todo<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title\">installDefaultHandler<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">int<\/span> sig)<\/span> <\/span>{\n\n        <span class=\"hljs-comment\">\/\/ Android L+ expose signal and sigaction symbols that override the system<\/span>\n        <span class=\"hljs-comment\">\/\/ ones. There is a bug in these functions where a request to set the handler<\/span>\n        <span class=\"hljs-comment\">\/\/ to SIG_DFL is ignored. In that case, an infinite loop is entered as the<\/span>\n        <span class=\"hljs-comment\">\/\/ signal is repeatedly sent to breakpad's signal handler.<\/span>\n        <span class=\"hljs-comment\">\/\/ To work around this, directly call the system's sigaction.<\/span>\n        <span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title class_\">sigaction<\/span> sa;\n        <span class=\"hljs-built_in\">memset<\/span>(&amp;sa, <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-built_in\">sizeof<\/span>(sa));\n        <span class=\"hljs-built_in\">sigemptyset<\/span>(&amp;sa.sa_mask);\n        sa.sa_handler = SIG_DFL;\n        sa.sa_flags = SA_RESTART;\n        <span class=\"hljs-built_in\">sigaction<\/span>(sig, &amp;sa, <span class=\"hljs-literal\">nullptr<\/span>);\n    }\n\n<span class=\"hljs-comment\">\/\/ This function runs in a compromised context: see the top of the file.<\/span>\n<span class=\"hljs-comment\">\/\/ Runs on the crashing thread.<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title\">restoreHandlersLocked<\/span><span class=\"hljs-params\">()<\/span> <\/span>{<span class=\"hljs-comment\">\/\/todo<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (!sHandlerInstalled)\n            <span class=\"hljs-keyword\">return<\/span>;\n        <span class=\"hljs-comment\">\/\/\u5c06\u8001\u7684sOldHandlers\u91cd\u65b0sigaction\u4e0a<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">sigaction<\/span>(TARGET_SIG, &amp;sOldHandlers, <span class=\"hljs-literal\">nullptr<\/span>) == <span class=\"hljs-number\">-1<\/span>) {\n            <span class=\"hljs-comment\">\/\/todo<\/span>\n            <span class=\"hljs-built_in\">installDefaultHandler<\/span>(TARGET_SIG);\n        }\n\n        sHandlerInstalled = <span class=\"hljs-literal\">false<\/span>;\n        <span class=\"hljs-built_in\">ALOGV<\/span>(<span class=\"hljs-string\">\"Signal handler restored.\"<\/span>);\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-type\">static<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title\">restoreAlternateStackLocked<\/span><span class=\"hljs-params\">()<\/span> <\/span>{<span class=\"hljs-comment\">\/\/todo<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (!sStackInstalled)\n            <span class=\"hljs-keyword\">return<\/span>;\n\n        <span class=\"hljs-type\">stack_t<\/span> current_stack;\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">sigaltstack<\/span>(<span class=\"hljs-literal\">nullptr<\/span>, &amp;current_stack) == <span class=\"hljs-number\">-1<\/span>)\n            <span class=\"hljs-keyword\">return<\/span>;\n        <span class=\"hljs-comment\">\/\/ Only restore the old_stack if the current alternative stack is the one<\/span>\n        <span class=\"hljs-comment\">\/\/ installed by the call to InstallAlternateStackLocked.<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (current_stack.ss_sp == sNewStack.ss_sp) {\n            <span class=\"hljs-keyword\">if<\/span> (sOldStack.ss_sp) {\n                <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">sigaltstack<\/span>(&amp;sOldStack, <span class=\"hljs-literal\">nullptr<\/span>) == <span class=\"hljs-number\">-1<\/span>)\n                    <span class=\"hljs-keyword\">return<\/span>;\n            } <span class=\"hljs-keyword\">else<\/span> {\n                <span class=\"hljs-type\">stack_t<\/span> disable_stack;\n                disable_stack.ss_flags = SS_DISABLE;\n                <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-built_in\">sigaltstack<\/span>(&amp;disable_stack, <span class=\"hljs-literal\">nullptr<\/span>) == <span class=\"hljs-number\">-1<\/span>)\n                    <span class=\"hljs-keyword\">return<\/span>;\n            }\n        }\n\n        <span class=\"hljs-built_in\">free<\/span>(sNewStack.ss_sp);\n        sStackInstalled = <span class=\"hljs-literal\">false<\/span>;\n    }\n\n<span class=\"hljs-comment\">\/\/ This function runs in a compromised context: see the top of the file.<\/span>\n<span class=\"hljs-comment\">\/\/ Runs on the crashing thread.<\/span>\n<span class=\"hljs-comment\">\/\/ \u53d1\u751f\u4fe1\u53f7\u5904\u7406\u7684\u5730\u65b9\uff0c\u8f6c\u53d1\u7ed9\u5404sHandlerStack\u7684handleSignal ok<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-type\">void<\/span> <span class=\"hljs-title\">SignalHandler::signalHandler<\/span><span class=\"hljs-params\">(<span class=\"hljs-type\">int<\/span> sig, <span class=\"hljs-type\">siginfo_t<\/span> *info, <span class=\"hljs-type\">void<\/span> *uc)<\/span> <\/span>{\n        <span class=\"hljs-built_in\">ALOGV<\/span>(<span class=\"hljs-string\">\"Entered signal handler.\"<\/span>);\n<span class=\"hljs-comment\">\/\/ All the exception signals are blocked at this point.<\/span>\n        <span class=\"hljs-function\">std::unique_lock<:mutex> <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(sHandlerStackMutex)<\/span><\/:mutex><\/span>;\n\n        <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">auto<\/span> it = sHandlerStack-&gt;<span class=\"hljs-built_in\">rbegin<\/span>(); it != sHandlerStack-&gt;<span class=\"hljs-built_in\">rend<\/span>(); ++it) {\n            (*it)-&gt;<span class=\"hljs-built_in\">handleSignal<\/span>(sig, info, uc);\n        }\n\n        lock.<span class=\"hljs-built_in\">unlock<\/span>();\n    }\n\n    SignalHandler::<span class=\"hljs-built_in\">SignalHandler<\/span>() {\n        <span class=\"hljs-comment\">\/\/\u4e0a\u9501\uff0ctodo<\/span>\n        <span class=\"hljs-function\">std::lock_guard<:mutex> <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(sHandlerStackMutex)<\/span><\/:mutex><\/span>;\n\n        <span class=\"hljs-comment\">\/\/\u5efa\u4e00\u4e2asHandlerStack<\/span>\n        <span class=\"hljs-keyword\">if<\/span> (!sHandlerStack)\n            sHandlerStack = <span class=\"hljs-keyword\">new<\/span> std::vector<signalhandler>;\n\n        <span class=\"hljs-comment\">\/\/todo<\/span>\n        <span class=\"hljs-built_in\">installAlternateStackLocked<\/span>();\n        <span class=\"hljs-comment\">\/\/todo<\/span>\n        <span class=\"hljs-built_in\">installHandlersLocked<\/span>();\n        <span class=\"hljs-comment\">\/\/\u5c06\u81ea\u5df1\u653e\u8fdb\u53bb<\/span>\n        sHandlerStack-&gt;<span class=\"hljs-built_in\">push_back<\/span>(<span class=\"hljs-keyword\">this<\/span>);\n    }\n\n    SignalHandler::~<span class=\"hljs-built_in\">SignalHandler<\/span>() {\n        <span class=\"hljs-function\">std::lock_guard<:mutex> <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(sHandlerStackMutex)<\/span><\/:mutex><\/span>;\n\n        <span class=\"hljs-keyword\">auto<\/span> it = std::<span class=\"hljs-built_in\">find<\/span>(sHandlerStack-&gt;<span class=\"hljs-built_in\">begin<\/span>(), sHandlerStack-&gt;<span class=\"hljs-built_in\">end<\/span>(), <span class=\"hljs-keyword\">this<\/span>);\n        sHandlerStack-&gt;<span class=\"hljs-built_in\">erase<\/span>(it);\n        <span class=\"hljs-keyword\">if<\/span> (sHandlerStack-&gt;<span class=\"hljs-built_in\">empty<\/span>()) {\n            <span class=\"hljs-keyword\">delete<\/span> sHandlerStack;\n            sHandlerStack = <span class=\"hljs-literal\">nullptr<\/span>;\n            <span class=\"hljs-built_in\">restoreAlternateStackLocked<\/span>();\n            <span class=\"hljs-built_in\">restoreHandlersLocked<\/span>();\n        }\n    }\n\n<\/signalhandler><\/signalhandler><\/code><\/pre>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u5fae\u4fe1Android\u5ba2\u6237\u7aef\u7684ANR\u76d1\u63a7\u65b9\u6848 \u7528\u62377563717074065 2021-08-07 1,527 \u9605&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":163,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-167","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android"],"_links":{"self":[{"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/posts\/167","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/comments?post=167"}],"version-history":[{"count":0,"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/posts\/167\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/media\/163"}],"wp:attachment":[{"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/media?parent=167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/categories?post=167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/newstrong.top\/index.php\/wp-json\/wp\/v2\/tags?post=167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}