Friday, November 16, 2012

Checking for NULL : Early returns or enclosing blocks?

Checking for NULL is a daily chore for every true to his salt programmer. We have come long way in programming languages and their implementations, however, this coder nemesis continues to flourish.
Now that we have ascertained the futility of thinking of doing away with the NULL check, lets try to make the best of it. What do you think is a better way of checking for NULL?

Approach #1

 if(pPointer == NULL)
    return; //possibly with error


Approach #2:

if(pPointer != NULL)
{
        ......
}


You could generalize this for any kind of error checking. The reason this post came up is because I have recently had a slight change of heart as to which is the better approach.

Disclaimer : I realize there is nothing that is "one-size-fits-all" in programming. There might be special situations when one is certainly better than the other. Let this be a very general case.

Saturday, March 06, 2010

Modifying class VTABLE at runtime

First of all, I am very grateful to Jaydeep Bhalerao and Vijay Balani for sharing
such cool stuff with me. Thanks a lot guys.

Disclaimer : This code is meant for experimental purposes only. Use it at your own risk.
I am not responsible for any consequences (good or bad)that may result due
the use of the code given herein.

The compiler generates a separate VTABLE for each class that either
defines its own virtual methods or inherits virtual methods from
another class or both. The VTABLE is used by the runtime environment
to dispatch virtual method calls at runtime. Another thing to note is
that the VTABLE is shared by ALL the objects of a class.

I wont go into the details of VTABLES here, for a more in-depth
discussion of VTABLES and their implementation use Wikipedia
entry for "VTABLE".

Here's another link : http://www.relisoft.com/book/lang/poly/2implem.html


Now here, I am going present some (very platform dependent) code
that changes the contents of a class' virtual table at runtime.

This works ONLY on Windows.

We start with a class that defines some virtual methods, as follows,

class Base
{

public:
virtual void fun1(){cout<<"\nfun1";}
virtual void fun2(){cout<<"\nfun2";}

};

Next up we shall define global function that shall later find a place in the Base class VTABLE,

static void fun3()
{

printf("\nThis is the modified virtual function");

}


Now that we have these two things in place. In the main function we need a Base object

Base* ptr = new Base;

Calling these virtual functions gives expected results,

ptr->fun1();
ptr->fun2();

Now comes the ugly part. We use the Win32 VirtualQuery function to retrieve information about the range of pages in the virtual address space of the calling process used by the VTABLE. The VirtualQuery function requires a pointer to a struct of type MEMORY_BASIC_INFORMATION to fill information about the pages.

LPDWORD* lpVtabl = (LPDWORD*)ptr;
lpVtabl = (LPDWORD*)*lpVtabl ;
MEMORY_BASIC_INFORMATION mbi1;

if(VirtualQuery( (LPVOID)(lpVtabl), &mbi1,
sizeof(mbi1)) != sizeof(mbi1))

return -1;


Now get the base address of the VTABLE,

PVOID pvRgnBaseAddress1 = mbi1.BaseAddress;

Normally, the protion of the virtual address space where the VTABLE resides is write protected, if we have to modify the VTABLE we must subvert this protection mechanism. The Win32 VirtualProtect function allows you change the read-write access permissions of a range of pages. We pass it the base address of the VTABLE and the flag PAGE_EXECUTE_READWRITE to make it writable.

if(FALSE == ::VirtualProtect( pvRgnBaseAddress1, 4,
PAGE_EXECUTE_READWRITE, &dwOldProtect11))
return -1;

Now the code that follows changes the VTABLE contents, substituting address of function "fun3" in place of a virtual member function,

DWORD dw = reinterpret_cast(fun3);
memcpy((LPVOID)(lpVtabl + 0), (LPVOID)(lpVtabl + 1), 4);
memcpy((LPVOID)(lpVtabl + 1), (LPVOID)&dw, 4);

Voila, there you go. Now try calling the virtual methods,

ptr->fun1();
ptr->fun2();

The output is as follows,

fun2
This is the modified virtual function

If anybody wants the full code, leave your email address in the comment, I will mail it to you.

Saturday, November 10, 2007

Using the GNU Debugger

The GNU debugger(gdb) comes standard with any Linux installation(Okay maybe not, but its can be selected during installation).Also, it comes with the Bloodshed Dev-CPP C/CPP IDE for Windows. Its a very useful but often overlooked tool for C/CPP development.Most programmers resort to multiple printfs at various points in the code to trace out the error. This approach seems paleolithic when you see the advantages offered by gdb.
For one thing, the printfs make the code messy.Secondly, debugging is a very painstaking process when using printfs.This comes from personal experience of course.
Also after you are done debugging,you have to cleanup those print statements.
These are just a few reasons.Start using gdb and more will become obvious to you.

Thats why I emphasize the use of gdb.

Now a lot of people have come to me asking me the procedure for using gdb. I guess from now on I can just throw the blog at them

Lets look at the steps involved.
(For Linux only, Bloodshed offers a GUI interface,which is pretty straight forward.If you still want a tute.Leave a comment)

1.Compile with symbol table information

You can use either "cc" or "g++" depending on your language of choice.For the sake of simplicity,we will assume cc for the duration of this discussion.Similar arguments apply to g++.
When compiling use the "-g" option/flag.This allows your program to be debugged by gdb.

Basically, this tells the compiler to store symbol table information (source level symbols) in your
object file or load module.

For example,suppose we are trying to a compile are C source file dfs_ops.c. This file is standalone and does not link with any other object files other than the standard C library.
The Command to execute is

:> cc dfs_ops.c -g -o dfs_ops

This will tell the compiler to compile dfs_ops.c into an executable file dfs_ops and also store the symbol table information in the file.
As is obvious, storing the symbol table in your executable increases its physical size. So make sure you dont do this in your final deliverable.(Which will hopefully be thoroughly tested. :-))

2. Start a debugging session for your program with gdb

Next, you need to enter into a session with gdb, to interactively debug your program with gdb.
This means the program must be started under control of gdb.
To do this you can do either of the following in a shell...

i) :> gdb
In this approach , you start gdb but do not specify any program to debug.In this case you must run a program expicitly from the gdb prompt to start a debugging session.
This can be done as follows.
gdb:> run <program_name>

Here is the name of a program that you want to debug.This could be a full path or just the program name in the current directory.

ii) :> gdb <program_name>

In this approach, you explicitly specify the program which you want to debug.

After you have entered in a session with gdb, you should see a gdb prompt. Similar to this..

gdb:>

3.Setting a breakpoint

Now that you have entered in a session with gdb, using either of the two approaches in step 2, you must set an execution break point.This is a point in the program where the gdb will pause execution and give control to you.You can then perform various actions like looking at variable values,register values, funtion returns,step wise execution etc.
To set a break point, use the "break" command at the gdb prompt.
You can set a break point either by specifying a line number or function name.

gdb:> break <line_num>
gdb:> break <func_name>

Note: Pressing TAB here, will list available functions and class methods

For example :

gdb:> break 80 // Pauses execution at Line 80 w.r.t to the Source file line numbers
gdb:> break main //pause execution when program control enters function main

You can specify multiple break points

More to come...just wait....

Saturday, November 03, 2007

Linux File System Development using FUSE

FUSE (Filesystems in User Space) is an open source project that allows developers to create file systems as user application as against a kernel module (which is the normal case). It is obvious to developers familiar with FS development to notice that ,a filesystem in userspace would mean a significant performance penalty. Certainly there is a performance hit because the filesystem application communicates with the FUSE module which in turn handles VFS communication introducing an extra level of indirection.

So why bother?

FUSE is certainly worth the performance trade-off for a number of reasons :

1.FUSE offers a higher level interface which much simpler than the VFS interface.This forms an excellent starting point for budding file system developers to get the hang of things.
2.FUSE also offers a lower layer interface which is akin to the VFS interface.This allows developers familiar with VFS to test out their File system code in user space before introducing it as a kernel module.Those who know about kernel panics and constant reboots and kernel re-compilation that are part of Linux kernel development will know why this convenience is of such great value.
3.For some file systems where performance is not an issue, developing file systems is not only easier but also a much faster process, because the now the developers have a the whole C library at their disposal which will be linked to their file system application.Means lots of utility functions.

Although, the documentation and tutorials for FUSE are few and far between.And whatever there are, are not easily accessible.So I will try to include a tutorial for FUSE on my blog some time later.No promises..

Monday, December 25, 2006

YUMmy!!!

The New Fedora Core distro is out viz.Fedora Core 6.Like it the earlier versions it still sucks as far as features are concerned,especially media players.
Fortunately it comes with a very handy tool for installing RPMs from an online repositories.Its called
'yum' (Yellow Dog Updater,Modified).Using 'yum', installing RPMs is a breeze.

Here's something to get you started with 'yum' :
1.Before you can install from online repositories ,add support for them on your system .Do the following in your terminal ,in the super user mode of course ,

# rpm -ihv http://ayo.freshrpms.net/fedora/linux/6/i386/RPMS.freshrpms/freshrpms-release-1.1-1.fc.noarch.rpm
32 bit version:
# rpm -ihv http://rpm.livna.org/fedora/6/i386/livna-release-6-1.noarch.rpm
64 bit version:
# rpm -ihv http://rpm.livna.org/fedora/6/x86_64/livna-release-6-1.noarch.rpm
You can browse the packages available there at http://rpm.livna.org/fedora/6/i386/ and http://zod.freshrpms.net/.

2.Now you can use yum in the following manner to install new packages ,
#yum install package_name1[package_name2][package_name3].....[package_nameN]

You can use the '-y' if you dont wanna answer y/n questions

3.You can also use yum to update existing packages,

#yum update package_name1[package_name2][package_name3]...[package_nameN]
If no package name is specified yum will update all installed packages

4.Similarly the command to remove packages is
#yum remove package_name1[package_name2][package_name3]....[package_nameN]
"erase" can also be used instead of "remove".
Apart from this are a lot of options for searching packages ,group install etc.Go check out the man page.

One of the bugs that I had with the yum version that ships with FC6 occurs when an instance of yum terminates improperly, giving the following error everytime "yum" is run,
Existing lock /var/run/yum.pid: another copy is running. Aborting.

To avoid this please update to the latest version of yum before using it..i.e
#yum update yum

Friday, December 15, 2006

This is the summary of speech Given by Alex Stepenov (The man behind STL ; Principal Scientist, Adobe Systems) at Adobe India on 30 Nov 2004. It's really a great speech. I think every programmer should read it.

1. Study , Study and Study

- Never ever think that you have acquired all or most of the knowledge which exists in the world. Almost everybody in US at age of 14 and everybody in India at age of 24 starts thinking that he has acquired all the wisdom and knowledge that he needs. This should be strictly avoided.

- You should be habituated to studies...exactly in the same way as you are habituated to brushing teeth and taking bath every morning. The habit of study must become a ‘part of your blood’. And the study should be from both the areas: CS, since it is your profession, and something from non-CS...Something which doesnot relate to your work. This would expand your knowledge in other field too. A regular study, everyday, is extremely essential. It doesnot matter whether you study of 20 minutes of 2 hours, but consistency is a must.

- You should always study basics and fundamentals. There is no point in going for advanced topics. When I was at the age of 24, I wanted to do PhD in program verification, though I was not able to understand anything from that. The basic reason was that my fundamental concepts were not clear. Studying ‘Algebraic Geometry’ is useless if you donot understand basics in Algebra and Geometry. Also, you should always go back and re-read and re-iterate over the fundamental concepts. What is the exact definition of ‘fundamental’? The stuff which is around for a while and which forms basic part of the concepts can be regarded as more fundamental. Of course, everybody understands what a fundamental means.

- Here are few books which I would strongly recommend that every CS professional should read and understand.

i. “Structure and Interpretation of Computer Programs” by Albenson and Sussman I personally donot like the material present in this book and I do have some objections about it but this is the best book I have ever seen which explains all the concepts in programming in a clear and excellent way. This book is available online at http://mitpress.mit.edu/sicp/

ii. Introduction to Computer Architecture: by Hennessy and Patterson. How many of you have shipped the programs by writing them in assembly? A very good understanding of basics of how a computer operates is what every CS professional must have. H&P Wrote two books on CA. I am talking about their first book, the introductory text for understanding basic aspects of how a computer works. Even if you feel that you know whatever is written in that book, donot stop reading. It’s good to revise basics again and again.

iii. “Fundamentals of Programming” by Donald Knuth. The core of CS is algorithms and Data structures. Every CS professional must have the 3 volumes of Knuth’s Book on programming. It really doesnot matter if you take 30 years of your life to understand what Knuth has written, what is more important is that you read atleast some part of that book everyday without fail. iv. Introduction to Algorithms by Cormen, Leiserson and Rivest This book should be read daily to keep your concepts fresh. This is the best book for fundamental concepts in algorithms.

2. Learn Professional Ethics

- As a CS Professional, you are morally obliged to do a good job. What this means is that you are supposed to do your job not for your manager but for yourself. This is already told in Bhagwatgeeta : Doing duties of your life.

- The direct implication of this is: never ever write a bad code. You don’t need to be fastest and run after shipping dates; rather you need to write quality code. Never write junk code. Rewrite it till it is good. Thoroughly test every piece of code that you write. Do not write codes which are “sort of alright”. You might not achieve perfection, but atleast your code should be of good quality.

- Let me quote my own example in this context. You might have heard about STL, The Standard Template Library that ships in with C++ compilers. I wrote it 10 years ago, in 1994. While implementing one of the routines in the STL, namely the “search routine”, I was a bit lazy and instead of writing a good linear order implementation of KMP which was
difficult to code, I wrote a best quadratic implementation. I knew that I could make the search faster by writing a linear-order implementation, but I was lazy and I did not do that. And, after 10 years of my writing STL, exactly the same implementation is still used inside STL and STL ships with an inefficient quadratic implementation of search routine even today!! You might ask me: why can’t you rewrite that? Well...I cannot, because that code is no more my property!! Further, nobody today will be interested in a standalone efficient STL ...people would prefer one which automatically ships out with the compiler itself.

- Moral is, you should have aesthetic beauty built inside you. You should “feel” uneasy on writing bad code and should be eager to rewrite the code till it becomes upto the quality. And to the judge the quality, you need to develop sense regarding which algorithms to use under what circumstances.

3. Figure out your Goals

- Always aspire doing bigger things in life

- “Viewing promotion path as your career” is a completely wrong goal. If you are really interested in studying and learning new things, never ever aspire for being a manager. Managers cannot learn and study...they have no time. “Company ladder aspiration” is not what should be important for you.

- You might feel that you want to do certain things which you cannot do till you become a manager. When you become a manager, you will soon realize that now you just cannot do anything!

- You will have a great experience as programmers. But if you care for people and love people, you will never enjoy being a manager...most good managers are reluctant managers. If you see people as people, you cannot survive at management level.

- Always aspire for professional greatness. Our profession is very beautiful because we create abstract models and implement them in reality. There is a big fun in doing that. We have a profession which allows us to do creative things and even gives nice salary for that.

- The three biggest mistakes that people usually make are aiming for money, aiming for promotion and aiming for fame. The moment you get some of these, you aspire for some more...and then there is no end. I donot mean that you shouldnot earn money, but you should understand how much money would satisfy your needs. Bill Clinton might be the richest person in the world; he is certainly not the happiest. Our lives are far better than his.

- Find your goal, and do best in the job that you have. Understand that what is in your pocket doesnot matter...what is in your brain finally matters. Money and fame donot matter. Knowledge matters.

4. Follow your culture

I have seen the tradition that whatever junk is created in US, it rapidly spreads up in the rest of the world, and India is not an exception for this. This cultural change creates a very strong impact on everybody’s life. Habits of watching spicy Bollywood or Hollywood movies and listening to pop songs and all such stupid stuff gets very easily cultivated in people of your age...but believe me, there is nothing great in that. This all just makes you run away from your culture. And there is no wisdom in running away from your culture. Indian culture, which has great Vedas and stories like Mahabharata and Bhagwatgeeta is really great and even Donald Knuth enjoys reading that. You should understand that fundamental things in Indian culture teach you a lot and you should never forget them. Finally, I would like to conclude by saying that it’s your life...donot waste it on stupid things...develop your tests, and start the fight.

Sunday, August 20, 2006

Juxta it is then!

Yes.I have finally zeroed in on my first sem project.Its actually an application that implements the JXTA P2P protocol.Looks exciting.Time will tell....