systrace学习atrace打开各系统层tag开关的原理
atrace命令可以开启trace,让系统中埋下的trace标记开始记录,这是怎么实现的呢,
我们以系统层的trace为例来查看,
atrace的代码
frameworks/native/cmds/atrace/atrace.cpp
93/* Tracing categories */
94static const TracingCategory k_categories[] = {
95 { "gfx", "Graphics", ATRACE_TAG_GRAPHICS, {
96 { OPT, "events/mdss/enable" },
97 { OPT, "events/sde/enable" },
98 } },
99 { "input", "Input", ATRACE_TAG_INPUT, { } },
100 { "view", "View System", ATRACE_TAG_VIEW, { } },
101 { "webview", "WebView", ATRACE_TAG_WEBVIEW, { } },
102 { "wm", "Window Manager", ATRACE_TAG_WINDOW_MANAGER, { } },
里面通过设置属性的值,来传递信息,即哪些tag需要进行记录
606// Set the trace tags that userland tracing uses, and poke the running
607// processes to pick up the new value.
608static bool setTagsProperty(uint64_t tags)
609{
610 std::string value = android::base::StringPrintf("%#" PRIx64, tags);
611 if (!android::base::SetProperty(k_traceTagsProperty, value)) {
612 fprintf(stderr, "error setting trace tags system property\n");
613 return false;
614 }
615 return true;
616}
60const char* k_traceTagsProperty = "debug.atrace.tags.enableflags";
执行函数由于执行的次数很多,所以没有必要每次都读取属性 debug.atrace.tags.enableflags的值来判断当前tag是否需要打印,只需要读一次,保存下来即可。
但是进程怎么知道属性值变化了呢,这里调用每个系统服务的SYSPROPS_TRANSACTION方法,来推送,
531// Poke all the binder-enabled processes in the system to get them to re-read
532// their system properties.
533static bool pokeBinderServices()
534{
535 sp<IServiceManager> sm = defaultServiceManager();
536 Vector<String16> services = sm->listServices();
537 for (size_t i = 0; i < services.size(); i ) {
538 sp<IBinder> obj = sm->checkService(services[i]);
539 if (obj != NULL) {
540 Parcel data;
541 if (obj->transact(IBinder::SYSPROPS_TRANSACTION, data,
542 NULL, 0) != OK) {
543 if (false) {
544 // XXX: For some reason this fails on tablets trying to
545 // poke the "phone" service. It's not clear whether some
546 // are expected to fail.
547 String8 svc(services[i]);
548 fprintf(stderr, "error poking binder service %s\n",
549 svc.string());
550 return false;
551 }
552 }
553 }
554 }
555 return true;
556}
SYSPROPS_TRANSACTION 方法执行起来做什么?
status_t BBinder::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
{
switch (code) {
...
case SYSPROPS_TRANSACTION: {
report_sysprop_change();
return NO_ERROR;
}
...
}
}
report_sysprop_change()方法会调用属性变化的回调函数,
-
void report_sysprop_change() {
-
do_report_sysprop_change();
-
-
-
// libutils.so is double loaded; from the default namespace and from the
-
// 'sphal' namespace. Redirect the sysprop change event to the other instance
-
// of libutils.so loaded in the 'sphal' namespace so that listeners attached
-
// to that instance is also notified with this event.
-
static auto func = get_report_sysprop_change_func();
-
if (func != nullptr) {
-
(*func)();
-
}
-
-
}
所以,服务进程中写了回调函数后,就可以更新属性的值了。
这里使用了binder来进行通知。
InputDispatcher里的trace调用
3868void InputDispatcher::traceInboundQueueLengthLocked() {
3869 if (ATRACE_ENABLED()) {
3870 ATRACE_INT("iq", mInboundQueue.count());
3871 }
3872}
ATRACE_ENABLED
/system/core/include/cutils/ | ||
H A D | trace.h | 168 #define ATRACE_ENABLED() atrace_is_tag_enabled(ATRACE_TAG) |
156#define ATRACE_GET_ENABLED_TAGS() atrace_get_enabled_tags()
157static inline uint64_t atrace_get_enabled_tags()
158{
159 atrace_init();
160 return atrace_enabled_tags;
161}
162
163/**
164 * Test if a given tag is currently enabled.
165 * Returns nonzero if the tag is enabled, otherwise zero.
166 * It can be used as a guard condition around more expensive trace calculations.
167 */
168#define ATRACE_ENABLED() atrace_is_tag_enabled(ATRACE_TAG)
169static inline uint64_t atrace_is_tag_enabled(uint64_t tag)
170{
171 return atrace_get_enabled_tags() & tag;
172}
调用traceInit()可以设置属性变化的回调,会调用
22static void traceInit() {
23 ::android::add_sysprop_change_callback(atrace_update_tags, 0);
24}
这里有个很有意思的知识点,在代码中搜不到traceInit的调用,只看到定义,
20static void traceInit() __attribute__((constructor));
21
22static void traceInit() {
23 ::android::add_sysprop_change_callback(atrace_update_tags, 0);
24}
那到底是怎样设置的回调函数呢?
其实设置了 __attribute__((constructor)) 这个高端写法,在main函数开始的地方,就会调用traceInit方法,我们可以搜一下 __attribute__((constructor))这个用法。也可以写个例子来验证这种调用,情况确实如此。
查看atrace_update_tags的定义,在里面读取属性"debug.atrace.tags.enableflags"的值,更新了atrace_enabled_tags的值,
98/**
99 * If tracing is ready, set atrace_enabled_tags to the system property
100 * debug.atrace.tags.enableflags. Can be used as a sysprop change callback.
101 */
102void atrace_update_tags();
在 system/core/libcutils/trace-dev.inc
里有其实现,获取了要监控的属性值
136// Update tags if tracing is ready. Useful as a sysprop change callback.
137void atrace_update_tags()
138{
139 uint64_t tags;
140 if (CC_UNLIKELY(atomic_load_explicit(&atrace_is_ready, memory_order_acquire))) {
141 if (atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {
142 tags = atrace_get_property();
143 pthread_mutex_lock(&atrace_tags_mutex);
144 atrace_enabled_tags = tags;
145 pthread_mutex_unlock(&atrace_tags_mutex);
146 } else {
147 // Tracing is disabled for this process, so we simply don't
148 // initialize the tags.
149 pthread_mutex_lock(&atrace_tags_mutex);
150 atrace_enabled_tags = ATRACE_TAG_NOT_READY;
151 pthread_mutex_unlock(&atrace_tags_mutex);
152 }
153 }
154}
总结:
细节很多,这里回顾一下大体过程,atrace里设置tag,标识哪些tag可以进行写trace,然后写到属性值debug.atrace.tags.enableflags里,atrace又进行了binder调用所有系统服务的SYSPROPS_TRANSACTION对应的方法,告诉它们,属性值变化了,可以调用属性变化回调函数了。
系统服务进程就调用预定的回调函数,读取debug.atrace.tags.enableflags的值,保存起来,以后就可以用这个值来和tag进行比较,判断当前的tag是否需要写trace,避免每次都属性值,那个读取代价太大。
普通应用中的trace原理类似,也是设置了属性值。
相关知识点:属性值的变化可以设置回调函数。
binder中竟然有个冷门方法SYSPROPS_TRANSACTION,通知属性值的变化。
参考资料:
[Android systrace系列] systrace的信息从哪里来 - zzc1024 - 博客园
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfagge
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01