Archive

Archive for the ‘Things You Shouldn't do’ Category

Cascade errors can happen on forcefully closing handles

March 21st, 2009 Sarath Comments

In his recent Windows Confidential article Win32 and Shell Guru Raymond Chen talking about the caveats of forcefully closing the handles.

In many situations as a windows user  you will definitely faced “File is being used by another process” error when you try to delete or access a file. As a solution for our impatience or to kill the dominance of other process you may forcefully close the file handles. Here are many utilities to close the files being used by foreign application. Tools like Process Explorer allows users to forcefully close any handles opened by any process in the system.

The issues are many

If the the handle is closed earlier by another application, when the original owner will get invalid handle error when it tries to close the corresponding handle.

The invalid handle error may come again if the application uses the handle again. Things may even worse, if the handle value is reused by operating system when the user tries to open another files. As far as the application concerned it got a valid handle value and it’s supposed to point the first file it has opened, in fact the first handle pointer actually points to second file. This may lead data corruption by writing the data intended for the first file is actually written to another file.

Now first and second file handles are actually pointing to the second file and as per the programming logic, if the first file handle is closed, it’s actually closing the second file and you’ve created the same situation which happened to the file earlier. The second file handle got invalid and this can lead to cascaded error.

In the above condition , the error happened when you opened a new file, but what’ if a it’s another kernel object like a mutex, by closing the handle, the mutex handle become invalid and by losing the synchronization, it may lead again for data corruption.

He also explain data corruption issues with search index when forcefully closing handles. Please see the original technet article to know issues with force-handle-close.

Your program really works fine on first run?

August 28th, 2007 Sarath Comments

Earlier in my career, I just write the program and fix the bugs by debugging it. anyway gradually I’ve corrected that bad habit but still I consider the first run of my programs as an adventurous task. IMO the code level issues and logical issues should be with your logic and static debugging skills. It will increase your potential and capability to write code. You will feel really great when you are working in an environment where you can’t do debugging. The best examples are the embedded devices, medical equipments like like Ultra Sound machines. Under such environment logs, trace are our debuggers.

What I found that most of the people investing maximum 4-5 years in coding after that, they will move to the next level like technical lead and module leaders, even they can be a PL of a project. At that point, your coding era will come to an end. Yea! In my opinion, coding is the most easiest, interesting, presentable task. It increase your skills and logical capabilities. So try to get the best soft-skills in that area.

The issues may take just a minute to fix, code level modification may be minor but considering the other facts to ensure that the bug is really fixed, the cost is really high. Especially if you are working for a medium sized project (10K – 100K code size) the cost is really high. You may required to spend time on compilation, booting time and start up the device or platform you are working(if required), passing information about the modification to your team etc are the major task for a simple modification. What if you need to update it twice or thrice? When you are implementing a requirement, make sure that you are confirmd every aspect from your senior member or concerned person else you may need to change your entire code. Once I saw an interesting forward that describing the designer, analyst,programmer, business executive etc… point of view and final product. Make sure that it’s not like that.

So try hard, to make your program working on first run. ( If you feels it is hard, just try towards that area, it will never decrease your potential, but you will get really improved)

Release your DCs and take care while using Wrapper (RAII) classes

April 13th, 2007 Sarath Comments

Today I was wondering the application I was working with constantly increments the GDI count. I could not identified the problem on first look because the application was hard to debug because of it’s size and use of third party release version of libraries. Anyway I tracked it down there had a small window which has some number of buttons. This window is a constantly updating one that’s why it has a lot of painting operations. To avoid the flickering, we were using a memory DC class. But the memory DC class was properly releasing all the GDI objects it possessing.  Still where’s the problem. I just cracked down the problem. The buggy code was something as follows.

// You please assume that this is the implemented ctor

CMemDC dc(GetDC(), ClientRect);

The above was the buggy code. As the documentation of GetDC says, you should release it on completion as GetDC adds a GDI handle to the application.

What’s the alternative solution?

You can use CClientDC. It’s derived from CDCpublically hence you will be able to access the all the public operations of CDC. It act as a common RAII (Resource Acquisition Is Initialization)class. where it’s locking the resource in the constructor and unlocks in the destructor. CClientDC class calls GetDC call of the passing window handle(pointer) and calls the same window’s ReleaseDC call of the same window on destruction. So that you can work without worrying about calling GetDC() and ReleaseDC() functions of the window.

You can rewrite the code as follows

CClientDC dc(this); // pass window class’s this pointer

CMemDC dc(&dc, ClientRect);

OK just wait a minute earlier I had made a call like this CMemDC(GetDC(),ClientRect); so sometime you may have a tendency to write something like this CMemDC dc(&CClientDC(this),rect); It too should work fine no? No never! Go back to C++ school again the CClientDC object creating inside the function destructs when the function call completes so the CClientDC’s destructor will free the DC object acquired in it’s construction. Also if the constructor throws some exception, it is not sure that the object destructs properly. It may skip the hidden destructor call written by compiler and will go the catch block or some other handlers. Same case is also applicable while using any RAII classes. Initialize the objects outside the function calls and pass the object for safety.

You may do some further drawing calls with the memory DC object but finally it will end up in a crash (normal while destructing the mem dc object).

// The errorneous code as follows

CMyDialog::OnPaint()
{
    CMemDC MemDC(&CClientDC(this),rect); // ERROR dont do like this.
    … // Your drawing calls goes here
}

// Correct code

CMyDialog::OnPaint()
{
    CClientDC dc(this);
    CMemDC MemDC(&dc,rect); // Correct dont do like this
    // Also the destructors will be called in the opposite way they constructed.
    // So there will not be any problems
    … // Your drawing calls goes here
} // dtors will be called here

Ok here’s the code of a simple MemDC class. Hope this very simple without any GDI any leaks. But still this is not full fledged one. You can go to codeproject or codeguru to get some well implemented advanced memory DC classes.

class CMemDC : public CDC
{
    CBitmap m_Bitmap;
    CRect m_Rect;
    CDC* m_pDC;
public:

    /* Stores the dc to blit to screen, store the rectangle area for size */
    CMemDC(CDC* pDC, CRect rect) : m_pDC(pDC), m_Rect(rect)
    {
        CreateCompatibleDC(pDC); // Create DC for off-screen drawing
        // Further drawing will be happened in bitmap instead of screen
        m_Bitmap.CreateCompatibleBitmap( pDC, rect.Width(),rect.Height());
    }
    ~CMemDC()
    {
        // Finally blt to screen
        m_pDC->BitBlt( 0, 0, m_Rect.Width(), m_Rect.Height(), this, 0,0,SRCCOPY);
    }
};

I conclude as follows

1. If you have called GetDC(), it should be released properly

2. Don’t construct RAII objects within function calls because it will be destroyed after function calls. Also if some exception occured, it will not be release properly.

Categories: C++, Code, Things You Shouldn't do, Tips Tags:

How are you doing? Nothing… things are going as usual :(

March 26th, 2007 Sarath Comments

Yesterday I had a voice chat with my roommate John, who’s currently working at Belgium as part of his onsite assignment. He started the conversation by asking me “How are you doing and what are the updates from your side?” I started with “Hey John I’m doing fine here. Things are going as usual…” actually it was a start from my side to give updates from my side. Suddenly John replied me back “Never say like this to someone, especially those whom know you that “Nothing special from my side and things are going as usual. It’s bit irritating…” Anyway we had a nice talk yesterday night and we shared our updates (updates from Japan and Updates from Belgium :-D )

When I applied a second thought on the same, surely the above said kind of reply is a bit irritating. I used to ask someone whom I know the same question and 80% of the replies are “Things are going as usual”. Anyway I am also biased to this answer but normally I’ll have something to say even I start with things are going as usual. (Huh lot of things are happening in my life :) )

John too was trying to keep-in-touch with me as all we do with our friends by asking this simple well-known question. But most of the people including me limiting the answer in a single line. The answer gives a hunch that we are not interested in talking with that person, we are not ready to share something with him and also there’s a notion that we are giving importance only for the big matters in our life. You can keep thinking on if I answer like this but the thing is, the conversation ends up there. But if we share small things, like “Last week I saw a movie. It is having a good story which is really inspirational” “Work was very tight last week and I had spent a lot time for fixing up the bugs” this will keep the conversation at least for some more time and we will have a quality time with our friends. Surely we will have as many things to share… silly simple things in life. It also having a power to keep the closeness to your friend and we can have different type of replies to the intensity and levels of friends. But we have to keep our friendship and relationships in a good way.

Thanks a lot John for the nice input and pointing out the mistake in my attitude.

You Should Avoid Partial Initialization of Objects

February 28th, 2007 Sarath Comments

Recently a code came to me for a review. I’m not exposing the real code but just scribbling a sample code like as it is.

#include <iostream>

using namespace std;
#define LOG_ERROR(msg) cerr<<msg<<endl
// Just a manager class. the members and other details are irrelevant here
class CManager
{ };
class CRender
{
private:
// Status whether the object is initialize or not
bool m_bInitialized;
CManager* m_pManager; // Manager Pointer
public:
// Ctor
CRender( CManager* pManager )
{
    if( !pManager )
    {
        LOG_ERROR(”Invalid pointer to Manager”);
        return; // You shouldn’t return at this point. This is dangerous
    }
    m_pManager = pManager;
    m_bInitialized = false;
    }
    // Initialize function
    bool Initialize()
    {
        if( !m_bInitialized )
        {
            cout<<”Do processing”
            m_bInitialized = true;
        }
        else
           LOG_ERROR(”Object already initialized”);
       return m_bInitialized;
    }
};

int main( int argc, char* argv[] )
{
    CRender rend(NULL);
    rend.Initialize();
    return 0;
}

Effective C++ also explains this scenario in prolific manner. An object should be constructed and destructed fully. Partial Initialization will make some unexpected behavior. The Initialize function can be called any number times from outside world. If we pass a NULL to the pointer, the object creation will not be complete since some of the significant members are omitted from its initialization.

Of course there are many ways defend write solid code. But still many people are not thinking in that way. You can also check for the m_pManager pointer many times in the functions where we are using it. In some trusted applications or classes, we will not validates the input because we are quite sure about the parameter passing.

In this case the the m_bInitializedis the catch which is initialized with some unknown values (it may vary depends on the compilers and configuration) we we can’t predict. Now in this case the Object will be in truble with “Default” constructor of that member. Note that this is the case of intrinsic data types. For the objects of some classes, the default Initialization will be done using default constructor or specified constructor in the Initialization list. Your code defines the behavior of your program.

Also I need to add one more point; if we are assigning something inside the ctor, that will be operator= operation than (copy) contruction.

Construction happens in the initialization list. For those members which is not specified in the initialization list, the compiler will initialize them with default constructor or value(compiler specific. for Visual C++, in the debug mode, the default value for initialization is 0xCD per byte).

CRender( CManager* pManager ) : m_pManager(pManager)

{

}

The above code is initialization and the previous one is rather assignment. The initialization really makes sense while you are using some heavy class or containers which does some heavy initializations. Containers will allocate memory of a default number of elements to avoid frequent allocation and de-allocation.

Suppose we have a vector of type int as class member and we are going to initialize it as follows.

CRender( const vector<int>& points )
{
    m_Points = vec; // calling operator= of vector
}

In the above code, the m_Points member will be initialized with default constructor even if didn’t specify that. Inside the body of the constructor, it is calling “operator=” of vector. So for the initialization of a member we have pay more CPU cycles since it will do some allocations, de-allocation or relocation depends on the input. But the following code can save some CPU cycle and thus the code will be a bit faster.

CRender( const vector<int>& points ) : m_pPoints(points)
{
    // Do rest of the processing
}

The above one has a serious drawback while we are using multiple constructors for the object where we need to specify it in the initialization list of every ctors. In that case it can be moved to a common function where you can do the initialization even if you pay more CPU cycles.

So never ever throw exceptions or return from constructors or destructors because it will show some unexpected behaviours because of the partial construction or destruction of objects (members).

Categories: C++, Code, Things You Shouldn't do, Tips Tags:

CArray SetSize and vector resize – How it behaves?

January 25th, 2007 Sarath Comments

#include <iostream>
#include <vector>
#include <string>
#include <afxtempl.h>

using namespace std;

int main()
{

     // MFC Array
     CArray<CString,CString> mfcArray;
     mfcArray.SetSize( 10 );
     mfcArray.Add(”Test Data”);
     mfcArray.Add(”Test Data”);
     mfcArray.Add(”Test Data”);
     mfcArray.Add(”Test Data”);
     mfcArray.Add(”Test Data”);
     cout<<”CArray size after operations”<<mfcArray.GetSize()<<endl;
    

     // STL Array

     vector<string> stlArray;
     stlArray.resize( 10 );
     stlArray.push_back(”Test Data”);
     stlArray.push_back(”Test Data”);
     stlArray.push_back(”Test Data”);
     stlArray.push_back(”Test Data”);
     stlArray.push_back(”Test Data”);
     cout<<”STL Array size”<<stlArray.size();
     return 0;
}

I’m using the above code to insert some items from the location 0 in the mfcArray. What’s the problem with the MFC array code? The above code will not serve our purpose. This is a common mistake to happen while we use the MFC templates. “SetSize” function will reserve the items and allocates the memory. We have to use “SetAt” function (it will not grow the array size) to insert for the proper allocation. If we use “InsertAt” function, again we are making bug because InsertAt function will also grow the array size. The “Add” function will append data to the end of array. So after the complete operations, the mfcArray will have 15 items and the 5 items I inserted will be there at the end of array. The first 10 elements will be blank. STL also behaves same as MFC templates. Just be aware about this.

Categories: Code, Things You Shouldn't do, Tips Tags:

Clipping cursor still active after stopping debugger :-O

October 20th, 2006 Sarath Comments

I have written code in Visual Studio 2005 to show list box as a pop-up window.

On Clicking the main window, I show/hide the window accordingly.

Yea the program working as I expected without having any problems.

When I had some issues, i decided to debug the program.

On showing the Listbox( cursor will be clipped ), I stopped debugging using Shift+F5.

The thing is, the Cursor Clipping was still there. After closing some opened windows from Visual Studio IDE and Switching to other windows resolved issue. but it was hectic for  minute.

I’m sure the process was not at all active. because it’s a very small application which exit on Shift+F5 press

 

// Code to clip the cursor on showing/hdie the window

void CListBoxEx::OnShowWindow(BOOL bShow, UINT nStatus)
{
    CListBox::OnShowWindow(bShow, nStatus);

    if( SW_SHOWNORMAL == bShow ) // Clip the cursor if window showing
    {
        CRect rect;
        GetWindowRect(rect);
        ClipCursor( rect );
    }
    else if( SW_HIDE == bShow ) // remove clipping on hiding
    {
        ClipCursor(NULL);
    }
}

Categories: Code, Things You Shouldn't do Tags:

The ten worst presentation moments

August 22nd, 2006 Sarath Comments

Take a look at The ten worst presentation moments

Source: Nishanth Sivakumar [Code Project]

A Funny Bug

August 1st, 2006 Sarath Comments

There we had a funny bug in one of our security products. Ok let me introduce the author of this bug Mr. John A V. He’s my colleague, senior in my college and he is my room mate as well.
He’s a real a brilliant guy who is having in-depth knowledge in C++, Windows Operating System, Linux and UNIX. He worked with security products and drivers in all platforms.

But this brilliant guy had a funny bug in his early days of his career. Let me explain the bug.

John was the person who supposed to do the registry monitoring part of the application. The key responsibility of his module was to monitor the registry keys used by the application and if somebody change those settings manually or programmatically, (in simple word if a change occurs) this module will replace the keys with it’s previous (original) values.
John did its coding in a well manner, and prepared for testing. He started the application. As the part of testing, he deleted the key which supposed to use by the application. Suddenly his application caught into a deadlock. He checked the code. he could not find any problems with that. When analyzed once more, he found the problem.
His module implements a call back mechanism, which is invoked whenever the registry keys’ value changed. As usual, his callback function invoked when the registry value changed. Suddenly the module, changed it back to the old (original) value. But his modification was also a change and “this change” gave him a callback that “the key you are watching has been changed”. Finally the module stuck up. Anyway he fixed it and it’s working fine now… but still we’re used to remember him this funny bug:).