Tag Archives: c++

Checking for C++ 11 Support

Most c++ compilers define a constant named __cplusplus which indicates C++ 11 support. Hence you can write something like this (thanks Cygon for the SO reply)


              

#if __cplusplus <= 199711L #error This library needs at least a C++11 compliant compiler #endif [/cpp] On most g++, you can pass -std=c++11 to toggle C++ 11 support:

g++ -std=c++11 main.cpp

This is what I get when I try to output the __cplusplus constant with the flag set:


              

#include
using namespace std;

int main() {
cout << __cplusplus << endl; return 0; } [/cpp] [text] $ g++ -std=c++11 test.cpp $ ./a.out 201103 [/text] Visual C++ compiler version 2012 or above should come with near-complete C++ 11 support.

Working With Time In C++

Working with time with any programming language is always tricky, C++ is no exception.

Getting Current Time

Use the time function to get the current time. Note that time_t has no timezone information, it’s simply UTC offset from epoch (1 January 1970 00:00:00). In most platform it’s stored as 8 bytes integer.

#include 

int main(int argc, char** argv) {
  time_t now;
  time(&now);
  return 0;
}

Formatting / Printing Time

Use C-style strftime function to format time. Note that strftime takes a struct tm * as parameter, so we have to first convert the time_t. Use localtime to convert it into local time zone.


              

struct tm * now_tm = localtime(&now);
char now_str[100];
strftime(now_str, sizeof(now_str), “%F %T %z”, now_tm);
cout << now_str << endl [/cpp] The above pattern string will produce a time format like this: [text] 2015-03-12 12:11:45 +1000 [/text] strftime man page has an excellent explanation of the pattern string. If you want to convert into GMT timezone you can also use gmtime

Parsing Time

This is where things get even more trickier. Not until C++11 standard the language come with a built-in way to parse time strings. Prior to that you have to either write your own parsing function or use 3rd party library like boost.

Check here how to enable C++11 in your toolset.

The new C++11 standard comes with get_time function which can be used to parse string into a struct tm:


              

#include
#include
#include

using namespace std;

int main() {
struct tm tt;
cout << "enter time in YYYY-MM-DD HH:mm format: "; cin >> get_time(&tt, “%Y-%m-%d %H:%M”);
cout << put_time(&tt, “%d %b %Y, %H:%M %z\n”); return 0; } [/cpp] This code will produce output like this: [text] $ ./a.out enter time in YYYY-MM-DD HH:mm format: 2015-06-11 23:44 11 Jun 2015, 23:44 +1000 [/text]

Setting Up ZeroMQ C++ On Visual Studio

This article is tested against following version / configuration:

  • Visual Studio 2012 (V110) Platform Toolset
  • Win32
  • ZeroMQ 4.0.4
  • Runtime Library: Multi-threaded DLL (/MD)

Steps to setup ZeroMQ on a Visual Studio C++ project:

  1. Download and install ZeroMQ-4.0.4~miru1.0-x86.exe (or newer) from http://zeromq.org/distro:microsoft-windows
  2. Set ZEROMQ_HOME environment variable to C:\Program Files (x86)\ZeroMQ 4.0.4 (or wherever you installed it to)
  3. On Visual Studio project configuration, add $(ZEROMQ_HOME)\include to Configuration Properties -> VC++ Directories. Don’t forget to restart Visual Studio so it picks up the new environment variable
  4. Add $(ZEROMQ_HOME)\lib to Linker -> General -> Additional Library Directories
  5. Add libzmq-v110-mt-4_0_4.lib to Linker -> Input -> Additional Dependencies
  6. Get a copy of zmq.hpp from , place this somewhere on your project. This header file references zmq.h located at $(ZEROMQ_HOME)\include
  7. Once you’ve compiled your executable, place libzmq-v110-mt-4_0_4.dll on the same folder, otherwise ZeroMQ initialisation will cause runtime crash

And finally take a look at some excellent tutorial examples from zeromq.org website to get you started, in particular:

See Also

Debugging Visual C++ DLL Without Host Application EXE Source Code

Here’s our situation, the 3rd party app we’re using in our company can be customized by loading a DLL into it, but we (obviously) cannot see the source code of the host exe program, we only have access to our DLL’s source code. The problem is how to debug our DLL when crashes occured?

Yes it’s unfortunate, if the DLL did cause a crash the host exe will go down together with it. Luckily the host exe record some kind of stack trace when it crashed, here’s what it looked like (let’s call our DLL cricket.dll to simplify things):

Filename    : *******
Time        : 2014.11.13 18:41 (74:37:03 elapsed)
Program     : ******
Version     : ******
Revision    : ******
OS          : Windows 7 Server 6.1 Service Pack 1 (Build 7601)
BIOS        : DELL   - 1 - PowerEdge R420
Explorer    : 9.11
ID          : 
Processors  : 24 x Intel Xeon  E5-2420 0 @ 1.90GHz
Computer    : LIVE-SERVER-1:WORKGROUP
Memory      : 29253 free of 32690 Mb
Virtual     : 2639 free of 4095 Mb
Handlers    : 14569
Path        : D:********
Disk D:     : 169325 Mb of 224999 Mb free
Exception   : C0000005 at 70606D91 read to 1FAF001A

Modules     : 01080000 009DD000 d:************.exe (*****)
            : 775A0000 00180000 c:\windows\syswow64\ntdll.dll (6.1.7601.18247)
            : 76EB0000 00110000 c:\windows\syswow64\kernel32.dll (6.1.7601.18409)
....
            : 705F0000 00047000 cricket.dll

Pay particular attention to the Modules section at the bottom. This tells us specific address in memory where our dll was loaded by the host exe. This information will be crucial to determine the relative address further down in the stack trace.

In this instance it told us cricket.dll was loaded at 0x705F0000 and it’s of 0x00047000 bytes length.

Further down the massive stack trace, we can see the record of the particular crash-causing thread:

      crash : #213 0002EFF4 EIP: 70606D91 ESP: 23CEF448 
              70606D91:000000 [70606D91] unknown (cricket.dll)
              705FF5E1:000000 [705FF5E1] unknown (cricket.dll)
              705F90C9:000000 [705F90C9] unknown (cricket.dll)
              705FF1A2:000000 [705FF1A2] unknown (cricket.dll)
              7060D652:000000 [7060D652] unknown (cricket.dll)
              7060D6D0:000000 [7060D6D0] unknown (cricket.dll)
              76EC3378:000012 [76EC338A] AcquireSRWLockExclusive (kernel32.dll)
              775D9F0F:000063 [775D9F72] RtlInsertElementGenericTableAvl (ntdll.dll)
              775D9F0F:000036 [775D9F45] RtlInsertElementGenericTableAvl (ntdll.dll)

crash -->  70606D91 80780F00          cmp        byte [eax+0xf], 0x0
              70606D95 74EB              jz         0x70606d82

          70606D97 8B8310040000      mov        eax, [ebx+0x410]
          70606D9D 89BD24FDFFFF      mov        [ebp+0xfffffd24], edi
          70606DA3 3BF8              cmp        edi, eax
          70606DA5 740E              jz         0x70606db5

          70606DA7 663B770C          cmp        si, [edi+0xc]

What I really wanted to know here is which line of my source code corresponds to the hex code above? First, find out the relative address. In this circumstances, since the DLL was loaded at 0x705F0000, we have to subtract that amount from the address, so 0x70606D91 - 0x705F0000 (in base 16) is 0x00016D91 (you can pull up Windows calculator, set it to Programmer mode if base 16 math is too hard).

Next, prepare the DLL source code of the same version against that crashed on production environment (git tagging will be very helpful here). This also requires the .pdb file of corresponding DLL which hopefully you’ve saved when releasing the code. Keep in mind recompiling the exact same source might produce incompatible .pdb.

Drop the .pdb file into your Release folder, and from Visual Studio select Debug -> Attach to Process... It’ll be easier if you run the exe locally loaded with the exact same DLL that crashed.

Next you’ll need to translate the relative address into the local address of the exe your debugger is attached to. To do this:

  1. Open the Modules window (Debug -> Windows -> Modules)
  2. Find your DLL, take note of its start address

vcppdebug1.

Here my local DLL is loaded at 0F75000, so I just need to add that to the relative address to localize it: 0x0F75000 + 0x0x00016D91 = 0x0F766D91

Next is to find the source code corresponding to that address:

  1. Open Debug -> Windows -> Disassembly
  2. On the address bar, input the localized address 0x0F766D91
  3. Right click on the line, and select Go to Source
  4. Voila! You’ve managed locate the culprit line, now do this for the other location on the stack trace too

vcppdebug2

Big thanks to SO community for helping me with this technique.

Using Boost Logging

Simple std::cout works great but there are few problems:

  1. Logging output only goes to console
  2. If program runs for a long time via cron / scheduler then output has to be redirected to a file
  3. Doing so might cause a large log with filesystem lock for which the program has to be stopped before it can be cleaned

Here’s how to use the Boost Logging library:


              

#include

#include “boost/log/trivial.hpp”
#include “boost/log/utility/setup.hpp”

using namespace std;

int main() {
// Output message to console
boost::log::add_console_log(
cout,
boost::log::keywords::format = “[%TimeStamp%]: %Message%”,
boost::log::keywords::auto_flush = true
);

// Output message to file, rotates when file reached 1mb or at midnight every day. Each log file
// is capped at 1mb and total is 20mb
boost::log::add_file_log (
boost::log::keywords::file_name = “MyApp_%3N.log”,
boost::log::keywords::rotation_size = 1 * 1024 * 1024,
boost::log::keywords::max_size = 20 * 1024 * 1024,
boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
boost::log::keywords::format = “[%TimeStamp%]: %Message%”,
boost::log::keywords::auto_flush = true
);

boost::log::add_common_attributes();

// Only output message with INFO or higher severity
boost::log::core::get()->set_filter(
boost::log::trivial::severity >= boost::log::trivial::info
);

// Output some simple log message
BOOST_LOG_TRIVIAL(trace) << "A trace severity message"; BOOST_LOG_TRIVIAL(debug) << "A debug severity message"; BOOST_LOG_TRIVIAL(info) << "An informational severity message"; BOOST_LOG_TRIVIAL(warning) << "A warning severity message"; BOOST_LOG_TRIVIAL(error) << "An error severity message"; BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message"; } [/cpp]

See Also

Using Boost On Visual Studio Project

To use Boost libraries, set following configurations on Visual Studio project properties:

  1. Check if boost is already installed (eg: C:\Program Files (x86)\boost\boost_1_51_0) if not, go through the installation process on http://www.boost.org/doc/libs/1_52_0/more/getting_started/windows.html
  2. Ensure BOOST_HOME environment variable exist and points to the installation path above
  3. On project properties, under C/C++ -> General, add $(BOOST_HOME) to Additional Include Directories
  4. Under Linker -> General, add $(BOOST_HOME)\lib to Additional Library Directories
  5. Ensure C/C++ -> Code Generations -> Runtime Library is set to /MD or /MDd so linker can find boost lib files

Some boost component such as boost log need to be built first before it can be linked:

  1. Unarchive the downloaded compressed file
  2. Open command prompt in administrator mode and cd into the unarchived directory. Run bootstrap.bat to build b2
  3. Run b2 install --prefix=PREFIX --toolset=msvc-10.0 --build-type=complete stage. This will take about 30 minutes, be patient. Note: “PREFIX” is the directory you want to install boost (eg: lib). “toolset=msvc-10.0″ means compile boost by using visual studio 2010.

Generating Visual C++ Crash Dump For Debugging

Detecting cause of problem that occurs only in production environment is hard. For Visual C++ created native windows application, this can be done using DebugDiag tool.

Download and install the tool on the production server, run it, and create a Crash rule type

vcppdebug1

Select a specific process target:

vcppdebug2

And search for your process

vcppdebug3

Tick This process instance only if multiple processes with same name are running but you’re only interested in one.

Click next and accept all defaults. Then when the crash occurs, you will get a .dmp file on C:\Program Files\DebugDiag\Logs\Crash rule for process id NNNN folder.

This .dmp file can be copied into your PC and opened in Visual Studio for stack trace analysis. Don’t forget you need to tell Visual Studio where to find the symbol (.pdb) file.

Select Set symbol paths on Visual Studio Action bar and add the folder containing your .pdb file.

vcppdebug4

Then start the debugging session by selecting Debug with Native Only. Visual Studio will tell you the stack trace when the crash happens.

Thanks to Ganesh R for providing this solution on Stack Overflow.

Also checkout Microsoft’s documentation on DebugDiag.

C++ min max Macro When Including Windows API

This is yet another quirks of C++ programming I found (and could be very hard to debug).

When you use Windows API (eg: you have #include ), it will pull min() and max() macro.

Apparently this will cause confusion for the compiler if you’re including another 3rd party library which expects standard library min() and max(). The error message you get is something like this (how obscure is this?):

1>c:mongodbsrcsrcmongodb../bson/bsonelement.h(630): warning C4003: not enough actual parameters for macro 'max'
1>c:mongodbsrcsrcmongodb../bson/bsonelement.h(630): error C2589: '(' : illegal token on right side of '::'
1>c:mongodbsrcsrcmongodb../bson/bsonelement.h(630): error C2059: syntax error : '::'
1>c:mongodbsrcsrcmongodb../bson/bsonelement.h(630): error C2143: syntax error : missing ';' before '{'

To avoid pulling the macros from Windows API, hash define following:

#define NOMINMAX

Connecting to MongoDB On Visual C++ / Visual Studio 2010

Environment / Dependencies:

  • Windows 7 64bit
  • Visual Studio 2010 (Win32-Release target project)
  • MongoDB 2.2.3
  • Git

Visual Studio 2010 sample client project doesn’t appear to compile on the latest version of mongodb source code (2.4.3 at the time of this writing). It seems the last working sample is version 2.2.3. Follow these steps to compile and use it as your starting point

  1. Clone the source code from git:
    git clone git://github.com/mongodb/mongo.git C:mongodbsrc
  2. Open command prompt to C:mongodbsrc, switch to version 2.2.3 by running:
    git checkout r2.2.3
  3. Double click C:mongodbsrcsrcmongoclientexamplessimple_client_demo.vcxproj. If Visual Studio prompt to upgrade, don’t do it
  4. Compile the project on visual studio and test it. Use this as your starting point
  5. If you’re trying to copy the settings into your own project, pay particular attention to following items:
    • Boost cpp files and mongo_client_lib.cpp inclusion
    • VC++ Directories
    • C/C++ –> General –> Additional Include Directories
    • C/C++ –> Preprocessor –> Preprocessor Definitions
    • Linker –> Input –> Additional Dependencies
    • Additional preprocessor definitions only for these boost files: thread.cpp, tss_dll.cpp, tss_pe.cpp
    • Different Output Files for utf8_codecvt_facet.cpp file

Quick Cheat Sheet

// Connecting to mongodb on c++
mongo::DBClientConnection conn;
conn.connect("localhost");

// mongo shell
db.mycoll.insert({name: "Gerry", age: "25"})

// c++
conn.insert("mydb.mycoll", BSON("name" << "Gerry" << "age" << 25));

// mongo shell
db.mycoll.update({name: "Gerry"}, {name: "Gerry", age: "30"}, {upsert: "true"})

// c++
conn.update("mydb.mycoll", BSON("name" << "Gerry"), BSON("name" << "Gerry" << "age" << 30), 1);

Documentations:

  • http://docs.mongodb.org/ecosystem/tutorial/download-and-compile-cpp-driver