VALGRIND
============
We will use valgrind with following tools :-
> memcheck [default]
> callgrind
> cachegrind
> massif
> helgrind
valgrind --tool=memcheck [prog-name] [prog-argumements]
a simple example is valgrind --tool=memcheck ls -al
===================================================
nemesis@nemesis-laptop:~$ valgrind --tool=memcheck ls -al
==3497== Memcheck, a memory error detector
==3497== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3497== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==3497== Command: ls -al
==3497==
total 13300
==3497==
==3497== HEAP SUMMARY:
==3497== in use at exit: 14,671 bytes in 95 blocks
==3497== total heap usage: 1,902 allocs, 1,807 frees, 150,632 bytes allocated
==3497==
==3497== LEAK SUMMARY:
==3497== definitely lost: 200 bytes in 3 blocks
==3497== indirectly lost: 240 bytes in 20 blocks
==3497== possibly lost: 0 bytes in 0 blocks
==3497== still reachable: 14,231 bytes in 72 blocks
==3497== suppressed: 0 bytes in 0 blocks
==3497== Rerun with --leak-check=full to see details of leaked memory
==3497==
==3497== For counts of detected and suppressed errors, rerun with: -v
==3497== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 33 from 10)
===================================================
[NOTE]: In the above trace "3497" which precedes every line of Valgrind output is the pid of the program being run under valgrind i.e. ls -al in this case.
PRE-REQUISITES
==============
1. Strongly recommended to run the program with -g (with debug symbols) option. It is generally true of all profiling tools.
2. Use no optimization or as a compromise -0
Never be afraid to try something new. Remember, amateurs built the ark. Professionals built the Titanic
Thursday, March 11, 2010
Wednesday, March 10, 2010
Bitfields
-- Used for saving space
-- NOT portable across platforms
-- bitfield declaration cannot use const and volatile qualifiers
-- Max bit field length is 64 bits. Using more than 32 bits is likely to be non portable
-- CANNOT take the address of a bitfield
-- CANNOT have a pointer to a bitfield
-- CANNOT define an array of bitfields
-- A bitfield of size 0 will force alignment to the nearest word boundary [depends actually on compiler behaviour -- some compilers may pad to the size of the base type...some to the word boundary]
-- A structure containing bitfields is suitably/appropriately padded.
-- NOT portable across platforms
-- bitfield declaration cannot use const and volatile qualifiers
-- Max bit field length is 64 bits. Using more than 32 bits is likely to be non portable
-- CANNOT take the address of a bitfield
-- CANNOT have a pointer to a bitfield
-- CANNOT define an array of bitfields
-- A bitfield of size 0 will force alignment to the nearest word boundary [depends actually on compiler behaviour -- some compilers may pad to the size of the base type...some to the word boundary]
-- A structure containing bitfields is suitably/appropriately padded.
Tuesday, March 9, 2010
Cool Compile time check
If only we could evaluate a condition at compile time instead of link or run time. Well there is a way ...
Picked up this nifty trick from the linux kernel code.
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 *!!(condition)]))
Awesome piece of code ....It's a beauty...
Concept : Array of negative size is illegal. Remember array of size 0 is possible
Therefore if a condition evaluates to true we have :-
void(sizeof(NEGATIVE ARRAY) which would trigger a compile time error
If the condition is false, we have :-
void (sizeof(char[1 - 2 * !!(0))])
==> void(sizeof(char[1-2* !1])
====>void(sizeof(char[1-0])
======>void(sizeof(char[1])
========> void(const number) ====> This has no impact on C code although it is a valid expression.
you could have 1; anywhere in the code but to be "gcc warning free" it is better to have (void) 1 .
Here is a simple example, don't worry about the logic as I just needed a condition and do NOT mean to say that size of int should be smaller than that of a char :)
#define ADY_BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
int main(int argc, char *argv [])
{
/* will not compile */
ADY_BUILD_BUG_ON(sizeof(char) < sizeof(int));
}
and here is what we get :--
nemesis@nemesis-laptop:~/test_code$ gcc build_bug_on_example.c
build_bug_on_example.c: In function ‘main’:
build_bug_on_example.c:9: error: size of array ‘type name’ is negative
Picked up this nifty trick from the linux kernel code.
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 *!!(condition)]))
Awesome piece of code ....It's a beauty...
Concept : Array of negative size is illegal. Remember array of size 0 is possible
Therefore if a condition evaluates to true we have :-
void(sizeof(NEGATIVE ARRAY) which would trigger a compile time error
If the condition is false, we have :-
void (sizeof(char[1 - 2 * !!(0))])
==> void(sizeof(char[1-2* !1])
====>void(sizeof(char[1-0])
======>void(sizeof(char[1])
========> void(const number) ====> This has no impact on C code although it is a valid expression.
you could have 1; anywhere in the code but to be "gcc warning free" it is better to have (void) 1 .
Here is a simple example, don't worry about the logic as I just needed a condition and do NOT mean to say that size of int should be smaller than that of a char :)
#define ADY_BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
int main(int argc, char *argv [])
{
/* will not compile */
ADY_BUILD_BUG_ON(sizeof(char) < sizeof(int));
}
and here is what we get :--
nemesis@nemesis-laptop:~/test_code$ gcc build_bug_on_example.c
build_bug_on_example.c: In function ‘main’:
build_bug_on_example.c:9: error: size of array ‘type name’ is negative
Labels:
BUILD_BUG_ON,
cathing bugs at compile time
Mod Utils
Package name : module-init-tools
sudo apt-get install module-init-tools
Use :-
lsmod
modprobe
depmod
rmmod
Modprobe : Intelligent enough to figure out the dependencies.
[it is just a depmod -a combined with insmod of the necessary modules]
Default location of the modules :
/lib/modules/`uname -r`
Module dependency
File : /lib/modules/`uname -r`/modules.dep
e.g from the modules.dep file :-
-------------x--------------------------x---------------------------x--------------------------------
kernel/fs/freevxfs/freevxfs.ko:
kernel/fs/nfs/nfs.ko: kernel/fs/lockd/lockd.ko kernel/fs/nfs_common/nfs_acl.ko kernel/net/sunrpc/auth_gss/auth_rpcgss.ko kernel/net/sunrpc/sunrpc.ko
kernel/fs/exportfs/exportfs.ko:
kernel/fs/nfsd/nfsd.ko: kernel/fs/lockd/lockd.ko kernel/fs/nfs_common/nfs_acl.ko kernel/net/sunrpc/auth_gss/auth_rpcgss.ko kernel/net/sunrpc/sunrpc.ko kernel/fs/exportfs/exp
ortfs.ko
kernel/fs/lockd/lockd.ko: kernel/net/sunrpc/sunrpc.ko
sudo apt-get install module-init-tools
Use :-
lsmod
modprobe
depmod
rmmod
Modprobe : Intelligent enough to figure out the dependencies.
[it is just a depmod -a combined with insmod of the necessary modules]
Default location of the modules :
/lib/modules/`uname -r`
Module dependency
File : /lib/modules/`uname -r`/modules.dep
e.g from the modules.dep file :-
-------------x--------------------------x---------------------------x--------------------------------
kernel/fs/freevxfs/freevxfs.ko:
kernel/fs/nfs/nfs.ko: kernel/fs/lockd/lockd.ko kernel/fs/nfs_common/nfs_acl.ko kernel/net/sunrpc/auth_gss/auth_rpcgss.ko kernel/net/sunrpc/sunrpc.ko
kernel/fs/exportfs/exportfs.ko:
kernel/fs/nfsd/nfsd.ko: kernel/fs/lockd/lockd.ko kernel/fs/nfs_common/nfs_acl.ko kernel/net/sunrpc/auth_gss/auth_rpcgss.ko kernel/net/sunrpc/sunrpc.ko kernel/fs/exportfs/exp
ortfs.ko
kernel/fs/lockd/lockd.ko: kernel/net/sunrpc/sunrpc.ko
-------------x--------------------------x---------------------------x--------------------------------
Therefore, nfs.ko requires nfs_acl.ko to be already installed. This dependency is build by depmod -a
Monday, March 8, 2010
qsort: Using array
1. The realloc operation can be expensive if the the operation is carried out for a large number of times AND/OR if the memory is already fragmented.
2. A malloc operation could be considered but it would require a flag to indicate the first instance of executing the function
if ( FLAG == TRUE)
Memory already allocated. Don't allocate any memory
else { /* Flag = FALSE */
Allocate Memory
Set Flag = TRUE
}
--------------------------------------x------------------x-------------------x-----------------------------
#define ARRAY_SIZE 10
typedef struct adi_data_t_ {
unsigned int number;
} adi_data_t;
typedef struct adi_delete_list_t_ {
adi_data_t ** first;
unsigned int count;
} adi_delete_list_t;
int adi_compare_data (const void * a, const void *b)
{
const adi_data_t ** one = (const adi_data_t **) a;
const adi_data_t ** two = (const adi_data_t **) b;
printf("Number one : [%d] Number two : [%d] ret [%d]\n", (*one)->number, (*two)->number, (*one)->number - (*two)->number);
//return (*one)->number - (*two)->number ;
return (*two)->number - (*one)->number ;
}
int adi_delete_walker(adi_delete_list_t * delete, adi_data_t * data)
{
static adi_data_t* array[ARRAY_SIZE];
void *temp = NULL;
delete->first = array;
memcpy(&array[delete->count], &data, sizeof(adi_data_t *));
delete->count++;
}
int main (int argc, char* argv[])
{
adi_delete_list_t delete;
adi_data_t data_array[ARRAY_SIZE];
unsigned int i = 0;
memset(&delete, 0, sizeof(adi_delete_list_t));
/* Fill the array and pass it to the delete function */
for (i=0; i < ARRAY_SIZE ; i++) {
data_array[i].number = rand()/1000000;
printf(" Data Array filled with %d \n", data_array[i].number);
adi_delete_walker(&delete, &data_array[i]);
}
printf("qsort parameters: first [%p] count [%d]", delete.first, delete.count);
/* qsort the array */
qsort(delete.first, delete.count, sizeof(adi_data_t *), adi_compare_data);
for (i=0; i < ARRAY_SIZE ; i++) {
printf(" POST SORT: Data Array filled with %d \n", (*(delete.first)[i]).number);
}
}
2. A malloc operation could be considered but it would require a flag to indicate the first instance of executing the function
if ( FLAG == TRUE)
Memory already allocated. Don't allocate any memory
else { /* Flag = FALSE */
Allocate Memory
Set Flag = TRUE
}
--------------------------------------x------------------x-------------------x-----------------------------
#define ARRAY_SIZE 10
typedef struct adi_data_t_ {
unsigned int number;
} adi_data_t;
typedef struct adi_delete_list_t_ {
adi_data_t ** first;
unsigned int count;
} adi_delete_list_t;
int adi_compare_data (const void * a, const void *b)
{
const adi_data_t ** one = (const adi_data_t **) a;
const adi_data_t ** two = (const adi_data_t **) b;
printf("Number one : [%d] Number two : [%d] ret [%d]\n", (*one)->number, (*two)->number, (*one)->number - (*two)->number);
//return (*one)->number - (*two)->number ;
return (*two)->number - (*one)->number ;
}
int adi_delete_walker(adi_delete_list_t * delete, adi_data_t * data)
{
static adi_data_t* array[ARRAY_SIZE];
void *temp = NULL;
delete->first = array;
memcpy(&array[delete->count], &data, sizeof(adi_data_t *));
delete->count++;
}
int main (int argc, char* argv[])
{
adi_delete_list_t delete;
adi_data_t data_array[ARRAY_SIZE];
unsigned int i = 0;
memset(&delete, 0, sizeof(adi_delete_list_t));
/* Fill the array and pass it to the delete function */
for (i=0; i < ARRAY_SIZE ; i++) {
data_array[i].number = rand()/1000000;
printf(" Data Array filled with %d \n", data_array[i].number);
adi_delete_walker(&delete, &data_array[i]);
}
printf("qsort parameters: first [%p] count [%d]", delete.first, delete.count);
/* qsort the array */
qsort(delete.first, delete.count, sizeof(adi_data_t *), adi_compare_data);
for (i=0; i < ARRAY_SIZE ; i++) {
printf(" POST SORT: Data Array filled with %d \n", (*(delete.first)[i]).number);
}
}
Subscribe to:
Posts (Atom)