kernel/user.c:171: error: dereferencing pointer to incomplete type

Hi Guys,

I am building a kernel for a class, based off of the 2.6.24.7 source, and am running into an annoying error. I normally do not program in C, so that may be part of the problem.

I made some modifications, and here's the error:

kernel/user.c: In function ‘sched_create_user’: kernel/user.c:167: warning: statement with no effect kernel/user.c:168: warning: statement with no effect kernel/user.c:169: warning: ISO C90 forbids mixed declarations and code kernel/user.c:171: error: dereferencing pointer to incomplete type make[1]: *** [kernel/user.o] Error 1 make: *** [kernel] Error 2

The function code itself:

static int sched_create_user(struct user_struct *up) { int rc = 0;

up->tg = sched_create_group();


if (IS_ERR(up->tg))
	rc = -ENOMEM;
// Patch
//set_tg_uid(up);
up->uid;
up->tg;
struct task_group * group = up->tg;
uid_t userid = up->uid; 
group->uid = userid; // line 171

list_add(&up->fair_sched_list, &user_list); // Adds the user to the list.
atomic_inc(&users); // Adds a user (increment). Presumably atomically.
assignusercputime(); // Divides up the CPU time equally among users.

return rc;

}

Here's the task_group struct:

struct task_group {

#ifdef CONFIG_FAIR_CGROUP_SCHED struct cgroup_subsys_state css;

#endif

/* schedulable entities of this group on each cpu */
struct sched_entity **se;
/* runqueue "owned" by this group on each cpu */
struct cfs_rq **cfs_rq;
unsigned long shares;
/* spinlock to serialize modification to shares */
spinlock_t lock;
struct rcu_head rcu;
uid_t uid;

};

All I am attempting to do is set the task_group uid to the userr_struct's uid. Does anyone have any ideas why it's dong this?

Posted Sep 23, 2011, 6:03 AM UTC

313
HotRodLincoln•
struct task_group * group = up->tg;

That looks fishy. You have to declare things in C before you do anything, ie, at the very top of the function.

The compiler is also right, these instructions do nothing, are they supposed to do something?:

up->uid;
up->tg;

They're roughly equivalent to:

7;

I'm thinking maybe you're confused about what the -> does in C. All it does is get the value at an address.

Fix the warnings and see if the error persists, I don't think it will once you move the declaration to the proper place.

0
rossryanOP•

Modified it to:

static int sched_create_user(struct user_struct *up) { int rc = 0; struct task_group * group;

up->tg = sched_create_group();


if (IS_ERR(up->tg))
	rc = -ENOMEM;
// Patch

group = up->tg;
uid_t userid = up->uid; 
group->uid = userid; // line 170
// Modifications below made by Ryan Ross based off of Srivatsa Vaddagiri's earlier code.
list_add(&up->fair_sched_list, &user_list); // Adds the user to the list.
atomic_inc(&users); // Adds a user (increment). Presumably atomically.
assignusercputime(); // Divides up the CPU time equally among users.

return rc;

}

kernel/user.c: In function ‘sched_create_user’: kernel/user.c:169: warning: ISO C90 forbids mixed declarations and code kernel/user.c:170: error: dereferencing pointer to incomplete type make[1]: *** [kernel/user.o] Error 1 make: *** [kernel] Error 2

I'm at my wit's end. I modified the task_group struct to include uid as a member, and would think that up->group->uid = ip->uid. The error seems to imply an incomplete type, but a quick check on Google implies that it means any number of errors. Could sched_create_group() be returning something other than a task_group? Or is a uid_t somehow special in that it doesn't like to be get and set via normal methods?

1
HotRodLincoln•

This is another mixed declaration to move up:

uid_t userid = up->uid; 

Anything else could be doing anything...but I'd focus on getting the code you can see right, then branching out.

1
rossryanOP•

static int sched_create_user(struct user_struct *up) { int rc = 0; struct task_group * group; uid_t userid;

up->tg = sched_create_group();


if (IS_ERR(up->tg))
	rc = -ENOMEM;
// Patch

group = up->tg;
userid = up->uid; 
group->uid = userid; // line 171
// Modifications below made by Ryan Ross based off of Srivatsa Vaddagiri's earlier code.
list_add(&up->fair_sched_list, &user_list); // Adds the user to the list.
atomic_inc(&users); // Adds a user (increment). Presumably atomically.
assignusercputime(); // Divides up the CPU time equally among users.

return rc;

}

kernel/user.c: In function ‘sched_create_user’: kernel/user.c:171: error: dereferencing pointer to incomplete type make[1]: *** [kernel/user.o] Error 1 make: *** [kernel] Error 2

Why is this line not working? "group->uid = userid; // line 171"?

uid is a part of the task_group struct, right? I added uid to it earlier. Is it because it's a value type that is doesn't like it?

1
HotRodLincoln•

I'm not 100% sure, since I don't have kernel code to look at with me, but I don't think that uid_t is a pointer, so:

group->uid is equivalent to group.(*uid)

So, I think you may need to tone that down to a up.uid = userid;

1
m1ss1ontomars2k4•

You have to declare things in C before you do anything

If you're not going to specify a C standard, then I will specify one for you that makes you wrong. It is allowed in C99, and generally, GCC warnings about this in C90 mode are meaningless.

0
HotRodLincoln•

The reason we clear up all warnings especially when we didn't write the makefile ourselves is because Open Source authors frequently use the -Werror switch for gcc. The reason for this is to prevent the generation of tons of warnings simply because warnings aren't errors which turns every error into a WOT, 99% of which is useless.

0