为什么说获取堆栈从来就不是一件简单的事情

碎碎谈

为了不让文章看上去过于单调,笔者考虑了一下,特意增加了碎碎谈环节!自从上次这篇文章发出去后 黑科技!让Native Crash 与ANR无处宣泄!googleplay,就挺受读者欢迎的呀,收藏数大于点赞数是虚拟机什么鬼,嘿嘿!从我的视点动身,原本Signal科技巨头从大郎手机开始动身的意图便是想建造一个类googleplay安卓版下载似于安全气囊的装置,保证crash后第一时间重启康复,达到一个运用安稳的意图,可是渐渐写着写着,发现许多crash监控渠道的也是用了相同的核心原理(大部分还没开源噢),只是效果的目标不同,那么为什么不把Signal打造成一个通用的基础件呢!无论是安全气囊仍是监控,其实都是上层的运用不同罢了!嗯!有了这个主意之后,给GoogleSigngoogle网站登录入口al补充一些日志监控逻辑google中国,就愈加完善了!所以就有了本篇文章!算是一个补充文!假如没看过黑科技!让Native Crash 与ANR无处宣泄!这篇文章的新朋友科技手抄报,请先阅读!(假如没有ndk开发经验也不要紧,里Android边也不触及很复杂的c常识)

获取仓库

获取仓库!或许许多新朋友看到这android平板电脑价格个就会想,这有什么难的嘛!直接new 一个Throwable获取不就能够了嘛,或许Thread.currentThread().stackT虚拟机是什么意思race(kotlin)等等也能够呀!嗯!是的!咱们在java层一般会有很固定的获取仓库方法,这得益于java虚拟机的规划,也得益于java言语的规划,由于屏蔽了多渠道底层的差异,咱们就能够用相对一致的api去获取当时安全教育平台登录入口的仓库。这个仓库也特指java虚拟机仓库!

android是什么系统是关于native的仓库,问题就来了!咱们知道native层一般跟许多因素有关,比方链接器,编译器,还有各种库的版别,各种abi等等影响,获取一个仓库音讯,可没有那么简略,由于太多因素搅扰了,这也是前史的包袱!还有关于咱们android来说,android官方在对仓库获取的android的drawable类方法,也android/harmonyos是有前史改变的

4.1.1以上,5.0以下,android native运用体系自带google网站登录入口libcork虚拟机哪个最好用screw.so,5.0开始,体系中没有了libcogoogle商店rkscrew.so 高版别的安卓源码中android下载安装就运用了他的优化版替换libunwind。同时关于ndk来说,编译器的版别也在不断改变,从默许的gcc变成clang(ndk >=13),能够看到,咱们会在许多版别,许多因素下,找一个一致的方法,还真的不简略!不过呀!在2022的今天,google早已推出了一个计划一致库 breakpad ,嗯!尽管能不能成为规范还不决,可是也是一个生态的前进

Siandroid下载安装gnal的挑选

前面介绍了这么多方案,breakpad是虚拟机是什么意思不是Signal的首选呢!尽管breakpad不错,可是里边覆盖了太多其他体系的编译,比方mac,window等科技霸主从带娃开始等规范,还有便是作为一个开源库,仍是期望减少这些库的导安全工程师入,所以跟大多数主流方案一向,咱们挑选用unwind.h去完成仓库打印,由于这个就直接内置在咱们的默许编译中了,并且这个在科技帝国从高分子材料开始在android也能用!下面咱们虚拟机是什么意思来看一下完成!即Signal项意图unwind-utils的完成。那么咱们要考虑一些什么呢!

仓库巨细

日志当然需求设定追溯的仓库巨细,内容太多欠好(过于臃肿,排查困难),内容太少也欠好(很有或许漏掉要害crash仓库),所以Signal默许设置30条,能够依据实践项目修改虚拟机

std::string backtraceToLogcat() {
    默许30个
    const size_t max = 30;
    void *buffer[max];
    //ostringstream方便输出string
    std::ostringstream oss;
    dumpBacktrace(oss, buffer, captureBacktrace(buffer, max));
    return oss.str();
}

_Unwind_Backtrace

_Unwind_Backtrace是un科技之全球垄断wind提供给咱们仓库回溯函数

_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *);

那么这个_Unwindandroidstudio安装教程_Traandroidstudio安装教程ce_Fn是个啥,其实点进去看

typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
                                                void *);

科技最狂潮实这就代表一个函数,关于咱们常年写java的朋友有点不友好对吧,以java的方法,其实意思便是传xxx(随便函数名android/harmonyos)( _Unwind_Context虚拟机安装教程win10 *,void *)这样google的结构的函数即可,这儿的意思便是一个callback函数,当咱们获取android什么意思到地址信息就会回调该参科技之门数,第二个便是需求传递给参数一的参数,android是什么系统这儿有点绕对吧,咱们怎样了解呢!参数一其实便是一个函数的引证,那么这个函数需求参数怎样办,就经过第二个参数传递!

咱们看个比方:这个在Signal也有

static _Unwind_Reason_Code unwindCallback(struct _Unwind_Context *context, void *args) {
    BacktraceState *state = static_cast<BacktraceState *>(args);
    uintptr_t pc = _Unwind_GetIP(context);
    if (pc) {
        if (state->current == state->end) {
            return _URC_END_OF_STACK;
        } else {
            *state->current++ = reinterpret_cast<void *>(pc);
        }
    }
    return _URC_NO_REASON;
}
size_t captureBacktrace(void **buffer, size_t max) {
    BacktraceState state = {buffer, buffer + max};
    _Unwind_Backtrace(unwindCallback, &state);
    // 获取巨细
    return state.current - buffer;
}
struct BacktraceState {
    void **current;
    void **end;
};

咱们界说了一个结构体BacktraceState,其实是为了后面记载函数地址而用,这儿有两个效果,end代表日志限google浏览器制的巨细,current表示实践日志条数巨细(由于仓google中国库条数或许小于end)

_Unwind_GetIP

咱们在unwindCallback这儿拿到了体系回调给咱们的参数科技,要害便是这个了 _Unwind_Conte虚拟机哪个最好用xt这个结构体参数了,这安全模式怎么解除个参数的效果便是传递给_Unwi科技之锤nd_GetIP这个函数,获取咱们当时的履google中国行地址,即pc值!那么这个pc值又有什么用呢!这个便是咱们获取仓库的要害!native仓库的获取需求地址去解android下载安装析!(不同google浏览器于java)咱们先有这个概念,后科技霸主从带娃开始面会持续解说

dladdr

经过了_Unwind_GetIP咱们获取了pc值安全教育平台登录,这个时分就用上dladdr函数去解析了,这个是linux内核函数,专门用于地址符号解析

The function dladdr() determines whether the address specified in
       addr is located in one of the shared objects loaded by the
       calling application.  If it is, then dladdr() returns information
       about the shared object and symbol that overlaps addr.  This
       information is returned in a Dl_info structure:
           typedef struct {
               const char *dli_fname;  /* Pathname of shared object that
                                          contains address */
               void       *dli_fbase;  /* Base address at which shared
                                          object is loaded */
               const char *dli_sname;  /* Name of symbol whose definition
                                          overlaps addr */
               void       *dli_saddr;  /* Exact address of symbol named
                                          in dli_sname */
           } Dl_info;
       If no symbol matching addr could be found, then dli_sname and
       dli_saddr are set to NULL.

能够看到,每个地址会的解析信googleplay安卓版下载息会保存在Dl_info中,假如有运转符号满意,dli_sname和dli_saddr就会被设定为相应的so称号跟地址,dli_fbase是基址信息,由于咱虚拟机linux们的so库被加载到程序的方位是不固定的!所以一般选用地址偏移的方法去在运转时寻觅真实的so库,所以就有这个dli_fbase信息。

Dl_info info;
if (dladdr(addr, &info) && info.dli_sname) {
    symbol = info.dli_sname;
}
os << " #" << idx << ": " << addr << " " <<"  "<<symbol <<"n" ;

终究咱们能够经过dladdr,一一把保存的地址信息解析出来,打印到native日志中比方Signa虚拟机怎么使用l中demo crash信息(假如需求打印so称号,也能够经过dli_fname去获取,这儿不举例)

为什么说获取仓库历来就不是一件简略的工作

native仓库发生进程

经过上面的日志分析(最好看下demo中的app演示candroid/harmonyosras安全教育平台作业登录h),咱们其实在MainActivity中安全教育日设定了一个crash函数

private external fun throwNativeCrash()

依照仓库日志分析来看,只有在第16条才呈现了调用google商店符号,这跟咱们在日安全期计算器常java开发中是不是很不相同!由于java层的仓库一般都是最近的仓库音讯代表着错误音讯,比方应该是第0条才导致的crash,可是演示中真实的仓库crash却隐藏在了日志海里边!信任有不少朋友在看n科技之全球垄断ative crasgoogle中国h日志也是,是不是也感到无从下手,由于首条日志虚拟机哪个最好用往往并不是真实crash的主因!咱们来看一下安全教育平台作业登录真实的进程:安全教育平台登录入口咱们程序从正常态到crash,终究发生了什么!

为什么说获取仓库历来就不是一件简略的工作

能够看到,咱们真实googleplay安卓版下载dump_stack前,是有许多前置的步骤,为什么会有这么多呢!其实这就触及到linux内核虚拟机的危害中止的原理,这儿给一张粗略图android下载

为什么说获取仓库历来就不是一件简略的工作
crash发生后,一般安全教育平台登录入口会在用户态阶段调用中止进入内核态,把自己的中止信号(这儿区别一下科技手抄报,不是咱们signal.h里边的信号)放在eax寄存器中(大部分,也有其他的寄存器,这儿仅举Google例)

然后内核层经过传来的中止信google商店号,找到信号表,然后依据对应的处理程序,再抛回给用户态,这个时分才进行sigaction的逻辑

所以说,crash发生到真实dump日志,其实会有一个进程,这儿面依据sigactiongoogle翻译的设置也会有多个改变,咱们要了解的一点是,真实的cras虚拟机安装教程h信息,往往藏在仓库海中,需求咱们一步步去解析,比方经过addr2line等东西去分析地址,才能得到真实的原因,并且一般的andr科技oid项目,都是依赖于第三方的so,这也给咱们的排查带来难度,不过只需咱们能识别出特定的so(dli_fname信息就有),是不是就能够把锅甩出去了呢,对吧!

最终

看到这儿虚拟机的危害,读者朋安全教育日友应该有一个对native仓库的大概模型了google谷歌搜索主页,当然也不用怕!Signal项目中就包含了相关的unwind-utils东西类,直接用也是能够的,不过现在打印的信息比较简略,后续能够依据我们的实践,去添加参数!代码都在里边,求star求pr !Signa虚拟机linuxl,当然,看完了本文,别忘了留下你的赞跟谈论呀!

往期引荐

听说Compose与RecyclerView虚拟机怎么使用结合会有水土不服?

Androidgoogle翻译 gradle迁移至kts

我正在参加技能社区创作者签约计划招募活动,点击链接报名投稿。

发表评论

提供最优质的资源集合

立即查看 了解详情