aosp15 SurfaceFlinger打印ATRACE编译报错及ScopedTrace类剖析

背景:

有学员基于aosp15代码版本开始学习马哥的SurfaceFlinger/Perfetto课程,但是它想要基于aosp15版本代码也进行相关的自定义的ATRACE的打印,来通过打atrace看perfetto方式追踪整个函数的调用栈。
在这里插入图片描述
但是他在SurfaceFlinger的Layer.cpp中进行相关的ATRACE_CALL添加,具体添加代码如下:

在这里插入图片描述目的很简单,只是想针对releasePreviousBuffer整个方法进行在perfetto上slice输出。
但是学员反馈居然在aosp15版本添加上面代码后,有编译报错

error: no matching constructor for initialization of ‘::android::ScopedTrace’

详细编译报错如下:

system/core/libutils/include/utils/Trace.h:27:9: error: '_PASTE' macro redefined [-Werror,-Wmacro-redefined]
   27 | #define _PASTE(x, y) x ## y
      |         ^
frameworks/native/services/surfaceflinger/common/include/common/trace.h:63:9: note: previous definition is here
   63 | #define _PASTE(x, y) x##y
      |         ^
In file included from frameworks/native/services/surfaceflinger/Layer.cpp:78:
system/core/libutils/include/utils/Trace.h:28:9: error: 'PASTE' macro redefined [-Werror,-Wmacro-redefined]
   28 | #define PASTE(x, y) _PASTE(x,y)
      |         ^
frameworks/native/services/surfaceflinger/common/include/common/trace.h:64:9: note: previous definition is here
   64 | #define PASTE(x, y) _PASTE(x, y)
      |         ^
In file included from frameworks/native/services/surfaceflinger/Layer.cpp:78:
system/core/libutils/include/utils/Trace.h:36:7: error: redefinition of 'ScopedTrace'
   36 | class ScopedTrace {
      |       ^
frameworks/native/services/surfaceflinger/common/include/common/trace.h:80:7: note: previous definition is here
   80 | class ScopedTrace {
      |       ^
frameworks/native/services/surfaceflinger/Layer.cpp:845:9: error: no matching constructor for initialization of '::android::ScopedTrace'
  845 |         ATRACE_CALL();

那么到底是怎么回事呢?难道高版本的SurfaceFlinger都不支持ATRACE使用了么?
下面来剖析一下整个编译报错的原因。

编译原因剖析

首先看编译报错日志,可以看到其实有多个error输出的:

----错误1:有一个Trace.h:27行的redefined重复第一报错
system/core/libutils/include/utils/Trace.h:27:9: error: '_PASTE' macro redefined [-Werror,-Wmacro-redefined]
   27 | #define _PASTE(x, y) x ## y
   
----错误2:有一个Trace.h:36行的redefined重复第一报错
system/core/libutils/include/utils/Trace.h:36:7: error: redefinition of 'ScopedTrace'
   36 | class ScopedTrace {

---错误3:有一个我们自己加入的代码ATRACE_CALL报错,报错是找不到匹配构造方法
frameworks/native/services/surfaceflinger/Layer.cpp:845:9: error: no matching constructor for initialization of '::android::ScopedTrace'
  845 |         ATRACE_CALL();

首先大家可能下意识的会忽略掉前两个.h中错误,因为可能觉得这块代码都不是我们自己写的,所以很容易不理会,但是错误3因为属于自己加入代码并且报错就在加的哪一行,一般注意力都在错误3,这样看其实也算正常啦,毕竟大家下意识只关注自己加入代码。
哈哈,那么就按照常规分析错误3来看看:
ATRACE_CALL宏剖析
那么我们来看看ATRACE_CALL这个宏
system/core/libutils/include/utils/Trace.h

#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)

这里的ATRACE_NAME代码又如下:

#define _PASTE(x, y) x ## y
#define PASTE(x, y) _PASTE(x,y)
#define ATRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(ATRACE_TAG, name)

这里一共分为3个部分,这里挨个进行剖析
在这里插入图片描述

部分1:
::android::ScopedTrace,它其实是一个类,属于类型的声明


class ScopedTrace {
public:
    inline ScopedTrace(uint64_t tag, const char* name) : mTag(tag) {
        atrace_begin(mTag, name);
    }

    inline ~ScopedTrace() {
        atrace_end(mTag);
    }

private:
    uint64_t mTag;
};

可以看出这个类型的变量在构造和析构时候会调用atrace_begin和atrace_end。

部分2:
PASTE(___tracer, LINE)
本质其实就是调用宏,进行拼接成唯一的一个对象变量名字,拼接变量名字主要目的就是为了防止命名冲突。
PASTE(___tracer, LINE)第二个__LINE__代表行号意思
所以最后拼接的变量是:
___tracer845

部分3:
这个没啥可说的,就是ScopedTrace构造方法需要传递的参数

所以最后这个宏结果就是:

::android::ScopedTrace ___tracer845(ATRACE_TAG, name)

再看错误

error: no matching constructor for initialization of '::android::ScopedTrace

明明在system/core/libutils/include/utils/Trace.h中看到了有这个的android::ScopedTrace定义,为啥说没有匹配到呢?

这里明明有啊,所以这里其实就需要结合前面的错误2了:

system/core/libutils/include/utils/Trace.h:36:7: error: redefinition of 'ScopedTrace'
   36 | class ScopedTrace {

说Trace.h的ScopedTrace是重复定义,那么到底是哪里先定义了呢?错误日志中也有提示:

frameworks/native/services/surfaceflinger/common/include/common/trace.h:80:7: note: previous definition is here
   80 | class ScopedTrace {

简单说frameworks/native/services/surfaceflinger/common/include/common/trace.h也有定义ScopedTrace

在这里插入图片描述
哈哈,那这里其实就清楚了,原理SurfaceFlinger对于ATRACE打印这块有自己做了全新的trace.h来定义相关的trace打印输出的宏,所以代码中一旦引入了SurfaceFlinger自己的trace.h就不可以再使用
system/core/libutils/include/utils/Trace.h。

那么到此就可以清楚了为啥调用一个ATRACE_CALL会报错的原因了,那么这个问题如何解决呢?
那当然是看看SurfaceFlinger自己的trace.h是不是有类似宏就可以了。

解决办法:

frameworks/native/services/surfaceflinger/common/include/common/trace.h
文件中可以使用的宏


#define SFTRACE_ENABLED() ::tracing_perfetto::isTagEnabled(ATRACE_TAG)
#define SFTRACE_BEGIN(name) ::tracing_perfetto::traceBegin(ATRACE_TAG, name)
#define SFTRACE_END() ::tracing_perfetto::traceEnd(ATRACE_TAG)
#define SFTRACE_ASYNC_BEGIN(name, cookie) \
    ::tracing_perfetto::traceAsyncBegin(ATRACE_TAG, name, cookie)
#define SFTRACE_ASYNC_END(name, cookie) ::tracing_perfetto::traceAsyncEnd(ATRACE_TAG, name, cookie)
#define SFTRACE_ASYNC_FOR_TRACK_BEGIN(track_name, name, cookie) \
    ::tracing_perfetto::traceAsyncBeginForTrack(ATRACE_TAG, name, track_name, cookie)
#define SFTRACE_ASYNC_FOR_TRACK_END(track_name, cookie) \
    ::tracing_perfetto::traceAsyncEndForTrack(ATRACE_TAG, track_name, cookie)
#define SFTRACE_INSTANT(name) ::tracing_perfetto::traceInstant(ATRACE_TAG, name)
#define SFTRACE_FORMAT_INSTANT(fmt, ...) \
    ::tracing_perfetto::traceFormatInstant(ATRACE_TAG, fmt, ##__VA_ARGS__)
#define SFTRACE_INSTANT_FOR_TRACK(trackName, name) \
    ::tracing_perfetto::traceInstantForTrack(ATRACE_TAG, trackName, name)
#define SFTRACE_INT(name, value) ::tracing_perfetto::traceCounter32(ATRACE_TAG, name, value)
#define SFTRACE_INT64(name, value) ::tracing_perfetto::traceCounter(ATRACE_TAG, name, value)

// SFTRACE_NAME traces from its location until the end of its enclosing scope.
#define _PASTE(x, y) x##y
#define PASTE(x, y) _PASTE(x, y)
#define SFTRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(name)
// SFTRACE_CALL is an SFTRACE_NAME that uses the current function name.
#define SFTRACE_CALL() SFTRACE_NAME(__FUNCTION__)

#define SFTRACE_FORMAT(fmt, ...) \
    ::android::ScopedTrace PASTE(___tracer, __LINE__)(fmt, ##__VA_ARGS__)

#define ALOGE_AND_TRACE(fmt, ...)                   \
    do {                                            \
        ALOGE(fmt, ##__VA_ARGS__);                  \
        SFTRACE_FORMAT_INSTANT(fmt, ##__VA_ARGS__); \
    } while (false)

其实可以看出上面的宏其实和以前基本上一个样,就是以前是ATRACE现在要变成SFTRACE。

在这里插入图片描述
修改后再次编译:
在这里插入图片描述
一次性成果,所以对于SF中如果在aosp15想要加入相关的ATRACE等尽量建议使用
frameworks/native/services/surfaceflinger/common/include/common/trace.h
下的宏进行,不要再使用和引入utils/Trace.h。

更多framework实战干货,请关注下面“千里马学框架”

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值