Suppressions in Valgrind

Recently I was trying to find all the memory leak in my product. Now my product is very complex and uses couple of third party libraries. When I ran valgrind it’s log file was full of errors from those third party libraries for which I do not have code.

If you want to find the memory leaks in your product only, one can use the Suppression facility in the valgrind

Following are the steps to create suppression file.

  • Create a file for example product.suppression
  • If you want to completely ignore certain shared library then add following lines to that file
  • {
       SUPPRESSION_TEST_OBJECT_COND
       Memcheck:Cond
       ...
       obj:<path to the shared library>
       ...
    }
    {
       SUPPRESSION_TEST_OBJECT_LEAK
       Memcheck:Leak
       ...
       obj:<path to the shared library>                                                                                                 
       ...
    }
    
  • Sometime I found that valgrind give false positive information. For example you may have code which is reusing certain buffer
  • In such case run the valgrind using –gen-suppressions=all option
  • Open the file and you will see output in some following format
  • Locate the memory leak which you think is false positive
  • Copy the suppression code and add it to your main suppression file
  • {
       <insert_a_suppression_name_here>
       Memcheck:Leak
       match-leak-kinds: possible
       fun:malloc
       fun:_ZN8stlp_std14__malloc_alloc8allocateEj
       fun:_ZN8stlp_std12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9_M_appendEPKcS7_
       fun:_ZN5dunit4Task4initEi
       fun:_Z12runPutGetAllbb
       fun:_GLOBAL__I_main
       obj:/export/pnq-gst-dev01a/users/adongre/valgrind_702/nc/ThinClient702X_maint/build-artifacts/linux/tests/cppcache/testThinClientPutGetAll
       obj:/export/pnq-gst-dev01a/users/adongre/valgrind_702/nc/ThinClient702X_maint/build-artifacts/linux/tests/cppcache/testThinClientPutGetAll
       fun:__libc_csu_init
       fun:(below main)
    }
    
  • You can also add it like below so that any code path calling that function will be ignored
  • {
       <insert_a_suppression_name_here>
       Memcheck:Leak
       match-leak-kinds: possible
       ...
       fun:_ZN8stlp_std14__malloc_alloc8allocateEj
       ...
    }
    
  • Remember to replace the line with some identifier
  • Next time when you run valgrind use the option –suppressions=

Pivotal GemFire Function Service and Scala

Yes Pivotal GemFire functions can be written in Scala. Pivotal GemFire Functions are described here
I am not going to write all the details about function Service. Since Scala is inter operable with Java, One can easily write Pivotal Gemfire functions in Scala and they will work as you wrote the functions in Java

Following is the Scala implementation of the MultiGetFunction taken from Function Service.

Step 1 : Write a Java wrapper around Gemfire Function Interface like below

package pivotal.scala.wrapper.functions;

import com.gemstone.gemfire.cache.execute.FunctionAdapter;
import com.gemstone.gemfire.cache.execute.FunctionContext;

public abstract class ScalaFunctionAdapter extends FunctionAdapter {    
  @Override
  public void execute(FunctionContext arg0) {
    executeScalaWrapper(arg0);
  }
  @Override
  public String getId() {
    return getIdScalaWrapper();
  }
  public abstract String getIdScalaWrapper();    
  public abstract void executeScalaWrapper(FunctionContext arg0);    
}

Step 2: Implement this interface in Scala , for example like below

package scala.gemfire.quickstart

import scala.collection.JavaConversions._
import com.gemstone.gemfire.cache.execute.FunctionAdapter
import com.gemstone.gemfire.cache.CacheFactory
import com.gemstone.gemfire.cache.execute.RegionFunctionContext
import com.gemstone.gemfire.cache.Region
import com.gemstone.gemfire.cache.Declarable
import com.gemstone.gemfire.cache.execute.FunctionContext
import com.gemstone.gemfire.cache.partition.PartitionRegionHelper
import pivotal.scala.wrapper.functions.ScalaFunctionAdapter

class MultiGetFunction extends ScalaFunctionAdapter {

  def getIdScalaWrapper: String = this.getClass.getName

  def executeScalaWrapper(fc: FunctionContext): Unit = {
    fc match {
      case frc: RegionFunctionContext => {
        val context = frc.asInstanceOf[RegionFunctionContext]
        val keys = context.getFilter()
        var keysTillSecondLast = new scala.collection.mutable.HashSet[Any]()
        keysTillSecondLast.addAll(keys.take(keys.size - 1))
        keysTillSecondLast.foreach { key =>
          context.getResultSender().
            sendResult(PartitionRegionHelper.
              getLocalDataForContext(context).get(key));
        }
        context.getResultSender().
          lastResult(PartitionRegionHelper.
            getLocalDataForContext(context).get(keys.last));
      }
      case _ => {
        fc.getResultSender().
          lastResult(Runtime.getRuntime().freeMemory() / (1024 * 1024));
      }
    }
  } 
}

Step 3 : Build code using sbt ( Java Wrapper + Scala Implementation of the functionAdapter)
Step 4: Use the built jar as a Function Execution code in java project.
Step 5: Note to add scala-library.jar in the classpath, sbt assembly combine all the deps but I have not tried that yet.

Using GemfireXD with Clojure

Clojure is a dynamic programming language that targets the Java Virtual Machine See here for further details. I like the language for many reasons and some of them are Full access to Java’s rich, mature API, Clojure is a Lisp, so all of the advantages that apply to Lisps apply to Clojure, Because “code is data”, you can do really neat things with macros and many more see here for more of why Clojure is awesome language to learn.

GemFire XD®, built on over a decade of innovation in real-time distributed systems, integrates with Pivotal HD and HAWQ to provide the industry’s first platform for creating closed loop analytics solutions. for more details about GemFire XD® see here.

In this post I am going to show how to access GemFire XD® using Clojure.

Java uses an API called JDBC to access databases, each vendor provides drivers to access their database systems, GemFire XD® uses JDBC driver for access. Download the jar file and place it on your classpath before starting Clojure REPL or Clojure Script

Clojure java.jdbc contains an interface to SQL databases via JDBC, first import the SQL interface

( ns clojure.gemfireXD.jdbc
  (:require [clojure.java.jdbc :as JDBC]))

Define the connection Parameters

def db-spec {:classname "com.vmware.sqlfire.jdbc.ClientDriver"
                :subprotocol "sqlfire"
                :subname "//localhost:1527/"})

You can either use DSL by the java.jdbc package or you can just simple execute any queries you want like below

(defn using-simple-queries
  []  
  (JDBC/db-do-commands db-spec true 
         "create table customer (
        c_w_id         integer        not null,
        c_d_id         integer        not null,
        c_id           integer        not null,
        c_discount     decimal(4,4), c_credit       char(2),
        c_last         varchar(16), c_first        varchar(16),
        c_credit_lim   decimal(12,2), c_balance      decimal(12,2),
        c_ytd_payment  float, c_payment_cnt  integer,
        c_delivery_cnt integer, c_street_1     varchar(20),
        c_street_2     varchar(20), c_city         varchar(20),
        c_state        char(2), c_zip          char(9),
        c_phone        char(16), c_since        timestamp,
        c_middle       char(2), c_data         varchar(500)) partition by (c_w_id) redundancy 1")
  (JDBC/db-do-commands db-spec true 
          "create table new_order ( no_w_id  integer   not null,
        no_d_id  integer   not null,no_o_id  integer   not null) 
        partition by (no_w_id) colocate with (customer) redundancy 1")

  (JDBC/db-do-commands db-spec true "alter table customer add constraint pk_customer 
        primary key (c_w_id, c_d_id, c_id)")

  (JDBC/db-do-commands db-spec true "create index ndx_customer_name 
        on customer (c_w_id, c_d_id, c_last)")

  (JDBC/db-do-commands db-spec true "alter table new_order add constraint pk_new_order
        primary key (no_w_id, no_d_id, no_o_id)")

  (JDBC/db-do-commands db-spec true, "create index ndx_neworder_w_id_d_id
        on new_order (no_w_id, no_d_id)")

  (JDBC/db-do-commands db-spec true "create index ndx_neworder_w_id_d_id_o_id
        on new_order (no_w_id, no_d_id, no_o_id)")
)

Creating a table using java.jdbc of Clojure DSL.

(defn create-table-customer
  [db-spec]
  (JDBC/db-do-commands
    db-spec ( JDBC/create-table-ddl
              :customer
              [:c_w_id         :integer    "not null"]
              [:c_d_id         :integer    "not null"]
              [:c_id           :integer    "not null"]
              [:c_discount     :decimal    "(4,4)"]
              [:c_credit       :char       "(2)"]
              [:c_last         :varchar    "(16)"]
              [:c_first        :varchar    "(16)"]
              [:c_credit_lim   :decimal    "(12,2)"]
              [:c_balance      :decimal    "(12,2)"]
              [:c_ytd_payment  :float]
              [:c_payment_cnt  :integer]
              [:c_delivery_cnt :integer] 
              [:c_street_1     :varchar    "(20)"]
              [:c_street_2     :varchar    "(20)"] 
              [:c_city         :varchar    "(20)"]
              [:c_state        :char       "(2)"]
              [:c_zip          :char       "(9)"]
              [:c_phone        :char       "(16)"] 
              [:c_since        :timestamp]
              [:c_middle       :char       "(2)"]
              [:c_data         :varchar    "(500)"]
              :table-spec "partition by (c_w_id) redundancy 1")))

  (defn create-table-new-order
    [db-spec]
    (JDBC/db-do-commands 
      db-spec
      (JDBC/create-table-ddl
        :new_order
        [:no_w_id  :integer   "not null"]
        [:no_d_id  :integer   "not null"]
        [:no_o_id  :integer   "not null"]
        :table-spec "partition by (no_w_id) colocate with (customer) redundancy 1")))  

Here is the complete working code

( try
  (JDBC/db-do-commands db-spec (JDBC/drop-table-ddl :new_order))
  (JDBC/db-do-commands db-spec (JDBC/drop-table-ddl :customer))
  (catch Exception _ ;;ignore 
  ))
(create-table-customer db-spec)
(create-table-new-order db-spec)

(JDBC/db-do-commands db-spec true "alter table customer add constraint pk_customer primary key (c_w_id, c_d_id, c_id)")

(JDBC/db-do-commands db-spec true "create index ndx_customer_name on customer (c_w_id, c_d_id, c_last)")

(JDBC/db-do-commands db-spec true "alter table new_order add constraint pk_new_order primary key (no_w_id, no_d_id, no_o_id)")

(JDBC/db-do-commands db-spec true "create index ndx_neworder_w_id_d_id on new_order (no_w_id, no_d_id)")

(JDBC/db-do-commands db-spec true "create index ndx_neworder_w_id_d_id_o_id on new_order (no_w_id, no_d_id, no_o_id)")

(JDBC/db-do-prepared db-spec true "insert into new_order values (?, ?, ?)" [1 1 1][2 2 2][3 3 3][4 4 4][5 5 5][6 6 6][7 7 7][8 8 8][9 9 9][10 10 10])

(println (JDBC/query db-spec ["SELECT * FROM new_order"] :result-set-fn count))

and there you go start using GemFire XD® using Clojure. Clojure Java.jdbc also provides api for accesing Database Metadata.
One can also use Clojure Connecton pooling Clojure JDBC pool

Building R on Ubuntu

Today morning I wanted to do experiments with RJDBC . To my surprise Ubuntu 12.04 does not have latest version of R
Following are the steps I have followed to build R on Ubuntu.

  • Install the required dependencies.
  • sudo apt-get install gcc g++ gfortran libreadline-dev libx11-dev xorg-dev
    
  • Download the source.
  • svn checkout https://svn.r-project.org/R/trunk/ r-devel
    
  • Sync the required modules.
  • cd r-devel/
    apt-get install rsync
    sudo apt-get install rsync
    ./tools/rsync-recommended
    

    If you are behind firewall, setup RSYNC_PROXY.

  • Configure and Make.
  • JAVA_HOME=<your java home> ./configure --prefix <where you want to install the binaries>
    make
    
  • Install.
  • make install
    

    Making Apache Thrift Selector Server Non-blocking

    Recently I am doing lot of experiments with Apache Thrift. Interesting piece of software framework  for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.

    Documentation seems to very limited. I was trying to use TThreadedSelectorServer 

    Typical usage of TThreadedSelectorServer I found is as below

    TNonblockingServerTransport trans = new TNonblockingServerSocket(port);
    TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(trans);
    args.transportFactory(new TFramedTransport.Factory());
    args.protocolFactory(new TBinaryProtocol.Factory());
    args.processor(your processor);
    args.selectorThreads(4);
    args.workerThreads(32);
    TServer server = new TThreadedSelectorServer(args);
    server.serve();
    

    But this serve is blocking call and you cannot use it in your already available server. Or I do not know any other way to make it embedded.

    Here is my solution to make it work .

    Create a new class child of TThreadedSelectorServer and implement serve and stop as below and you are good to go.

    public class MyTThreadedSelectorServer extends TThreadedSelectorServer {
    
      public MyTThreadedSelectorServer(Args args) {
        super(args);
      }
    
      public void serve() {
        if (!startThreads()) {
          return;
        }
        // start listening, or exit
        if (!startListening()) {
          return;
        }
        setServing(true);
      }
    
      public void stop() {
        setServing(false);
        super.stop();
      }
    
    }
    

    Building Thirift on Ubuntu behind firewall

    I was trying to build thrift on ubuntu and hit some issues, specially because my machine was behind the firewall. I am going to put down the steps to build thrift.
    You need some more packages on your box and boost.

    • Dowload Boost
    • Building boost instruction are given on there site, but you can use following command to build the boost locally
    • ./bootstrap.sh
      ./bootstrap.sh --prefix=/usr/local/boost_1_46_1
      ./bjam install
      
    • External packages required to build thrift can be done using following command
    • sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev
      
    • Go to thrift directory where you have un-archived the source code
    • Build thrift using following command providing boost directory and JAVAC location
    • ./configure --with-boost=/usr/local/boost_1_46_1 JAVAC=/home/avinash/export/where/jdk/1.6.0_26/x86.linux/bin/javac
      
    • Upon completing successfull configuration, run make command
    • make
      

      If you are behind firewall you might hit error regarding downloading jars from maven repository.
      Maven tries to auto download the dependencies if they are not available within your local repository,
      since maven did not know of your proxy it was unable to download them and failed. Adding the
      proxy config to your maven settings.xml should resolve your problem when you box is behind firewall

    • Open your build.xml from your java directory
    • /home/avinash/work/thrift-0.9.0/lib/java/build.xml
      
    • Look for target mvn.ant.tasks.download
    • Add following proxy settings to your file
      <setproxy proxyhost="your proxy server name" proxyport="port number"/>
      
    • So new target looks like below
    •  <target name="mvn.ant.tasks.download" depends="setup.init,mvn.ant.tasks.check,proxy" unless="mvn.ant.tasks.found">
          <setproxy proxyhost="proxy.com" proxyport="1234"/>
          <get src="${mvn.ant.task.url}/${mvn.ant.task.jar}" dest="${build.tools.dir}/${mvn.ant.task.jar}" usetimestamp="true"/>
        </target>
      

      This will solve your initial download issue but mvn.init target still give you issue while downloading maven depencies

    • If you already do not have settings.xml
    • Create it in your home folder under .m2 directory
    • Add following lines in the settings.xml file
    • <settings>
        <proxies>
         <proxy>
            <active>true</active>
            <protocol>http</protocol>
            <host>PROXY-SERVER-NAME</host>
            <port>PROXY-SERVER-PORT</port>
            <username>proxyuser</username>
            <password>somepassword</password>
            <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
          </proxy>
        </proxies>
      </settings>
      
    • and run make again.

    BEAUTIFUL STRINGS

    PROBLEM STATEMENT

    When John was a little kid he didn’t have much to do. There was no internet, no Facebook, and no programs to hack on. So he did the only thing he could… he evaluated the beauty of strings in a quest to discover the most beautiful string in the world.

    Given a string S, little Johnny defined the beauty of the string as the sum of the beauty of the letters in it.

    The beauty of each letter is an integer between 1 and 26, inclusive, and no two letters have the same beauty. Johnny doesn’t care about whether letters are
    uppercase or lowercase, so that doesn’t affect the beauty of a letter. (Uppercase ‘F’ is exactly as beautiful as lowercase ‘f’, for example.)

    You’re a student writing a report on the youth of this famous hacker. You found the string that Johnny considered most beautiful. What is the maximum possible beauty of this string?

    INPUT

    The input file consists of a single integer m followed by m lines.
    OUTPUT

    Your output should consist of, for each test case, a line containing the string “Case #x: y” where x is the case number (with 1 being the first case in the
    input file, 2 being the second, etc.) and y is the maximum beauty for that test case.

    CONSTRAINTS

    5 <= M <= 50
    2 <= length of S <= 500
    

    EXAMPLE INPUT

        5
        ABbCcc
        Good luck in the Facebook Hacker Cup this year!
        Ignore punctuation, please :)
        Sometimes test cases are hard to make up.
        So I just go consult Professor Dalves
    

    EXAMPLE OUTPUT

        Case #1: 152
        Case #2: 754
        Case #3: 491
        Case #4: 729
        Case #5: 646
    

    Solution:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <algorithm>
    #include <vector>
    
    struct InvalidChar
    {
        bool operator()(char c) const {
            return !isalpha((unsigned)c);
        }
    };
    
    int main( int argc, char **argv) 
    {
        if ( argc <= 1 ) {
            return 0;
        }
        std::ifstream input(argv[1]);
        if ( input.peek() == EOF ) {
            return 0;
        }
        // Read the number of test cases
        int M;
        input >> M ;
        // Read the first line and ignore it
        std::string line;
        std::getline (input,line);
        for ( int m = 0; m < M ; m++) {
            std::vector<int> occurences;
            occurences.resize(26);
            std::getline (input,line);
            std::transform(line.begin(), line.end(), line.begin(), ::tolower);
            line.erase(std::remove_if(line.begin(),line.end(),InvalidChar()), line.end());
            if ( !line.empty()) {
                for ( int i = 0; i < (int)line.size(); i++) {
                    occurences[line[i] - 'a']++;
                }
            }
            occurences.erase(std::remove(occurences.begin(), occurences.end(), 0), occurences.end());
            std::sort(occurences.begin(), occurences.end(), std::greater<int>());
            int multiply_factor = 26;
            int final_answer = 0;
            for ( std::vector<int>::iterator itr = occurences.begin(); itr != occurences.end(); ++itr) {
                final_answer += (*itr) * multiply_factor--;
            }
            std::cout << "Case #" << m + 1 << ":  " << final_answer << std::endl;
        }
        input.close();
        return 0;
    }
    

    Finding Memory leak in C++ Application on Windows

    Finding memory leaks can be very difficult job sometimes, if you do not have right set of tools. My experience with memory leak detector tools on windows is bad, sometimes they are not able to correctly instrument the code and some gives you cryptic language output. So I decided to write something. After reading couple of article, in pure C++ environment you can overload operator new and operator delete and this trick can be used to build small tool which would be easy to integrate and find leaks during development. In C language world writing macros which wraps systems calls like malloc/calloc/realloc will help you to find the file name and line number . But in C++, when you do new, it first calls operator new and then the constructors, so macros or pre-processor technique would not be useful.

    But Windows has nice StackWalk64 family of API which could be used to find the exact stack trace for the origin of the call.

    You will need to include following header file in your project and call dumpUnfreedMemory after your application is done.

    For further development on the same watch Memory Tracking On Windows

    #ifndef MEMORY_TRACKER_H_
    #define MEMORY_TRACKER_H_
    
    #pragma warning( disable : 4290 )
    #pragma comment(lib, "Dbghelp.lib")
    
    #include <Windows.h>
    #include <malloc.h>
    #include <DbgHelp.h>
    #include <stdio.h>
    #include <exception>
    
    
    static const int MAX_TRACES = 62;
    static const int MAX_LENGTH = 256;
    static const int BUFFER_LENGTH = (sizeof(SYMBOL_INFO) + MAX_LENGTH * sizeof(wchar_t) + sizeof(ULONG64) - 1) / sizeof(ULONG64); static bool SYSTEM_INITIALIZED = false;
    
    static CRITICAL_SECTION gLock;
    static bool lockInitialized = false;
    
    void Lock() {
      if ( lockInitialized == false ) {
        ::InitializeCriticalSection(&gLock);
        lockInitialized = true;
      }
      ::EnterCriticalSection(&gLock);
    }
    
    void Unlock() {
      ::LeaveCriticalSection(&gLock);
    }
    
    
    typedef struct record_t {
    char symbol[2048];
    char filename[128];
    char linenumber[2048];
      int depth;
    } record;
    
    typedef struct AllocList_t {
    DWORD address;
    DWORD size;
      record *details;
    
      struct AllocList_t* next;
    
    } AllocList;
    
    AllocList *gListHead = NULL;
    
    static void GetCallStackDetails(const void* const* trace, int count, AllocList *newRecord ) {
    for (int i = 0; i < count; ++i) {
    ULONG64 buffer[BUFFER_LENGTH];
    DWORD_PTR frame = reinterpret_cast<DWORD_PTR>(trace[i]);
    DWORD64 sym_displacement = 0;
    PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(&buffer[0]);
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    symbol->MaxNameLen = MAX_LENGTH;
    BOOL has_symbol = SymFromAddr(GetCurrentProcess(), frame, &sym_displacement, symbol);
    DWORD line_displacement = 0;
    IMAGEHLP_LINE64 line = {};
    line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
    BOOL has_line = SymGetLineFromAddr64(GetCurrentProcess(), frame, &line_displacement, &line);
    
        _snprintf (newRecord->details[i].symbol, 2048, "%s", "(No Symbol)");
    
    if (has_symbol) {
          _snprintf (newRecord->details[i].symbol, 2048, "%s", symbol->Name );
    }
    if (has_line) {
          _snprintf (newRecord->details[i].filename, 128, "%s", line.FileName);
          _snprintf (newRecord->details[i].linenumber, 2048, " [%d]", line.LineNumber);
    } else {
          _snprintf (newRecord->details[i].filename, 128, "%s", "Could not determing file name");
          _snprintf (newRecord->details[i].linenumber, 2048, " [%d]", "Could not determine file line");
        }
    }
    }
    
    static void addRecord(void *ptr, size_t size) {
      Lock();
    if ( SYSTEM_INITIALIZED == false ) {
    SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);
    if (SymInitialize(GetCurrentProcess(), NULL, TRUE)) {
    SYSTEM_INITIALIZED = true;
    } else {
    SYSTEM_INITIALIZED = false;
    return;
    }
    }
    
      AllocList *newRecord = (AllocList*) malloc ( sizeof ( AllocList ));
      newRecord->next = NULL;
      newRecord->address = (DWORD)ptr;
      newRecord->size = size;
    
      if ( gListHead == NULL ) {
        gListHead = newRecord;
      } else {
        AllocList *current = gListHead;
        while ( current->next != NULL ) {
          current = current->next;
        }
        current->next = newRecord;
      }
    
    void* trace[MAX_TRACES];
    int count = CaptureStackBackTrace(0, MAX_TRACES , trace, NULL);
    
      newRecord->details = ( record *) malloc ( count * sizeof ( record ));
      newRecord->details[0].depth = count;
    
    GetCallStackDetails( trace, count, newRecord);
      
      Unlock();
    }
    
    static void deleteRecord(void *ptr ) {
      Lock();
      AllocList *current, *previous;
      previous = NULL;
      for (current = gListHead; current != NULL; previous = current, current = current->next) {
        if (current->address == (DWORD)ptr) {
          if (previous == NULL) {
            gListHead = current->next;
          } else {
            previous->next = current->next;
          }
          free(current);
          Unlock();
          return;
        }
      }
      Unlock();
    }
    
    void dumpUnfreedMemory(FILE *fp=stderr) {
      Lock();
      AllocList *current;
      int totalBytesNotFreed = 0;
      for (current = gListHead; current != NULL; current = current->next) {
        int depth = current->details[0].depth;
        fprintf ( fp, "Bytes allocated %d not free in following code path\n", current->size );
        totalBytesNotFreed += current->size;
        for ( int i = 0; i < depth ; i++) {
          fprintf ( fp, "%s:%s:%s\n", current->details[i].filename, current->details[i].linenumber, current->details[i].symbol);
        }
        fprintf(fp, "\n");
      }
      fprintf ( fp, "Total bytes not freed %d\n", totalBytesNotFreed );
      Unlock();
    }
    
    // Overloading new operator
    void* operator new ( size_t size ) throw ( std::bad_alloc ) {
    void *ptr = (void *)malloc(size);
    addRecord(ptr, size);
    return ptr;
    }
    // Overloading new[] operator
    void * operator new [] (size_t size) {
      return operator new (size);
    }
    
    // Overloading delete Operator
    void operator delete ( void* ptr ) throw () {
    deleteRecord(ptr);
    free ( ptr );
    }
    
    // Overloading delete[] Operator
    void operator delete [] (void * p) {
      operator delete (p);
    }
    
    #endif
    

    Test program

    #include "MemoryTracker.h"
    void dummyfunc1() {
      char *ptr = new char;
    }
    
    int *dummyfunc2() {
      int *ptr = new int;
      return ptr;
    }
    
    int main ( int argc, char **argv) {
      int *ptr  = new int;
      int *ptr1 = new int;
      int *ptr2 = new int;
    
      delete ptr1;
      //delete ptr2;
      //delete ptr;
    
      dummyfunc1();
      int *ptr3 = dummyfunc2();
      delete ptr3;
    
      dumpUnfreedMemory();
    
      return 0;
    }
    

    After running this your will get output as follows:

    Bytes allocated 4 not free in following code path
    memory_test\memory_test\memorytracker.h: [95]:addRecord
    memory_test\memory_test\memorytracker.h: [137]:operator new
    memory_test\memory_test\memory_test.cpp: [12]:main
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c: [555]:__tmainCRTStartup
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c: [371]:mainCRTStartup
    Could not determing file name: [18512724]:BaseThreadInitThunk
    Could not determing file name: [18512724]:RtlInitializeExceptionChain
    Could not determing file name: [18512724]:RtlInitializeExceptionChain
    
    Bytes allocated 4 not free in following code path
    memory_test\memory_test\memorytracker.h: [95]:addRecord
    memory_test\memory_test\memorytracker.h: [137]:operator new
    memory_test\memory_test\memory_test.cpp: [14]:main
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c: [555]:__tmainCRTStartup
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c: [371]:mainCRTStartup
    Could not determing file name: [18512724]:BaseThreadInitThunk
    Could not determing file name: [18512724]:RtlInitializeExceptionChain
    Could not determing file name: [18512724]:RtlInitializeExceptionChain
    
    Bytes allocated 1 not free in following code path
    memory_test\memory_test\memorytracker.h: [95]:addRecord
    memory_test\memory_test\memorytracker.h: [137]:operator new
    memory_test\memory_test\memory_test.cpp: [3]:dummyfunc1
    memory_test\memory_test\memory_test.cpp: [21]:main
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c: [555]:__tmainCRTStartup
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c: [371]:mainCRTStartup
    Could not determing file name: [18512724]:BaseThreadInitThunk
    Could not determing file name: [18512724]:RtlInitializeExceptionChain
    Could not determing file name: [18512724]:RtlInitializeExceptionChain
    
    Total bytes not freed 9
    

    Making your class Non-Copyable and Non-Assignable

    I was working on removing Coverity defects. My product is written such that we do not do any copy and assignment of the C++ classes .
    So Coverity starting giving errors of following kind.

    CID 28711: Other violation (MISSING_ASSIGN) and CID 28711: Other violation (MISSING_COPY)
    

    Solution to this problem was to add private copy constructor and private assignment operator.
    But since I had more than 500 classes do edit. I wrote a two new classes NonCopyable and NonAssignable
    and inherit all the problem classes from the same.

    class NonCopyable 
    {
    protected:
        NonCopyable() {}
        ~NonCopyable() {}
    private:  
        NonCopyable( const NonCopyable& );
    };
    

    and

    class  NonAssignable
    {
    protected:
        NonAssignable() {}
        ~NonAssignable() {}
    private:  
        const NonAssignable& operator=( const NonAssignable& );
    };
    

    If you want to make your class Non copyable inherit from NonCopyable and If you want to make your class Non assignable inherit from NonAssignable

    Launching JVM from C++

    Recently I have to write small utility to launch my product Java server using C++. So thought to share the generic class I wrote for launching JVM using C++/Jni.

    #include <stdexcept>
    #include <windows.h>
    #include <tchar.h>
    #include <strsafe.h>
    #include <include/jni.h>
    
    #include <string>
    #include <stdlib.h>
    #include <vector>
    #include <iostream>
    
    
    class JVMLauncherException : public std::runtime_error {
    public:
        JVMLauncherException(const std::string& message) : std::runtime_error(message) 
        { 
        };
    };
    
    class JVMLauncher {
    public:
        JVMLauncher();
        void addJars(std::string inJar);
        void LaunchJVM();
        void StartJVMServer();
        void AddServerArguments(std::string);
    private:
        typedef jint (JNICALL *CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
    
        HINSTANCE     m_hDllInstance;
    
        std::string   m_JavaHome;
        std::string   m_ProductLibDir;
        std::string   m_JvmDllLocation;
    
        CreateJavaVM  m_JVMInstance;
        jclass        m_CacheServerLauncherClass;
        jmethodID     m_MainMethodID;
        JNIEnv       *m_JVMEnv;
        JavaVM       *m_RunningJVMInstance;    
    
        std::vector<std::string> m_listOfJars;
        std::vector<std::string> m_ServerArguments;
    
        void CheckForJNIException();
    protected:
    };
    
    JVMLauncher::JVMLauncher() {
        // Check for JAVA_HOME
        char *pValue;
        size_t len;
        errno_t err = _dupenv_s( &pValue, &len, "JAVA_HOME" );
        if ( err ) {
            throw JVMLauncherException("JAVA_HOME not defined");
        }    
        m_JavaHome       = pValue;
        m_JvmDllLocation = m_JavaHome + "\\jre\\bin\\server\\jvm.dll";
    
        err = _dupenv_s( &pValue, &len, "PRODUCT HOME PATH" );
        if ( err ) {
            throw JVMLauncherException("PRODUCT HOME PATH not defined");
        }
        m_ProductLibDir = pValue;
    
        m_listOfJars.push_back("depedent1.jar");
        m_listOfJars.push_back("depedent2.jar");
        m_listOfJars.push_back("depedent3.jar");
        m_listOfJars.push_back("depedent4.jar");
        m_listOfJars.push_back("depedent5.jar");    
    }
    void JVMLauncher::AddServerArguments(std::string inParam) {
        m_ServerArguments.push_back(inParam);
    }
    void JVMLauncher::LaunchJVM() {
        // Construct the product specific class path.
        std::string strJavaClassPath = "-Djava.class.path=";
        for ( std::size_t idx = 0; idx < m_listOfJars.size() - 1 ; idx++) {
            strJavaClassPath += m_ProductLibDir + "\\lib\\" + m_listOfJars[idx] + ";";
        }
        strJavaClassPath += m_ProductLibDir + "\\lib\\" + m_listOfJars[m_listOfJars.size() - 1] ;
    
        // consruct java.library.path
        std::string strJavaLibraryPath =  "-Djava.library.path=";
        strJavaLibraryPath             += m_JavaHome + "\\lib" + "," + m_JavaHome + "\\jre\\lib";
    
        
        // try loading jvm dll
        m_hDllInstance = LoadLibraryA(m_JvmDllLocation.c_str());
        if( m_hDllInstance == 0) {
            throw JVMLauncherException("Cannot load jvm.dll");
        }
        m_JVMInstance = (CreateJavaVM)GetProcAddress(m_hDllInstance, "JNI_CreateJavaVM");
        if ( m_JVMInstance == NULL )  {
            throw JVMLauncherException("Cannot load jvm.dll");
        }
    
        JavaVMOption options[3];
        options[0].optionString  = const_cast<char*>(strJavaClassPath.c_str());
        options[1].optionString  = const_cast<char*>(strJavaLibraryPath.c_str());
        options[2].optionString  = "-verbose:jni";
    
        JavaVMInitArgs vm_args;
        vm_args.version            = JNI_VERSION_1_6; //JNI Version 1.4 and above
        vm_args.options            = options;    
        vm_args.nOptions           = 3;       
        vm_args.ignoreUnrecognized = JNI_TRUE;
    
        //Create the JVM
        
        jint res = m_JVMInstance(&m_RunningJVMInstance, (void **)&m_JVMEnv, &vm_args);
        if (res < 0)  {
        	throw JVMLauncherException("Could not launch the JVM");
        }
    
        m_CacheServerLauncherClass = m_JVMEnv->FindClass("<your main class>");    
        CheckForJNIException();
    
        m_MainMethodID = m_JVMEnv->GetStaticMethodID(m_CacheServerLauncherClass, "main", "([Ljava/lang/String;)V");
        CheckForJNIException();
    }
    
    void JVMLauncher::StartJVMServer() {
    
        if ( m_RunningJVMInstance->AttachCurrentThread((LPVOID *)&m_JVMEnv, NULL) ) {
            std::cout << "Fail to attach the current thread " << std::endl;
        }
    
        jclass StringClass = m_JVMEnv->FindClass("java/lang/String");
        int numOfArguments = (int)m_ServerArguments.size() + 4 ;
        int argumentIndex = 0;
    
        jobjectArray jargs = m_JVMEnv->NewObjectArray(numOfArguments, StringClass, NULL);    
    
        m_JVMEnv->SetObjectArrayElement(jargs, argumentIndex++, m_JVMEnv->NewStringUTF("start"));
    
        std::string strJavaClassPath = "-classpath=";
        strJavaClassPath             += "\"";
        for ( std::size_t idx = 0; idx < m_listOfJars.size() - 1 ; idx++) {
            strJavaClassPath += m_ProductLibDir + "\\lib\\" + m_listOfJars[idx] + ";";
        }
        strJavaClassPath      += m_ProductLibDir + "\\lib\\" + m_listOfJars[m_listOfJars.size() - 1] ;
        strJavaClassPath      += "\"";
    
        m_JVMEnv->SetObjectArrayElement(jargs, argumentIndex++, m_JVMEnv->NewStringUTF(strJavaClassPath.c_str()));
    
        for ( std::vector<std::string>::iterator iter = m_ServerArguments.begin(); iter != m_ServerArguments.end(); ++iter) {
            std::string argument = *iter;
            m_JVMEnv->SetObjectArrayElement(jargs, argumentIndex++, m_JVMEnv->NewStringUTF(argument.c_str()));
        }
        m_JVMEnv->SetObjectArrayElement(jargs, argumentIndex++, m_JVMEnv->NewStringUTF("argument1"));    
        m_JVMEnv->SetObjectArrayElement(jargs, argumentIndex, m_JVMEnv->NewStringUTF("argument2"));    
    
        m_JVMEnv->CallStaticVoidMethod(m_CacheServerLauncherClass, m_MainMethodID, jargs);
    
        m_RunningJVMInstance->DestroyJavaVM();
    
        CheckForJNIException();
    }
    
    void JVMLauncher::CheckForJNIException() {
        jthrowable expt = m_JVMEnv->ExceptionOccurred();
        if (expt != NULL) {
            m_JVMEnv->ExceptionClear();
            jmethodID toString = m_JVMEnv->GetMethodID(m_JVMEnv->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;");
            jstring estring = (jstring) m_JVMEnv->CallObjectMethod(expt, toString);
            jboolean isCopy;
            std::string message = m_JVMEnv->GetStringUTFChars(estring, &isCopy);
            throw JVMLauncherException(message);
        }
    }