Thursday, October 23, 2014

Filtering log files on Windows 7

Note: this is just a reminder about Windows analogues of grep - find and findstr.

Being inspired by this article: http://habrahabr.ru/post/71568/
now leaving some how-to's when working with large log files, containing messages from many processes.

How to get all messages from a process with PID=8238

C:\logs> type file.log | find "8238"
2014-09-19 16:40:22 8238   [INFO] Closing Session
2014-09-20 16:40:22 8238   [INFO] Closing Session
2014-09-22 16:40:35 8238   [WARNING] Error: No IC output on selected net (i.e., no driver).Stopping.
2014-09-22 16:40:50 8238   [INFO] Close Session: Design file: demo2.p

2014-09-22 16:41:38 8238   [INFO] Close Session: Design file: demo2.p
2014-09-26 15:45:11 8238   [INFO] Close Session: Design file: demodiff.p


How to get messages from interval [2014-09-22, 2014-09-26]

C:\logs> type file.log  | findstr /r /C:"2014-09-2[2-6]"
2014-09-22 16:40:22    [INFO] Closing Session: 
2014-09-22 16:40:35    [WARNING] Error: No IC output on selected net (i.e., no driver).Stopping.
2014-09-22 16:40:50    [INFO] Close Session: Design file: demo2.p

2014-09-22 16:41:38    [INFO] Close Session: Design file: demo2.p
2014-09-26 15:45:11    [INFO] Close Session: Design file: demodiff.p


Note that  /r stands for regular expressions. But regexps are limited in findstr, only [class] or [a-b] is allowed. See http://technet.microsoft.com/ru-ru/library/bb490907.aspx for reference.

Thursday, October 2, 2014

Compiling .cpp files in FAR by pressing Enter

Sometimes we write small prototype console applications to test any functions or learn C++ features. It would be nice just to edit .cpp file and get .exe compiled at once, like Linux guys can do just by entering gcc command.



What you have to do - just to mimic
Start->All-Programs->Microsoft Visual Studio 2008->Visual Studio Tools->Visual Studio 2008 Command Prompt, which simply calls
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" x86

Thursday, September 25, 2014

Odd HINSTANCE

Being called from DLL module, guess, which one would give you odd result?

HINSTANCE h1 = AfxGetInstanceHandle();
HINSTANCE  h2 = GetModuleHandle(NULL);
HINSTANCE h3 = AfxGetApp()->m_hInstance;
HINSTANCE h4 = theApp.m_hInstance;


Wednesday, August 27, 2014

A hole in decorated C++ names

At the first glance Decorated C++ Names are ideal, they encode all possible C++ method names and allow links between .obj and .lib files. Read Format of a C++ Decorated Name.

But sometime these names can bring some mystics into your life. Today we spent plenty of time revealing a method of a one class doesn't work. It IS called, but you NEVER hit it. This became possible because there were TWO(!!) different classes of the same name.

Here is a prototype project reproducing such a case.



ClassA.h:
#include "Base.h"
class
ClassA : public Base
{
public:
   ClassA(void);
   int f(void);
};

ClassB.h:
#include "Base.h"
class
ClassA : public Base
{
public:
   ClassA(int a);
   int g(void);
};


The reason why compiler and linker produce no errors is because they have different Decorated C++ Names.
ClassA.obj:

?g@ClassA@@QAEHXZ (public: int __thiscall ClassA::g(void))
??0ClassA@@QAE@H@Z (public: __thiscall ClassA::ClassA(int))
??1ClassA@@QAE@XZ (public: __thiscall ClassA::~ClassA(void))

ClassB.obj:
?f@ClassA@@QAEHXZ (public: int __thiscall ClassA::f(void))
??0ClassA@@QAE@XZ (public: __thiscall ClassA::ClassA(void))
??1ClassA@@QAE@XZ (public: __thiscall ClassA::~ClassA(void))

Decorated Name of destructors are the same, but linker was surprisingly silent
(See Viewing Decorated Names for reference)


Monday, August 11, 2014

Fitting multilungual resources in Visual Studio C++ project in user-friendly manner

Going to I18n with our MFC Visual Studio C++ projects, we were considering several methods for organizing resources, (read here for details):
  1. Language-dependent binary 
  2. One resource DLL for all languages 
  3. One resource DLL per target language 

I bet #2 is the best one, and here is how to organize .rc files and VS projects in the way good both: for machine and for humanity. Good for machine, because:
Good for humanity because:
  • resources for all languages will be capable of manual editing with Visual Studio (thus you can keep resources synchronized among different languages), 
  • It would be possible to edit TEXTINCLUDE from VS GUI.
Plenty of time spent for investigation, reading docs, exploring existing projects and collegial disputes made it possible to get desired structure of VS C++ project and .rc files. This structure might be used as a template for other projects, and even might be an Ariadne's thread in localization labyrinth.

Thursday, June 5, 2014

Buffer overflow? No problem

I used to work with printf() function for decades. And I've proved that I'm experienced guy in it. It was harder for me to catch buffer overflow, than to find memory leaks.

std::string Format( Data & data )
{
   std::string res;
   char buf[256];
   sprintf(buf, "[%s] %s", data.GetSeverity(), data.descr.c_str());
   res = buf;
   res.append("\n");
  
   return res;
}

The problem that data.descr COULD be > 256 bytes length...

Thursday, May 29, 2014

Haunting memory leaks in Visual Studio with DEBUG_NEW

The simplest ever way to find where it leaks.

1. Insert well known piece of code in all .cpp files suspected for leakage:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
2. Use CMemoryState to dump blocks allocated within suspected region:
CMemoryState msOld;
msOld.Checkpoint();
CPerson* pper1 = new CPerson();
CPerson* pper2 = new CPerson();
msOld.DumpAllObjectsSince();
See further how #define DUMP_NEW can help you automate leak searching