c - 宏中未使用的参数会发生什么情况?

标签 c kernel tracepoint

这个问题来自于阅读内核,更具体地说是跟踪宏。当我研究内核模块如何执行二进制文件、elf 和脚本文件 (fs/exec.c) 时,我接触到了它们。

出于某种原因,我不记得哪个文件到达了tracepoint.h 文件,其中定义了宏TRACE_EVENT 等。我使用trace_event 作为示例,因为内核中的跟踪示例使用了该宏。该示例使用了宏

    TRACE_EVENT(foo_bar,

    TP_PROTO(const char *foo, int bar, const int *lst,
         const char *string, const struct cpumask *mask),

    TP_ARGS(foo, bar, lst, string, mask),

    TP_STRUCT__entry(
        __array(    char,   foo,    10      )
        __field(    int,    bar         )
        __dynamic_array(int,    list,   __length_of(lst))
        __string(   str,    string          )
        __bitmask(  cpus,   num_possible_cpus() )
    ),

    TP_fast_assign(
        strlcpy(__entry->foo, foo, 10);
        __entry->bar    = bar;
        memcpy(__get_dynamic_array(list), lst,
               __length_of(lst) * sizeof(int));
        __assign_str(str, string);
        __assign_bitmask(cpus, cpumask_bits(mask), num_possible_cpus());
    ),

    TP_printk("foo %s %d %s %s %s %s (%s)", __entry->foo, __entry->bar,
/*
 * Notice here the use of some helper functions. This includes:
 *
 *  __print_symbolic( variable, { value, "string" }, ... ),
 *
 *    The variable is tested against each value of the { } pair. If
 *    the variable matches one of the values, then it will print the
 *    string in that pair. If non are matched, it returns a string
 *    version of the number (if __entry->bar == 7 then "7" is returned).
 */
          __print_symbolic(__entry->bar,
                   { 0, "zero" },
                   { TRACE_SAMPLE_FOO, "TWO" },
                   { TRACE_SAMPLE_BAR, "FOUR" },
                   { TRACE_SAMPLE_ZOO, "EIGHT" },
                   { 10, "TEN" }
              ),

/*
 *  __print_flags( variable, "delim", { value, "flag" }, ... ),
 *
 *    This is similar to __print_symbolic, except that it tests the bits
 *    of the value. If ((FLAG & variable) == FLAG) then the string is
 *    printed. If more than one flag matches, then each one that does is
 *    also printed with delim in between them.
 *    If not all bits are accounted for, then the not found bits will be
 *    added in hex format: 0x506 will show BIT2|BIT4|0x500
 */
          __print_flags(__entry->bar, "|",
                { 1, "BIT1" },
                { 2, "BIT2" },
                { 4, "BIT3" },
                { 8, "BIT4" }
              ),
/*
 *  __print_array( array, len, element_size )
 *
 *    This prints out the array that is defined by __array in a nice format.
 */
          __print_array(__get_dynamic_array(list),
                __get_dynamic_array_len(list) / sizeof(int),
                sizeof(int)),
          __get_str(str), __get_bitmask(cpus))
);

所以,很自然地,在此之后我转到 TRACE_EVENT 的定义并找到了这个

#define TRACE_EVENT(名称、原型(prototype)、参数、结构、分配、打印)\ DECLARE_TRACE(名称, PARAMS(proto), PARAMS(args))

正如您所看到的,trace_event 宏不使用打印参数(或参数?),以及结构和分配参数。

非常清楚地表明该宏需要它们,但在其之下,它只是简单地调用不需要它们的declare_trace宏。

至于宏扩展的其余部分,我对此表示同意,没有什么意外的,但是宏的这种特殊用法让我感到烦恼。所有其他字段是否都有某种目的,或者它们只是......没有任何理由存在?

最佳答案

正如 @pvg 所说,linux/tracepoint.h 只是跟踪点的冰山一角。该 header 仅声明适当的函数和类型。这就是为什么它不处理 TRACE_EVENT 的某些参数。

但是带有跟踪定义的 header 会处理两次(甚至更多次),并且下次处理 TRACE_EVENT 的所有参数。

有关 Linux 内核中跟踪点的更多信息,请参阅 Documentation/trace/tracepoints.txt .

关于c - 宏中未使用的参数会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43724923/

相关文章:

c - 为什么 bpf 代码无法访问 cpumap_enqueue_ctx 的前 8 个字节?

c - tracepoint/syscalls/sys_enter 不触发 bpf_trace_printk

c - 在谈论 C 语言时,动态创建的结构是什么意思?

c++ - `intmax_t` 在具有 64 位 `long int` 和 `long long int` 的平台上应该是什么?

c - 如何获取已安装文件系统的列表

sed - 尝试安装新内核,错误 modules.order & Makefile Error 2

c - 在 C 项目中定义

mapping - 关于与核函数和支持向量机相关的术语的具体查询

linux - 是否需要在 del_timer() 之后再次调用 init_timer()