systrace/perfetto中需要actrace打tag相關(guān)方法-車載車機(jī)framework系統(tǒng)開發(fā)實戰(zhàn)
背景:
經(jīng)常在看systrace、perfetto相關(guān)trace時候,其實我們主要就是看各種方法的調(diào)用tag,如下圖所示

正因為有了系統(tǒng)中各個地方埋下的這些tag,才讓我們可以根據(jù)這些方法tag分析出整個系統(tǒng)的運行情況。但是大家有沒有想過,請問這些tag是怎么打上去的?如果我們自己要打印自己方法的tag應(yīng)該怎么搞?
使用atrace相關(guān)類方法介紹
這里還需要看對應(yīng)的trace源碼是最全面的 路徑:system/core/libcutils/include/cutils/trace.h 源碼:
/*
?*?Copyright?(C)?2012?The?Android?Open?Source?Project
?*
?*?Licensed?under?the?Apache?License,?Version?2.0?(the?"License");
?*?you?may?not?use?this?file?except?in?compliance?with?the?License.
?*?You?may?obtain?a?copy?of?the?License?at
?*
?*??????http://www.apache.org/licenses/LICENSE-2.0
?*
?*?Unless?required?by?applicable?law?or?agreed?to?in?writing,?software
?*?distributed?under?the?License?is?distributed?on?an?"AS?IS"?BASIS,
?*?WITHOUT?WARRANTIES?OR?CONDITIONS?OF?ANY?KIND,?either?express?or?implied.
?*?See?the?License?for?the?specific?language?governing?permissions?and
?*?limitations?under?the?License.
?*/
__BEGIN_DECLS
/**
?*?The?ATRACE_TAG?macro?can?be?defined?before?including?this?header?to?trace
?*?using?one?of?the?tags?defined?below.??It?must?be?defined?to?one?of?the
?*?following?ATRACE_TAG_*?macros.??The?trace?tag?is?used?to?filter?tracing?in
?*?userland?to?avoid?some?of?the?runtime?cost?of?tracing?when?it?is?not?desired.
?*
?*?Defining?ATRACE_TAG?to?be?ATRACE_TAG_ALWAYS?will?result?in?the?tracing?always
?*?being?enabled?-?this?should?ONLY?be?done?for?debug?code,?as?userland?tracing
?*?has?a?performance?cost?even?when?the?trace?is?not?being?recorded.??Defining
?*?ATRACE_TAG?to?be?ATRACE_TAG_NEVER?or?leaving?ATRACE_TAG?undefined?will?result
?*?in?the?tracing?always?being?disabled.
?*
?*?ATRACE_TAG_HAL?should?be?bitwise?ORed?with?the?relevant?tags?for?tracing
?*?within?a?hardware?module.??For?example?a?camera?hardware?module?would?set:
?*?#define?ATRACE_TAG??(ATRACE_TAG_CAMERA?|?ATRACE_TAG_HAL)
?*
?*?Keep?these?in?sync?with?frameworks/base/core/java/android/os/Trace.java.
?*/
//?Reserved?for?initialization.
/**
?*?Opens?the?trace?file?for?writing?and?reads?the?property?for?initial?tags.
?*?The?atrace.tags.enableflags?property?sets?the?tags?to?trace.
?*?This?function?should?not?be?explicitly?called,?the?first?call?to?any?normal
?*?trace?function?will?cause?it?to?be?run?safely.
?*/
void?atrace_setup();
/**
?*?If?tracing?is?ready,?set?atrace_enabled_tags?to?the?system?property
?*?debug.atrace.tags.enableflags.?Can?be?used?as?a?sysprop?change?callback.
?*/
void?atrace_update_tags();
/**
?*?Set?whether?tracing?is?enabled?for?the?current?process.??This?is?used?to
?*?prevent?tracing?within?the?Zygote?process.
?*/
void?atrace_set_tracing_enabled(bool?enabled);
/**
?*?This?is?always?set?to?false.?This?forces?code?that?uses?an?old?version
?*?of?this?header?to?always?call?into?atrace_setup,?in?which?we?call
?*?atrace_init?unconditionally.
?*/
extern?atomic_bool?atrace_is_ready;
/**
?*?Set?of?ATRACE_TAG?flags?to?trace?for,?initialized?to?ATRACE_TAG_NOT_READY.
?*?A?value?of?zero?indicates?setup?has?failed.
?*?Any?other?nonzero?value?indicates?setup?has?succeeded,?and?tracing?is?on.
?*/
extern?uint64_t?atrace_enabled_tags;
/**
?*?Handle?to?the?kernel's?trace?buffer,?initialized?to?-1.
?*?Any?other?value?indicates?setup?has?succeeded,?and?is?a?valid?fd?for?tracing.
?*/
extern?int?atrace_marker_fd;
/**
?*?atrace_init?readies?the?process?for?tracing?by?opening?the?trace_marker?file.
?*?Calling?any?trace?function?causes?this?to?be?run,?so?calling?it?is?optional.
?*?This?can?be?explicitly?run?to?avoid?setup?delay?on?first?trace?function.
?*/
void?atrace_init();
uint64_t?atrace_get_enabled_tags();
/**
?*?Test?if?a?given?tag?is?currently?enabled.
?*?Returns?nonzero?if?the?tag?is?enabled,?otherwise?zero.
?*?It?can?be?used?as?a?guard?condition?around?more?expensive?trace?calculations.
?*/
static?inline?uint64_t?atrace_is_tag_enabled(uint64_t?tag)
{
????return?atrace_get_enabled_tags()?&?tag;
}
/**
?*?Trace?the?beginning?of?a?context.??name?is?used?to?identify?the?context.
?*?This?is?often?used?to?time?function?execution.
?*/
static?inline?void?atrace_begin(uint64_t?tag,?const?char*?name)
{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_begin_body(const?char*);
????????atrace_begin_body(name);
????}
}
/**
?*?Trace?the?end?of?a?context.
?*?This?should?match?up?(and?occur?after)?a?corresponding?ATRACE_BEGIN.
?*/
static?inline?void?atrace_end(uint64_t?tag)
{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_end_body();
????????atrace_end_body();
????}
}
/**
?*?Trace?the?beginning?of?an?asynchronous?event.?Unlike?ATRACE_BEGIN/ATRACE_END
?*?contexts,?asynchronous?events?do?not?need?to?be?nested.?The?name?describes
?*?the?event,?and?the?cookie?provides?a?unique?identifier?for?distinguishing
?*?simultaneous?events.?The?name?and?cookie?used?to?begin?an?event?must?be
?*?used?to?end?it.
?*/
static?inline?void?atrace_async_begin(uint64_t?tag,?const?char*?name,
????????int32_t?cookie)
{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_async_begin_body(const?char*,?int32_t);
????????atrace_async_begin_body(name,?cookie);
????}
}
/**
?*?Trace?the?end?of?an?asynchronous?event.
?*?This?should?have?a?corresponding?ATRACE_ASYNC_BEGIN.
?*/
static?inline?void?atrace_async_end(uint64_t?tag,?const?char*?name,?int32_t?cookie)
{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_async_end_body(const?char*,?int32_t);
????????atrace_async_end_body(name,?cookie);
????}
}
/**
?*?Trace?the?beginning?of?an?asynchronous?event.?In?addition?to?the?name?and?a
?*?cookie?as?in?ATRACE_ASYNC_BEGIN/ATRACE_ASYNC_END,?a?track?name?argument?is
?*?provided,?which?is?the?name?of?the?row?where?this?async?event?should?be
?*?recorded.?The?track?name,?name,?and?cookie?used?to?begin?an?event?must?be
?*?used?to?end?it.
?*/
static?inline?void?atrace_async_for_track_begin(uint64_t?tag,?const?char*?track_name,
????????????????????????????????????????????????const?char*?name,?int32_t?cookie)?{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_async_for_track_begin_body(const?char*,?const?char*,?int32_t);
????????atrace_async_for_track_begin_body(track_name,?name,?cookie);
????}
}
/**
?*?Trace?the?end?of?an?asynchronous?event.
?*?This?should?correspond?to?a?previous?ATRACE_ASYNC_FOR_TRACK_BEGIN.
?*/
static?inline?void?atrace_async_for_track_end(uint64_t?tag,?const?char*?track_name,
??????????????????????????????????????????????const?char*?name,?int32_t?cookie)?{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_async_for_track_end_body(const?char*,?const?char*,?int32_t);
????????atrace_async_for_track_end_body(track_name,?name,?cookie);
????}
}
/**
?*?Trace?an?instantaneous?context.?name?is?used?to?identify?the?context.
?*
?*?An?"instant"?is?an?event?with?no?defined?duration.?Visually?is?displayed?like?a?single?marker
?*?in?the?timeline?(rather?than?a?span,?in?the?case?of?begin/end?events).
?*
?*?By?default,?instant?events?are?added?into?a?dedicated?track?that?has?the?same?name?of?the?event.
?*?Use?atrace_instant_for_track?to?put?different?instant?events?into?the?same?timeline?track/row.
?*/
static?inline?void?atrace_instant(uint64_t?tag,?const?char*?name)?{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_instant_body(const?char*);
????????atrace_instant_body(name);
????}
}
/**
?*?Trace?an?instantaneous?context.?name?is?used?to?identify?the?context.
?*?track_name?is?the?name?of?the?row?where?the?event?should?be?recorded.
?*
?*?An?"instant"?is?an?event?with?no?defined?duration.?Visually?is?displayed?like?a?single?marker
?*?in?the?timeline?(rather?than?a?span,?in?the?case?of?begin/end?events).
?*/
static?inline?void?atrace_instant_for_track(uint64_t?tag,?const?char*?track_name,
????????????????????????????????????????????const?char*?name)?{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_instant_for_track_body(const?char*,?const?char*);
????????atrace_instant_for_track_body(track_name,?name);
????}
}
/**
?*?Traces?an?integer?counter?value.??name?is?used?to?identify?the?counter.
?*?This?can?be?used?to?track?how?a?value?changes?over?time.
?*/
static?inline?void?atrace_int(uint64_t?tag,?const?char*?name,?int32_t?value)
{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_int_body(const?char*,?int32_t);
????????atrace_int_body(name,?value);
????}
}
/**
?*?Traces?a?64-bit?integer?counter?value.??name?is?used?to?identify?the
?*?counter.?This?can?be?used?to?track?how?a?value?changes?over?time.
?*/
static?inline?void?atrace_int64(uint64_t?tag,?const?char*?name,?int64_t?value)
{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_int64_body(const?char*,?int64_t);
????????atrace_int64_body(name,?value);
????}
}
__END_DECLS
日常使用trace打TAG其實本質(zhì)上都是基于這個類的,在這個的基礎(chǔ)上會加一些額外包裝 比如常見的幾個方法:1、ATRACE_CALL();這個方法,代表對一個function的開頭和結(jié)尾進(jìn)行tag,它的源碼如下 #define ATRACE_CALL() ATRACE_NAME(FUNCTION) 即本質(zhì)調(diào)用的是ATRACE_NAME
調(diào)用如下:

2、ATRACE_NAME方法
這個方法的本質(zhì)定義如下
//這里的ATRACE_NAME其實本質(zhì)是個臨時對象構(gòu)造和析構(gòu)進(jìn)行調(diào)用的atrace_begin和atrace_end,這兩個其實就是trace.h原始方法
調(diào)用如下:
namespace?android?{
//臨時對象,調(diào)用該時候該對象剛好構(gòu)造,一般方法域結(jié)束就代表作用無效了,因為會進(jìn)行對象的析構(gòu)
class?ScopedTrace?{
public:
????inline?ScopedTrace(uint64_t?tag,?const?char*?name)?:?mTag(tag)?{
????????atrace_begin(mTag,?name);//構(gòu)造時候進(jìn)行begin
????????????}
????inline?~ScopedTrace()?{
????????atrace_end(mTag);//析構(gòu)時候代表trace結(jié)束end
????}
private:
????uint64_t?mTag;
};

效果如下:

其他常見還有3、ATRACE_INT具體源碼:/**
代碼調(diào)用:
?*?Traces?an?integer?counter?value.??name?is?used?to?identify?the?counter.
?*?This?can?be?used?to?track?how?a?value?changes?over?time.
?*/
static?inline?void?atrace_int(uint64_t?tag,?const?char*?name,?int32_t?value)
{
????if?(CC_UNLIKELY(atrace_is_tag_enabled(tag)))?{
????????void?atrace_int_body(const?char*,?int32_t);
????????atrace_int_body(name,?value);
????}
}

效果如下:

trace相關(guān)實戰(zhàn)使用:
1、引入相關(guān)的頭文件及相關(guān)庫 #include <utils/Trace.h> 編譯時候還得考率相關(guān)utils的lib是否引入 如這里以截圖代碼為例就有引入libutils frameworks/base/cmds/screencap/Android.bp
cc_binary?{
????name:?"screencap",
????srcs:?["screencap.cpp"],
????shared_libs:?[
????????"libcutils",
????????"libutils",
????????"libbinder",
????????"libjnigraphics",
????????"libui",
????????"libgui",
????],
????cflags:?[
????????"-Wall",
????????"-Werror",
????????"-Wunused",
????????"-Wunreachable-code",
????],
}
2、定義好相關(guān)的TAG
?
這里就選了一個ATRACE_TAG_GRAPHICS即graphics這個組
3、調(diào)用相關(guān)actrace方法 ATRACE_CALL ATRACE_NAME 一般針對整個方法或者單獨作用域,ATRACE_CALL和ATRACE_NAME本質(zhì)沒有區(qū)別,只是把名字變成了function的name

具體效果如下:

優(yōu)點:只需要一個調(diào)用既可以實現(xiàn)tag打印,自動跟隨作用域進(jìn)行tag的結(jié)束 缺點:需要自己熟練掌握好作用域,沒有可以手動控制的tag結(jié)束的點
4、相關(guān)靈活控制開始與結(jié)束的trace方法 直接使用atrace_begin和atrace_end方法,使用如下:
GraphicBuffer::GraphicBuffer()
具體效果如下:
????:?BASE(),?mOwner(ownData),?mBufferMapper(GraphicBufferMapper::get()),
??????mInitCheck(NO_ERROR),?mId(getUniqueId()),?mGenerationNumber(0)
{
????ATRACE_NAME("GraphicBuffer::GraphicBuffer()1");
????atrace_begin(ATRACE_TAG,?"GraphicBuffer?1");
????width??=
????height?=
????stride?=
????format?=
????usage_deprecated?=?0;
????atrace_end(ATRACE_TAG);
????usage??=?0;
????layerCount?=?0;
????handle?=?nullptr;
}

同時也可以使用對應(yīng)宏定義: ? ?ATRACE_BEGIN(name); ? ?ATRACE_END(); 來控制

執(zhí)行后效果如下:

更多framework干貨手把手教學(xué)視頻及答疑可以看這里,可以加我v(androidframework007)獲?。?/p>
https://blog.csdn.net/learnframework/article/details/132739059