对于开源项目的研究--uftrace

总结开源项目 uftrace 中的编程技巧

对于Makefile的研究

简洁、美观的操作

编程不仅仅是对于功能上的实现,源码的简洁、明了也提高代码的可读性。通过对该项目的Makefile文件的研究,我发现了一下的操作可以提高代码的可读性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
_TARGETS := uftrace python/uftrace_python.so
_TARGETS += $(LIBMCOUNT_TARGETS) libmcount/libmcount-nop.so
_TARGETS += misc/demangler misc/symbols misc/dbginfo
TARGETS := $(patsubst %,$(objdir)/%,$(_TARGETS))

UFTRACE_SRCS := $(srcdir)/uftrace.c $(wildcard $(srcdir)/cmds/*.c $(srcdir)/utils/*.c)
UFTRACE_OBJS := $(patsubst $(srcdir)/%.c,$(objdir)/%.o,$(UFTRACE_SRCS))

UFTRACE_OBJS_VERSION := $(objdir)/cmds/script.o $(objdir)/cmds/tui.o
UFTRACE_OBJS_VERSION += $(objdir)/cmds/dump.o $(objdir)/cmds/info.o

DEMANGLER_SRCS := $(srcdir)/misc/demangler.c $(srcdir)/utils/demangle.c
DEMANGLER_SRCS += $(srcdir)/utils/debug.c $(srcdir)/utils/utils.c
DEMANGLER_OBJS := $(patsubst $(srcdir)/%.c,$(objdir)/%.o,$(DEMANGLER_SRCS))

SYMBOLS_SRCS := $(srcdir)/misc/symbols.c $(srcdir)/utils/session.c
SYMBOLS_SRCS += $(srcdir)/utils/demangle.c $(srcdir)/utils/rbtree.c
SYMBOLS_SRCS += $(srcdir)/utils/utils.c $(srcdir)/utils/debug.c
SYMBOLS_SRCS += $(srcdir)/utils/filter.c $(srcdir)/utils/dwarf.c
SYMBOLS_SRCS += $(srcdir)/utils/auto-args.c $(srcdir)/utils/regs.c
SYMBOLS_SRCS += $(srcdir)/utils/argspec.c

总结

通过上述代码,可以发现如果某个变量过长的话,应该要将其缩短。这里使用的方法就是通过+=来实现的。

在C语言中的符号\被专门用来连接上下两行。

对于源代码的研究

关于提示消息的输入输出

在这个项目中使用__attrabute__((nead)) static const uftrace_help []来存储帮助信息。使用了__attrabute__((nead))来告诉编译器就算没有使用这个对象也不要优化它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define __used __attribute__((used))

__used static const char uftrace_usage[] =
" uftrace -- function (graph) tracer for userspace\n"
"\n"
" usage: uftrace [COMMAND] [OPTION...] [<program>]\n"
"\n"
" COMMAND:\n"
" record Run a program and saves the trace data\n"
" replay Show program execution in the trace data\n"
" report Show performance statistics in the trace data\n"
" live Do record and replay in a row (default)\n"
" info Show system and program info in the trace data\n"
" dump Show low-level trace data\n"
" recv Save the trace data from network\n"
" graph Show function call graph in the trace data\n"
" script Run a script for recorded trace data\n"
" tui Show text user interface for graph and report\n"
"\n";

然后使用变参函数vprintf将其输出:

1
2
3
4
5
6
7
8
9
10
11
12
void __pr_dbg(const char *fmt, ...)
{
va_list ap;

color(TERM_COLOR_GRAY, logfp);

va_start(ap, fmt);
vfprintf(logfp, fmt, ap);
va_end(ap);

color(TERM_COLOR_RESET, logfp);
}

调用该函数:

1
__pr_dbg(uftrace_usage);

所以这里需要注意的是,虽然使用的是变参函数printf的变体,但是没有直接使用变参函数。而是使用fmt

关于这个可变参数函数的用法:

1
2
#define PR_FMT "uftrace"
__pr_dbg(PR_FMT ": %s:%d:%s\n ERROR: " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)

需要注意两点:

  • fmt之前还可以添加字符串
  • __VA_ARGS__必之前须要添加##

可变参数的其他使用

可以使用这中函数来输出日志;

1
__pr_dbg("")

对于开源项目的研究--uftrace
https://ysc2.github.io/ysc2.github.io/2023/12/29/对于开源项目的研究-uftrace/
作者
Ysc
发布于
2023年12月29日
许可协议