gpt4 book ai didi

android - 是否可以在没有 JNI 的情况下直接从 native 代码记录 Android systrace 事件?

转载 作者:太空宇宙 更新时间:2023-11-03 11:31:52 25 4
gpt4 key购买 nike

Android systrace 日志记录系统非常棒,但它仅适用于代码的 Java 部分,通过 Trace.beginSection()Trace.endSection()。在代码的 C/C++ NDK( native )部分中,它只能通过 JNI 使用,这在没有 Java 环境的线程中速度很慢或不可用...

有没有办法从 native C 代码向主系统跟踪跟踪缓冲区添加事件,甚至生成单独的日志?

This较早的问题提到 atrace/ftrace 是 Android 的 systrace 使用的内部系统。这可以(轻松)利用吗?

BONUS TWIST:由于跟踪调用通常处于性能关键部分,因此理想情况下应该可以在实际事件时间 之后运行调用。也就是说,我个人更愿意能够指定记录的时间,而不是调用自己轮询的时间。但这只是锦上添花。

最佳答案

根据 fadden 的指示发布带有一些代码的后续答案。请先阅读他/她的回答以获得概述。

只需将格式正确的字符串写入/sys/kernel/debug/tracing/trace_marker,即可毫无问题地打开。下面是一些基于 cutils header 的非常简单的代码和 C file .我更喜欢重新实现它而不是引入任何依赖项,所以如果你非常关心正确性,请检查那里的严格实现,和/或添加你自己的额外检查和错误处理。

这已经过测试,可以在 Android 4.4.2 上运行。

必须首先打开跟踪文件,将文件描述符保存在 atrace_marker_fd 全局中:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define ATRACE_MESSAGE_LEN 256
int atrace_marker_fd = -1;

void trace_init()
{
atrace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY);
if (atrace_marker_fd == -1) { /* do error handling */ }
}

正常的“嵌套”跟踪,如 Java Trace.beginSectionTrace.endSection 是通过以下方式获得的:

inline void trace_begin(const char *name)
{
char buf[ATRACE_MESSAGE_LEN];
int len = snprintf(buf, ATRACE_MESSAGE_LEN, "B|%d|%s", getpid(), name);
write(atrace_marker_fd, buf, len);
}

inline void trace_end()
{
char c = 'E';
write(atrace_marker_fd, &c, 1);
}

还有两种可用的跟踪类型,据我所知,Java 无法访问它们:跟踪计数器和异步跟踪。

Counters 跟踪整数值并在 systrace HTML 输出中绘制一个小图形。非常有用的东西:

inline void trace_counter(const char *name, const int value)
{
char buf[ATRACE_MESSAGE_LEN];
int len = snprintf(buf, ATRACE_MESSAGE_LEN, "C|%d|%s|%i", getpid(), name, value);
write(atrace_marker_fd, buf, len);
}

异步跟踪 产生非嵌套(即简单重叠)的间隔。它们在 systrace HTML 输出中显示为细线程状态栏上方的灰色段。他们采用一个额外的 32 位整数参数来“区分同时发生的事件”。结束跟踪时必须使用相同的名称和整数:

inline void trace_async_begin(const char *name, const int32_t cookie)
{
char buf[ATRACE_MESSAGE_LEN];
int len = snprintf(buf, ATRACE_MESSAGE_LEN, "S|%d|%s|%i", getpid(), name, cookie);
write(atrace_marker_fd, buf, len);
}

inline void trace_async_end(const char *name, const int32_t cookie)
{
char buf[ATRACE_MESSAGE_LEN];
int len = snprintf(buf, ATRACE_MESSAGE_LEN, "F|%d|%s|%i", getpid(), name, cookie);
write(atrace_marker_fd, buf, len);
}

最后,除了重新编译 Android 之外,似乎确实没有指定记录时间的方法,所以这对“奖励扭曲”没有任何作用。

关于android - 是否可以在没有 JNI 的情况下直接从 native 代码记录 Android systrace 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28001915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com