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
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?:
They're roughly equivalent to:
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.
Modified it to:
static int sched_create_user(struct user_struct *up) { int rc = 0; struct task_group * group;
}
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?
This is another mixed declaration to move up:
Anything else could be doing anything...but I'd focus on getting the code you can see right, then branching out.
static int sched_create_user(struct user_struct *up) { int rc = 0; struct task_group * group; uid_t userid;
}
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?
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->uidis equivalent togroup.(*uid)So, I think you may need to tone that down to aup.uid = userid;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.
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.