.dp-highlighter { font-family: "Consolas", "Monaco", "Courier New", Courier, monospace; font-size: 12px; background-color: #E7E5DC; width: 99%; overflow: auto; margin: 18px 0 18px 0 !important; padding-top: 1px; /* adds a little border on top when controls are hidden */ } /* clear styles */ .dp-highlighter ol, .dp-highlighter ol li, .dp-highlighter ol li span { margin: 0; padding: 0; border: none; } .dp-highlighter a, .dp-highlighter a:hover { background: none; border: none; padding: 0; margin: 0; } .dp-highlighter .bar { padding-left: 45px; } .dp-highlighter.collapsed .bar, .dp-highlighter.nogutter .bar { padding-left: 0px; } .dp-highlighter ol { list-style: decimal; /* for ie */ background-color: #fff; margin: 0px 0px 1px 45px !important; /* 1px bottom margin seems to fix occasional Firefox scrolling */ padding: 0px; color: #5C5C5C; } .dp-highlighter.nogutter ol, .dp-highlighter.nogutter ol li { list-style: none !important; margin-left: 0px !important; } .dp-highlighter ol li, .dp-highlighter .columns div { list-style: decimal-leading-zero; /* better look for others, override cascade from OL */ list-style-position: outside !important; border-left: 3px solid #6CE26C; background-color: #F8F8F8; color: #5C5C5C; padding: 0 3px 0 10px !important; margin: 0 !important; line-height: 14px; } .dp-highlighter.nogutter ol li, .dp-highlighter.nogutter .columns div { border: 0; } .dp-highlighter .columns { background-color: #F8F8F8; color: gray; overflow: hidden; width: 100%; } .dp-highlighter .columns div { padding-bottom: 5px; } .dp-highlighter ol li.alt { background-color: #FFF; color: inherit; } .dp-highlighter ol li span { color: black; background-color: inherit; } /* Adjust some properties when collapsed */ .dp-highlighter.collapsed ol { margin: 0px; } .dp-highlighter.collapsed ol li { display: none; } /* Additional modifications when in print-view */ .dp-highlighter.printing { border: none; } .dp-highlighter.printing .tools { display: none !important; } .dp-highlighter.printing li { display: list-item !important; } /* Styles for the tools */ .dp-highlighter .tools { padding: 3px 8px 3px 10px; font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif; color: silver; background-color: #f8f8f8; padding-bottom: 10px; border-left: 3px solid #6CE26C; } .dp-highlighter.nogutter .tools { border-left: 0; } .dp-highlighter.collapsed .tools { border-bottom: 0; } .dp-highlighter .tools a { font-size: 9px; color: #a0a0a0; background-color: inherit; text-decoration: none; margin-right: 10px; } .dp-highlighter .tools a:hover { color: red; background-color: inherit; text-decoration: underline; } /* About dialog styles */ .dp-about { background-color: #fff; color: #333; margin: 0px; padding: 0px; } .dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; } .dp-about td { padding: 10px; vertical-align: top; } .dp-about .copy { border-bottom: 1px solid #ACA899; height: 95%; } .dp-about .title { color: red; background-color: inherit; font-weight: bold; } .dp-about .para { margin: 0 0 4px 0; } .dp-about .footer { background-color: #ECEADB; color: #333; border-top: 1px solid #fff; text-align: right; } .dp-about .close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; color: #333; width: 60px; height: 22px; } /* Language specific styles */ .dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; } .dp-highlighter .string { color: blue; background-color: inherit; } .dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; } .dp-highlighter .preprocessor { color: gray; background-color: inherit; }

Thursday, March 12, 2009

postmortem debugging (WinDbg)

We write high quality code, but a crash is always possible. So what do you do if it your program crashes? Simple, you analyze the crash dumps, find out where and why it is crashing and fix it. But, what if the crash is not repeatable? Be prepared. The best thing to do is to install a crash dump tool on the computer where the software is going to be run/tested.

When a program error occurs in Windows, the operating system searches for a program error handler to deal with the error. If the system does not find such a handler, the system verifies that the program is not currently being debugged, and if not, it considers the error to be unhandled. The system then processes unhandled errors by looking in registry for a program error debugger. An example error handler is dr watson.

To install Dr. Watson as your crash dump analysis tool, follow these simple instructions here

To install Debugging tools for windows as your crash dump tool, do the following:

  • Download debugging tools for windows from here
  • Install it into your folder of choice, example: C:\Program Files\Debugging Tools for Windows.
  • Register Debugging tools for windows as your default debugger, by running this command from the command prompt: "C:\Program Files\Debugging Tools for Windows\WinDbg" -i" You should see this message confirming that WinDbg is your postmortem debugger:


  • Run regedit (from start->run) and modify this key: HKLM\software\microsoft\windows nt\currentversion\aedebug. Change the value of the key Debugger (creating it if necessary) to the following:
  • "C:\Program Files\Debugging Tools for Windows\cdb.exe" -p %ld -c ".dump /ma /u C:\Dumps\Crash.dmp; q" -e %ld –g

Any dump files from any programs from now on, will be put in C:\dumps\ with a .dmp extension.

Now that you have the dump file, take the .exe and .pdb files of the crashing program, drop them in your code's output directory and double click on the .dmp file. Visual studio will open a dump project for you. Start debugging your program, and it will show you where it crashes. This assumes that you built your program with debug symbols and moderate optimization (or no optmization). If you don't know how to do that, well, ask Google.

Wednesday, March 11, 2009

Add code expiry for hacks in your projects

Sometimes we are under tight deadlines to finish things, and we are forced to put in some hacks and quick fixes int he code, hoping to fix them later and write them propertly. You can add \\todo comments, and other stuff to remind you, but there is nothing better than a compilation error after a certain date.

I found this bit of code online, and just modified it slightly. You can put a compilation timebomb in your code, and once a certain date passes, your code will no longer compile. You'll be reminded to fix what you wanted to fix.

An example is provided here:

#include <iostream>
#include <sstream>

void assert_fail(const char* expr, int line, char const* file, const char* function);
#ifdef WIN32
#define CUSTOM_ASSERT(x) do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __FUNCTION__); } while (false)
#else
#define CUSTOM_ASSERT(x) do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__); } while (false)
#endif //WIN32

/////////////////////////////
#define YEAR ((((__DATE__ [7] - '0') * 10 + (__DATE__ [8] - '0')) * 10 \
+ (__DATE__ [9] - '0')) * 10 + (__DATE__ [10] - '0'))

#define MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 1 : 6) \
: __DATE__ [2] == 'b' ? 2 \
: __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 3 : 4) \
: __DATE__ [2] == 'y' ? 5 \
: __DATE__ [2] == 'l' ? 7 \
: __DATE__ [2] == 'g' ? 8 \
: __DATE__ [2] == 'p' ? 9 \
: __DATE__ [2] == 't' ? 10 \
: __DATE__ [2] == 'v' ? 11 : 12)

#define DAY ((__DATE__ [4] == ' ' ? 0 : __DATE__ [4] - '0') * 10 \
+ (__DATE__ [5] - '0'))

#define DATE_AS_INT (((YEAR - 2000) * 12 + MONTH) * 31 + DAY)YEAR - 2000) * 12 + MONTH) * 31 + DAY)

#define UNIQUE_NAME( Y,M,D ) ReviewBefore##_##Y##_##M##_##D##_##line
#define REVIEW_DATE( YYYY, MM, DD ) (((YYYY - 2000) * 12 + MM) * 31 + DD)
#define COMPILE_DATE (((YEAR - 2000) * 12 + MONTH) * 31 + DAY)

#define REVIEW_BEFORE( YYYY, MM, DD ) \
static const struct UNIQUE_NAME(YYYY,MM,DD)##__LINE__ { UNIQUE_NAME(YYYY,MM,DD)##__LINE__() { \
assert( COMPILE_DATE < REVIEW_DATE(YYYY, MM, DD) ); \
} } UNIQUE_NAME(YYYY,MM,DD)##__LINE__

#define EXPIRED "This code has expired"
#define REVIEW_BEFORE_STMT( YYYY, MM, DD ) \
CUSTOM_ASSERT(COMPILE_DATE < REVIEW_DATE(YYYY, MM, DD) )

void assert_fail(const char* expr, int line, char const* file, const char* function)
{
std::cerr << "Code obselete" << std::endl;
std::ostringstream str;
str << "Expresion: " << expr << "\n"
<< "line: " << line << "\n"
<< "file: " << file << "\n"
<< "function: " << function << "\n";

std::cerr << str.str() << std::endl;
}

int main()
{
REVIEW_BEFORE_STMT(2000,1,1);
std::cout << COMPILE_DATE << std::endl;

return 0;
}

Wednesday, March 4, 2009

why use shared_from_this() ?

Why would you need to use shared_from_this on an object? As the name implies, if you want to pass a shared pointer to *this (pointer to current object), then you use shared_from_this.

What happens if you don't? Well, a scenario could happen where you wrap *this pointer in a smart pointer from a member function, expecting that to work just fine. But what happens when you do that is you create another shared_ptr to *this with reference count of 1. When this member function exits, the shared_ptr gets destroyed, and your *this pointer is deleted, causing the destructor of the object to be called.

An example will make this clearer:
#include <iostream>
#include <boost/shared_ptr.hpp>

class Bar;
void foo(const boost::shared_ptr<Bar>& ptr);

class Bar
{
public:
void process()
{
foo(boost::shared_ptr<Bar>(this));
}
void print() const {std::cout << "I am still alive!!" << std::endl; }

~Bar() { std::cout << "Uh oh... I am dead!!" << std::endl; }
};

void foo(const boost::shared_ptr<Bar>& ptr)
{
ptr->print();
}

int main()
{
boost::shared_ptr<Bar> sPtr(new Bar());
sPtr->process();
sPtr->print();
std::cout << "Just before leavnig main " << std::endl;
sPtr->print();
return 0;
}


When you run this code (fix any errors first), it'll crash. The reason being, when the function process exits, the temporary shared_ptr resets its refcount to 0, and the *this object gets deleted. Then when main tries to delete the object again upon exit, it crashes.

To fix this, we use shared_from_this(), which will simply make sure that we get a smart pointer *this instead of a raw pointer *this. Read more about it in the boost docs


#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

class Bar;
void foo(const boost::shared_ptr<Bar>& ptr);

class Bar : public boost::enable_shared_from_this<Bar>
{
public:
void process()
{
foo(shared_from_this());
}
void print() const {std::cout << "I am still alive!!" << std::endl; }

~Bar() { std::cout << "Uh oh... I am dead!!" << std::endl; }
};

void foo(const boost::shared_ptr<Bar>& ptr)
{
ptr->print();
}

int main()
{
boost::shared_ptr<Bar> sPtr(new Bar());
sPtr->process();
sPtr->print();
std::cout << "Just before leavnig main " << std::endl;
sPtr->print();
return 0;
}

Tuesday, February 10, 2009

boost multi-index container

I am usually lazy to write tutorial-like articles, or anything of benefit, but I try to put here just something plain, simple that might direct the reader, and myself as well, in the right direction.

If you've worked with data that needs to be sorted according to many criterias, then you have probably struggled with using multiple containers and multiple sorting functions/algorithms. Scenarios include displaying data sorted in different views, such as, files according to size, name, change date, etc.

Here is an example of the very powerful boost multi index container. As the name implies it enables you to have multiple indices into your container, which enables you to look at it anyway you desire.

Read more about it, and find more examples here



#include <string>
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>

using boost::multi_index::multi_index_container;
using boost::multi_index::ordered_non_unique;
using boost::multi_index::ordered_unique;
using boost::multi_index::indexed_by;
using boost::multi_index::member;

struct employee_entry
{
employee_entry( const std::string& first,
const std::string& last,
long id):
first_name_(first),
last_name_(last),
id_(id)
{}
std::string first_name_;
std::string last_name_;
long id_;
};


typedef multi_index_container<
employee_entry, indexed_by<
ordered_unique<member<employee_entry, std::string
, &employee_entry::first_name_> >
, ordered_non_unique<member<employee_entry, std::string
, &employee_entry::last_name_> >
, ordered_non_unique<member<employee_entry, long
, &employee_entry::id_> >
>
> employee_set;

//employee set.... multi-index
employee_set m_employees;


int main()
{
using boost::multi_index::nth_index;
using boost::multi_index::get;

typedef nth_index<employee_set, 0>::type first_name_view;
first_name_view& fnv = get<0>(m_employees);

fnv.insert(employee_entry("John", "Smith", 110));
fnv.insert(employee_entry("Fudge", "Hunk", 97));
fnv.insert(employee_entry("Tolem", "Bathi", 87));
fnv.insert(employee_entry("Anjal", "Sunfo", 75));
fnv.insert(employee_entry("Heidi", "Clark", 89));

///get employees sorted by id
typedef nth_index<employee_set, 2>::type id_view;
id_view& idv = get <2> (m_employees);
for(id_view::reverse_iterator it = idv.rbegin(), it_end(idv.rend()); it != it_end; ++it)
{
std::cout << it->first_name_ <<" "
<< it->last_name_ << ":"
<< it->id_ << std::endl;
}

const std::string str(40, '-');
std::cout << str << std::endl;

///get employees sorted by first name
typedef nth_index<employee_set, 0>::type fname_view;
fname_view& fdv = get <0> (m_employees);

for(fname_view::iterator it = fdv.begin(), it_end(fdv.end()); it != it_end; ++it)
{
std::cout << it->first_name_ <<" "
<< it->last_name_ << ":"
<< it->id_ << std::endl;
}

return 0;
}

Thursday, November 27, 2008

Grub error 22 nightmare

So two nights ago, while trying to free up some space on my windows partition, I just decided to remove the linux SUSE partition which I rarely use. So I launched up partition magic, and off I go. I deleted the Linux partition. When I started my machine again, the nightmare started...

Booting grub stage 1.5
Grub error 22

What happened is that grub is looking for linux startup files that are not there anymore. One way to resolve this is to startup your computer with a windows CD, go to the recovery console, and execute fixmbr, which should restore the original MBR, windows only. I have a Toshiba Sattelite A100 laptop which comes only with a recovery CD (no Windows CD), so I had no luck with that.

I had valuable data on my hard-drive and simply wiping it out was not an option. So I did some research online and finally resolved my problem using the following:

1- Install the Ultimate Boot CD (free from www.ultimatebootcd.com). Get the self-extracting EXE as it is smaller and installs faster
2- Extract the ultimate boot cd into an ISO image and use Nero or some other CD writing software to burn it onto a blank CD
3- Insert this blank CD into your computer and startup.
4- Click F-12 as your machine is starting up (or the equivalent on your machine) to go to the Boot Menue. Choose to boot from CD/DVD
5- Once in the command list of the UltimateBootCD (UBCD), choose filesystem tools.
6- Go down to the MBRtool and select it. You should see a screen like the following:


7- Choose Option 4: Work with a MBR ...
8- From the next screen select option 9 (write/refresh boot code). It will ask you what Hard disk you want to select, choose 0 (or whichever is right for you). It will ask you whether you want to work with it on a file/sector or original, select 0 for original. Or simply execute this command /RBC /DSK:0
9- This usually just takes a second. Once this is done, reboot your machine again and it should boot normally this time.

Tuesday, November 11, 2008

boost::any (2) - storing pointers in boost::any

We know that we can retrieve the value stored in a boost::any using one of the two overloaded boost::any_cast by either passing our any by reference or as a pointer. What if we store a pointer in boost::any?

The following example assumes the declaration from the previous boost::any(1) post:

int main()
{
typedef std::vector<boost::any> MixedContainer_t;
MixedContainer_t mixedContainer;

A* aPtr1 = new A(2);
A* aPtr2 = new A(3);

mixedContainer.push_back(aPtr1);
mixedContainer.push_back(aPtr2);

//would not work. What is stored at front() is a pointer to A
//and not an object of type A.
if(A* a = boost::any_cast<A> (&mixedContainer.front()))
a->print();

//we can even confirm it by testing the types
if(typeid(A*) == mixedContainer.back().type())
{
std::cout << "object at front() is a pointer to A" << std::endl;
}
//to get a pointer to it, we need to retrieve a A**, and pass
//the type of object we think stored at front as A*
if(A** a = boost::any_cast<A*> (&mixedContainer.front()))
{
std::cout << "pointer-> ";
(*a)->print();
}

}


Storing pointers in boost::any is problematic, because boost::any stores only a value of the pointer, and when the boost::any is destroyed, the only memory that is released is that occupied by the pointer, and not the memory it points to. That is, delete or delete[] is not called. What to do? Use smart pointers. As with standard containers, avoid using auto_ptr because of its 'weird' copy semantics.

#include <iostream>
#include <vector>
#include <boost/any.hpp>
#include <boost/shared_ptr.hpp>


class A
{
int value_;
public:
A(int value) : value_(value) {}
void print() const {std::cout << "A's value: " << value_ << std::endl;}
~A() {std::cout << "A(" << value_ <<") destructor" << std::endl; }
};

class B
{
int value_;
public:
B(int value) : value_(value) {}
void print() const {std::cout << "B's value: " << value_ << std::endl;}
~B() {std::cout << "B(" << value_ <<") destructor" << std::endl; }
};

int main()
{
typedef std::vector<boost::any> MixedContainer_t;
MixedContainer_t mixedContainer;

boost::shared_ptr<A> aPtr0(new A(1));
A* aPtr1 = new A(2);
A* aPtr2 = new A(3);

mixedContainer.push_back(aPtr0);
mixedContainer.push_back(aPtr1);
mixedContainer.push_back(aPtr2);

//and to retrieve the value from shared Ptr is simple
try
{
boost::shared_ptr<A> ptr = boost::any_cast<boost::shared_ptr<A> > (mixedContainer.front());
ptr->print();

}
catch(boost::bad_any_cast& bac)
{
bac.what();
}
//only the destructor of the A pointed to by shared_ptr is printed.
}

Sunday, November 9, 2008

boost::any (1)

Sometimes you might want to store unrelated types in the same container, and convey the data from one point to another without caring much about it's type. C++ containers are templated on the type and can only store objects of the same type in the same container. Traditionally, this problem has been solved by storing pointers to objects as void pointers, or using discriminated unions. The problem with these two approaches is that they lose type safety. You can access elements using the wrong type and causes disastrous results at run time with no errors from the compiler.

boost::any solves this problem. Internally boost::any uses a templates to create a wrapper class for the type you pass to it, and then create an instance of this class on the heap. It then manages retrieving the object inside using boost::any_cast safely.

Examples:

#include <boost/any.hpp>
#include <iostream>
#include <string>
#include <vector>

class A
{
int value_;
public:
A(int value) : value_(value) {}
void print() const {std::cout << "A's print: " << value_ << std::endl; }
};

class B
{
public:
void print() const {std::cout << "B's print" << std::endl; }
};

class C
{
public:
void print() const {std::cout << "C's print" << std::endl; }
};

int main()
{
typedef std::vector<boost::any> MixedContainer_t;
MixedContainer_t mixedContainer;

mixedContainer.push_back(A(1));

try
{
A a = boost::any_cast<A> (mixedContainer.back());
a.print();
}
catch(boost::bad_any_cast& bac)
{
bac.what();
}

//you can also retrieve the object via a pointer using the
//the overloaded boost::any_cast
if(A* a = boost::any_cast<A> (&mixedContainer.back()))
{
std::cout << "I can retrieve A by pointer" << std::endl;
}

boost::any a1 = mixedContainer.back();
if(typeid(A*) == a1.type())
std::cout << "last element is of A's type " << std::endl;


mixedContainer.push_back(B());
mixedContainer.push_back(C());

//push a string
std::string str("Hello World!");
mixedContainer.push_back(str);

void print_any(boost::any& element); //declaration
std::for_each(mixedContainer.begin(),
mixedContainer.end(),
print_any);
return 0;
}

void print_any(boost::any& element)
{
try
{
A a = boost::any_cast<A> (element);
a.print();
}
catch(boost::bad_any_cast& ex)
{
std::cout << "bad cast exception" << ex.what();
}
try
{
B b = boost::any_cast<B> (element);
b.print();
}
catch(boost::bad_any_cast& ex)
{
std::cout << "bad cast exception" << ex.what();
}
try
{
C c = boost::any_cast<C> (element);
c.print();
}
catch(boost::bad_any_cast& ex)
{
std::cout << "bad cast exception" << ex.what();
}
}




As you can see in the previous example, we can store any type in boost::any. Boost::any preserves the type and will not let you tamper with it without knowing the correct type. You can store pointers too, but retrieving pointers is a bit tricky and I'll discuss it in a later post. For now, we are interested in the two mechanism for retrieving the values stores in boost::any:

template<typename ValueType>
ValueType any_cast(const any & operand);

The argument is the boost::any we want to retrieve, and the ValueType is the type of the stored value. If the type does not correspond to what is stored in boost::any, then this version of any_cast will throw a bad_any_cast exception.

template<typename ValueType>
ValueType * any_cast(any * operand)


This overloaded any_cast takes a pointer to any, and returns a pointer to the stored value. If the type in the any isn 't Value_Type, a NULL is returned. There is also a version of this any_cast for const pointers.

Note the difference between the first mechanism where an exception is thrown, and the second where a null pointer is returned. Also note that we can use any of the overloaded any_cast exception to retrieve the value by either passing our argument by reference (to use the first mechanism) or value (to use the second) as we show in the preceding example:

    mixedContainer.push_back(A(1));

try
{
A a = boost::any_cast<A> (mixedContainer.back());
a.print();
}
catch(...)
{}

if(A* a = boost::any_cast<A> (&mixedContainer.back()))
{
std::cout << "I can retrieve A by pointer" << std::endl;
}



References:
- Introduction to Boost by Bjorn Karlsson
- the boost website