NULL pointer Exception

#include <stdio.h>

struct sss {

int a;

};

int main(void)

{

struct sss *ptr;

puts("Enter value for (*ptr).a :");

scanf("%d",&(*ptr).a);

printf("(*ptr).a holds value %d\n",(*ptr).a);

}

OUTPUT

Enter value for (*ptr).a :

4

(*ptr).a holds value 4

Interested to execute the above code and check the output, normally fresh guy will do that, there is a big bug there. And one more thing (*ptr).a = ptr -> a , you can substitute this and check once again.

At

struct sss *ptr; line I just declared a pointer of type(data type) struct sss, but then I had not assigned(pointed) it to any thing. So on executing above code will through the below error.

$ ./a.out 

enter value for ptr->a
2
Segmentation fault

“Segmentation fault” this error tells that it is a NULL pointer exception, a man master of manythings finds it easier. But a fresh guy it becomes a nightmare.

Solution to this

Make the pointer to point something

It can be done in two ways

1) Make the pointer to point the same type variable,

#include <stdio.h>

struct sss

{

int a;

};

int main(void)

{

struct sss *ptr, var;

ptr = &var;

puts("Enter value for ptr -> a :");

scanf("%d",&ptr -> a);

printf("ptr -> a holds value %d\n",ptr -> a);

}

Why can’t we test it with other types,

#include <stdio.h>

struct sss

{

int a;

};

int main(void)

{

struct sss *ptr;

char var; // you can check with int var; too

ptr = &var;

puts("Enter value for ptr -> a :");

scanf("%d",&ptr -> a);

printf("ptr -> a holds value %d\n",ptr -> a);

}

You will get the same output, but at compile time you can see this warning message.

warning: assignment from incompatible pointer type

2) Dynamically allocating memory and making pointer to point such memory.

#include <stdio.h>

struct sss

{

int a;

};

int main(void)

{

struct sss *ptr;

ptr = (struct sss *)malloc(sizeof(struct sss));

puts("Enter value for ptr -> a :");

scanf("%d",&ptr -> a);

printf("ptr -> a holds value %d\n",ptr -> a);

}

At

ptr = (struct sss *)malloc(sizeof(struct sss));

I am allocating memory dynamically and making my pointer to point the starting address of that memory.

Hence my code will run without bug.

Enjoy..!

Advertisements

ctags and cscope

Searching for particular functions, keywords, header files, etc etc over big source code directory is difficult task for any one. But in Linux everything is easier if you know some tricks. Since it is an open source, you will get many hands to save you for anything.

ctags and cscope are alternative options for linux cross reference (LXR) source code browser or indexer. These two works fine for anyone who doesn’t has internet access and challenges in perfomation with LXR. Let me give some sort of hints for using these effectively. But whatever I say here is not the complete detail of these. If you dig deep you will get more and more sort of useful informations about this.

ctags

1) Installation is so simple

$ sudo apt-get install exuberant-ctags

exuberant-ctags -> is the variant of ctags works as similar, it is mainly distributed along with vim at olden days.

2) To create tag(database) file or index file of source code

$ cd linux.x.xx.x/
$ ctags -R

whereas ‘R’ represents recursively.

3) You will get a file named tags inside the source directory

4) Content of tags shown inside vim editor

contentoftag

How to browse for a particular function,

5) Open any file using vim

f1

6) To find where printk has been defined press CTRL + ] by placing cursor over printk, it will drop you into that target file

f2

7) You can continue to navigate pressing CTRL + ] repeatedly

f3

8) Moral : ctags puts each entry into its stack when it reaches top it reports

On pressing one more time CTRL + ]

F4

9) To go one step back press CTRL + T

f3

10) When it reaches bottom of stack, again it reports

f5

Useful….!

11) What will happen on the absence of tags file inside the source directory…?

Pressing CTRL + ]

f7

I hope you may understand ctags, it is always a better practice to create tags file inside the source directory for Kernel Hackers to work.

cscope

1) Installation is so simple

$ sudo apt-get install cscope

2) To create tag(database) file or index file of source code

$ cd linux.x.xx.x/
$ cscope -R

whereas ‘R’ represents recursively.

3) You will get a binary file named cscope.out inside the source directory

4) Then, you will get a self explanatory interactive window to use, here I will share some examples, again I will repeat the words that on digging deep you will find more stuff

c2

5) To find different places where printk has been used

c3

on hitting enter

pho

Pressing corresponding number you may get into that file.

6) Another, to find global declaration of printk, type printk at option Find this global definition: 

pho1

7)  cscope is very well supported in vim, typing “:cs”

dd

cc

8) To exit press CTRL + D

Spend some time with cscope.

Enjoy….!

“extern” keyword in C – Analysis

You may encounter with “extern” keyword often. It becomes prefix of many variables / functions. Its hard to understand them, after a research I will share what I understand, correct me if I am wrong.

Declaration of variables or functions

Simply declaring a function does not allocate memory for them. After encountering with this lines compiler understands that definition of such variable/function resides somewhere in the memory and continues to execute next lines. Declaration shares idea of datatype of variable, function arguments order, and their datatypes to be passed, return type of function etc… to user.

Definition of variables or functions

Here comes allocation of memory for variables/functions. When we start defining(writing body of) a function corresponding memory for such is allocated inside systems memory, it is same for in case of variable too. This definition may be done at same file or some other file.

Analyze with example

->

int variable;

Here 4 bytes or 2 bytes of memory is allocated for variable.

int function(int a, int b)

{

return a+b;

}

extern keyword with functions

In case for functions,

int function1(void)

and

extern int function1(void);

both are same. Since extern keyword extends the visibility of function throughout the file and we can declare functions for N number of times in .c or .h files but definition will be done at only single file.

extern keyword with variables

For defining variable look above at ‘->’ line. But how will you declare a variable without defining it. Many of you may give wrong answer as

int variable;

but correct way is,

extern int variable;

Here I am declaring the variable as many times as I want.

Moral:

For functions extern is implicitly available at beginning, but this is not for the case of variables, we need to explicitly say it is an extern variable (declared but defined somewhere).

Confused…!

Look at this examples,

1)

#include <stdio.h>

int variable;

int main(void)

{

var = 10;

puts("Over....!");

}

Analysis: No problem here, you all know why it is…?!

2)

#include <stdio.h>

extern int var;

int main(void)

{

puts("Over...!");

}

Analysis: No problem here, since we declared var but not used it

3) 

# include <stdio.h>

extern int var;

int main(void)

{

var = 10;

puts("Problem...!");

}

Analysis: We declared “var” but not yet defined(any where) and trying to allocate some value for region that is not yet defined

4)

#include <stdio.h>

# include "audhil.h"

extern int var;

int main(void)

{

var = 22;

puts("No problem");

}

Analysis: I defined “var” inside my own header file audhil.h, hence declared and defined no problem.

Where as audhil.h holds

int var = 10;

5) 

# include <stdio.h>

extern int var = 99;

int main(void)

{

puts("No problem...!");

}

Analysis: No problem here, I normally declared and defined variable here…

Final thoughts

1. declaration of variable can be done many times but definition is only once allowed.

2. extern keyword extends visibility of variable/function.

3. Since functions are always visible inside file, hence extern keyword not required explicitly for function declarations.

4. extern keyword before variable says that, it is only declared but not yet defined.

5. as a special case, when an extern variable declared and initialized, it is known as definition of variable.

Enjoy…!

Basics of Building and Running Modules

When you start writing device driver you will definitely look into this book. I will share some of Kernel functions, Macros, Variables and /proc files needed for Kernel Module building and running.

insmod

User space utility that, inserts module into active Kernel.

modprobe

User space utility same as insmod but it extends its support by insmoding the dependent modules too, by referring at /lib/modules/…. directories.

rmmod

User space utility, to remove module from active Kernel without need of reboot.

#include <linux/init.h>

module_init(init_function);

module_exit(exit_function);

Macros for initialisation and cleanup functions along with respective header file.

__init / __exit

Markers for functions only used at module initialisation / cleanup time.

__initdata / __exitdata

Markers for datas

Items marked are only considered while initialisation / cleanup time, and discarded afterwards respectively. These may work due to placing relevant objects at special ELF section in the executable files.

#include <linux/sched.h>

Header file, contains most important kernel API, functions and variables.

Usage:

struct task_struct *current;

Denotes current process.

current->pid

current->comm

The process ID and command name of the current process.

obj-m

Makefile symbol, used by kernel build system to determine which module to be built inside the current directory.

i) /sys/module

ii) /proc/module

i) sysfs hierarchy which contains informations about currently loaded modules, contains module name, amount of memory occupied, and usage count. Extra strings appended at end of each line denotes flags currently available for the module.

ii) Older single file version of that, (my laptop doesn’t contain this file)

vermagic.o

It is an object file lies inside kernel source directory, describe the environment a module built for.

#include <linux/module.h>

Necessary for all kernel module source code.

#include <linux/version.h>

Holds information of kernel version being built.

EXPORT_SYMBOL(symbol);

EXPORT_SYMBOL_GPL(symbol);

Exports symbol to kernel, first uses with licensing issues, second, restrict itself for only GPL licensed modules.

MODULE_AUTHOR(“S MOHAMMED AUDHIL”);

MODULE_LICENSE(“GPL”);

MODULE_VERSION(version_string); 

MODULE_DEVICE_TABLE(table_info); 

MODULE_ALIAS(alternate_name);

Description to reader + place documentation on module in object file.

#include <linux/moduleparam.h>

module_param(variable,type,perm);

Macro for module parameter, along with respective header file. It can be modified by user during insmoding. Type can be bool, charp, int, invbool, long, short, ushort, uint, ulong, or intarray.

#include <linux/kernel.h>

int printk(const char * fmt, …);

Same as normal printf.

Enjoy…!