Over the years, I have written quite a bit of code. Not mind boggling or anything, but a bit more than most other people I reckon. And looking back at it all, I’ve written some truly crappy stuff. I laugh at it, because I like to think I “know” stuff now. But today I was brought crashing down to earth.
Here is what I wrote:
/*….some code that initialised stuff…*/
Major=register_chrdev(253,”abc” , &fops);
if(Major < 0)
{
printk(“Registering failed !!\n”);
return Major;
}
printk(“Reading cruel world!!\n”);
return 0;
handle_list_head = (struct alloc_handle_list *)kmalloc (sizeof(struct alloc_handle_list), GFP_KERNEL);
if(handle_list_head==NULL)
{
printk(“Unable to allocate head”);
return 1;
}
INIT_LIST_HEAD(&handle_list_head->ptr);
if(handle_list_head->ptr.prev==NULL || handle_list_head->ptr.next==NULL)
/*….other init code… initialisation module ends…*/
/*…………………………………………….*//*……some other function….*/
list_for_each_safe(temp_list, temp_for_temp_list, &handle_list_head->ptr)
{
fun = list_entry(temp_list, struct alloc_handle_list, ptr);
if(fun->handle != handle) continue;
co_passage_page_assert_valid();
co_passage_page_acquire(&flags);
co_passage_page->operation=CO_OPERATION_UNREGISTER_HANDLE;
co_passage_page->params[0]=fun->handle;
co_switch_wrapper();
if(co_passage_page->params[0]==0)
{
co_passage_page_release(flags);
printk(“Did not unreg Handle (no such handle)!!\n”);
return -1;
}
co_passage_page_release(flags);
/*……….and some more…..*/
It isn’t important to know what this does, only that we were at a crucial point in the general proceedings. See if you can locate the flaw. It took poor Jitesh 4 hours to debug this little baby. Every time we executed the code, it would give us a Segmentation Fault. The kernel stack dump would tell us that the module was “Unable to deference pointer to kernel memory at virtual address…”.
We went through every detail of the pointer manipulation. We resorted to commenting the code line by line to figure out the offending snippet. Finally, unable to take it anymore, I called it a day and headed home. Jitesh, being the stubborn kind, struggled on. When he found the error, he called me up to dish out a few choice words and home truths. Here it is…
/*…in the initialisation function…*/
if(Major < 0)
{
printk(“Registering failed !!\n”);
return Major;
}
printk(“Reading cruel world!!\n”);
return 0;
handle_list_head = (struct alloc_handle_list *)kmalloc (sizeof(struct alloc_handle_list), GFP_KERNEL);
/*…continues…*/
As you can see, the head of our list structure was NEVER BEING INITIALIZED!!! This, my friends, is the absolute worst bit of code I have ever typed. And my punishment for doing this is to write truthfully about it in this post! Hopefully, this will remain the worst bit of code I ever write, and I won’t have to write another post like this ever!