函数调用中的指针值发生变化

时间:2015-06-18 00:28:06

标签: c linux pointers kernel

我在内核中有以下结构

struct state {
    /* Current algorithm iteration */
    int tune_id;
    /* Thread id */
    pid_t tid;
#ifndef __KERNEL__
    /* Paths */
    char *stats_path;
    char *budget_path;
    char *controller_path;
#endif  /* __KERNEL__ */
    int budget;
    /* Stats */
    struct statistics prev_stats;
    struct parameters current_params;
    u64 cur_time;
    /* Algorithm specific data */
    void *data;
};

struct tuning {
    struct algorithm *algorithm;
    struct state *state;
    struct energy energy;
};

我已经定义了一个函数tune(),如下所示:

void tune(struct task_struct *task) {
    struct statistics stats;
    struct state *state;
    get_current_stats(&stats);
    state = task->tuning.state;

    get_current_params(&state->current_params);
    compute_energy(&stats, state);
}

其他功能定义为:

void get_current_params(struct parameters *params)
{
    printk(KERN_DEBUG "get_current_params: parameters:0x%X\n", (unsigned int) params);
    params->cpu_frequency_MHZ = (cpufreq_get(0) + 500) / 1000;
    params->mem_frequency_MHZ = (memfreq_get() + 500) / 1000;
}

void compute_energy(struct statistics *stats, struct state *state)
{
    struct statistics *diffs;
    struct frontier *frontier;
    u64 energy_budget;
    int threshold;

    int i,j;
    struct configuration s;
    struct configuration emin;

#ifdef TIMING
    u64 ns;
    ns = get_thread_time();
 #endif

#ifdef DEBUG
#ifdef __KERNEL__
    printk(KERN_DEBUG "compute_energy: parameters:0x%X\n", (unsigned int) &state->current_params);
#endif  /* __KERNEL__ */
#endif
}

当我拨打tune()时,输出如下:

[    7.160139] get_current_params: parameters:0xBF396BA0
[    7.160298] compute_energy: parameters:0xBF396B98

我不明白地址因0x8而异的原因。 这反过来导致内核中除以0异常,因为struct parameters似乎具有0的值而不是get_current_params初始化的值

为什么current_params的成员struct state的地址会在函数调用中发生变化?

更新
我已经确认这个错误仅发生在PID 0上。
查看include/linux/init_task.h,我看到PID 0已静态初始化。这是我在PID 0和其他任务之间找到的唯一区别。这可能以某种方式对我遇到的问题负责吗?

1 个答案:

答案 0 :(得分:1)

对于我所看到的,你说得对,两个地址都应该是一样的。因此,只能有一个选项:同时内核中的任务信息发生变化。

考虑您的代码片段:

void tune(struct task_struct *task) {
    ...
    struct state *state;
    ...
    state = task->tuning.state;

您正在管理两个您可能无法控制的结构(您应该检查它):

(*task): struct task_struct

(*task->tuning.state): struct state

所以当你在tune()打电话时

get_current_params(&state->current_params);
compute_energy(&stats, state);

两个printk函数之间可能会发生某些事情,所以我认为你必须把重点放在哪里。 尝试在致电task->tuning.state之前保存get_current_params(),这样您就可以在致电compute_energy()后检查它是否仍然是相同的值。

希望这有帮助。