babeltrace与CTF相关学习笔记-4
- 写在前面
- metadata_string
- 重头开始定位,操作meta的位置
- bt_ctf_trace_get_metadata_string
- stream部分
- 内存的问题
写在前面
正在并行做几件事。
在编译过程中,突然想到,还是再详细研究一下之前的例程。
一是详细找了一下,除了前述这例子,没有其它的有价值的,对眼前这件事情来说。
然后也花了一些时间,进一步了解babeltrace,发现,也没有多少有用的价值。
所以,还是重新看一下代码:meta是如何被创建的。
metadata_string
bt_ctf_writer_flush_metadata中,我们看到,metadata_string这个变量。
在bt_ctf_writer_flush_metadata被调用之前,metadata大小是0
而如下上代码处,
metata_string,已经包含了全部的信息:
0x5555555d8a00 "/* CTF 1.8 */\n\ntrace {\n\tmajor = 1;\n\tminor = 8;\n\tuuid = \"e5dbb979-0a16-45e9-8e11-427aeb6066ea\";\n\tbyte_order = be;\n\tpacket.header := struct {\n\t\tinteger { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = native; } magic;\n\t\tinteger { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = native; } uuid[16];\n\t\tinteger { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = native; } stream_id;\n\t\tinteger { size = 22;
....
全文前本系列2。
这就确实比较难办了。因为之前 就处理完成了。
重头开始定位,操作meta的位置
bt_ctf_trace_get_metadata_string
在这里,找到了一直想要的:
看到了曙光。
下一个问题是,研究序列化之前,是如何构建stream的内容的。
下面这几句,我们先跳过:
g_string_append(context->string, "/* CTF 1.8 */\n\n");
if (append_trace_metadata(trace, context)) {
/* append_trace_metadata() logs errors */
goto error;
}
append_env_metadata(trace, context);
g_ptr_array_foreach(trace->common.clock_classes,
(GFunc) bt_ctf_clock_class_serialize, context);
它们对应
/* CTF 1.8 */
trace {
major = 1;
minor = 8;
uuid = "6390b8a6-c2c9-4b5a-b575-bf8addb369b0";
byte_order = be;
packet.header := struct {
integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = native; } magic;
integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = native; } uuid[16];
integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = native; } stream_id;
integer { size = 22; align = 1; signed = false; encoding = none; base = decimal; byte_order = native; } custom_trace_packet_header_field;
} align(8);
};
env {
host = "testhost";
test_env_int = 654321;
test_env_str = "oh yeah";
sysname = "GNU/Linux";
nodename = "testhost";
release = "4.4.0-87-generic";
version = "#110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017";
machine = "x86_64";
new_field = "test";
};
clock {
name = test_clock;
uuid = "e004df4e-1bb0-42f2-8478-363763d6b160";
description = "This is a test clock";
freq = 1123456789;
precision = 10;
offset_s = 13515309;
offset = 1234567;
absolute = true;
};
注意,我不是说这些代码不重要,我也跟过了,也都相当复杂。
而且,我的工程中,肯定会引用这部分,这个头部,也不是那么好制作。
这里我不想写这些内容。因为重点还是stream的部分,我们先把这一段研究一下:
for (i = 0; i < trace->common.stream_classes->len; i++) {
/* bt_ctf_stream_class_serialize() logs details */
err = bt_ctf_stream_class_serialize(
trace->common.stream_classes->pdata[i], context);
if (err) {
/* bt_ctf_stream_class_serialize() logs errors */
goto error;
}
}
stream部分
代码见上,很简单,从trace中得到,所有的stream,然后序列化。
内存的问题
如下图,这可能是个重要的问题,context->string的长度,只有4096
根了一遍,很无聊。
原因是很常规,层层迭代,然后存到字符串中。
这里有两点,让我困到不行了,
一个,我现在更加关心这些schema的类是如何创建的。
显然后面的迭代,只是从已存在的class序列化。
第二,是因为序列化不应该这样写。
序列化的意思是存存,我们为什么要存盘,最重要的原因之一是减少内存的占用。
这种迭代是不对的!
比如在逻辑上,event是stream的子node,
但在现实中,到了文件层面,大家只是序列的一部分。
所以,这里的问题,需我要自己来处理。比较头疼。
nanolog中有成千上万个meta,不可能一次存盘。
跟踪的主要的点,我稍贴部分图在这里:
我们最关心的最小粒度是event,在这里:
先放在这里,有时间再看,因为现在要再从头来过,找到class创建的过程中,如何生成mata定义的。