简体   繁体   中英

Pointer value changing across function call

I have the following structures in the 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;
};

I've defined a function tune() as follows:

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);
}

The other functions are defined as:

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
}

When I call tune() , the output is as follows:

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

I don't understand why the addresses differ by 0x8 . This in turn causes a divide by 0 exception in the kernel since the struct parameters seems to have values of 0 instead of what was initialized by get_current_params

Why is it that the address of the member current_params of struct state changes across function calls?

Update :
I've verified that this bug only occurs for PID 0.
Looking at include/linux/init_task.h , I see that PID 0 is statically initialized. This is the only difference I could find between PID 0 and the other tasks. Could this somehow be responsible for the issue I'm having?

For what I can see, you are right in that both addresses should be the same. So there can only be one option: task information changes in the kernel in the meanwhile.

Considering this snippet of your code:

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

You are managing two structs over which you may have no control (you should check that):

(*task): struct task_struct

and

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

So when in tune() you call

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

something could happen between both printk functions, so there is where I think you have to put your focus in. Try saving task->tuning.state before the call to get_current_params() so you could check that it continues to be the same value after call to compute_energy() .

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM