Proposition for reporting MEMORY LEAKS in strategy tester - page 2

 

Hi,

I'm using the Include File shown above only during the development and testing stage of a new EA. I want to ensure, that I do not have any memory leaks.

Later during life operation I simply do not include the file.

Matthias

 

Hi,

just for clarity and better understanding.

In contribution #6 of this thread I presented my version of an include file for checking and identifying memory leaks. Let us name this file "check_for_memory_leaks.mqh".

The following little script with name "little_script.mq5" uses this header file:

#include "check_for_memory_leaks.mqh"
class CA {
};
void OnStart() {
   CA *a;
   a = new CA;
   if (a == NULL) {
     Print("NULL Pointer!");
     return;
   }
   delete a;
}

Now I want to preprocess the source code by the following command:

cpp little_script.mq5 -E

The output is

$ cpp little_script.mq5 -E
# 0 "little_script.mq5"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "little_script.mq5"
# 1 "check_for_memory_leak.mqh" 1
# 9 "check_for_memory_leak.mqh"
class Cdbg_heap_obj_trace {
private:

  CHashMap<string,string> m_map;
  int m_line;
  string m_filename;

public:
  Cdbg_heap_obj_trace() {
    m_map.Clear();
  }

  ~Cdbg_heap_obj_trace() {
    Print ("-- Resume Memory Leaks --");
    string desc[], infos[];
    ArrayFree (desc);
    ArrayFree (infos);
    m_map.CopyTo (desc,infos);
    int size=ArraySize(infos);
    if (size == 0) {
      Print ("  no memory leaks");
    } else {
      Print (StringFormat ("%d undeleted objects left", size));
      for (int i=0; i<size; i++) {
 Print (StringFormat ("  - %s", infos[i]));
      }
    }
    Print ("-- End Resume --");
    m_map.Clear();
  }

  Cdbg_heap_obj_trace* location_recorder(const int line, const string filename) {
    m_line = line;
    m_filename = filename;
    return(GetPointer(this));
  }

  template <typename V>
  V* operator=(V* p_in) {
    string info = StringFormat ("File %s Line %d", m_filename, m_line);
    if (!m_map.Add (StringFormat("%x",p_in), info)) {
      Print (StringFormat ("%s ERROR m_map.Add", __FUNCTION__));
    }
    return p_in;
  }

  template <typename V>
  V* operator-(V* p_in) {
    string desc = StringFormat("%x",p_in);
    if (!m_map.ContainsKey(desc)) {
      Print (StringFormat ("ERROR at delete: Object %s not found!", desc));
      return p_in;
    }
    m_map.Remove (desc);
    return p_in;
  }

} dbg_heap_obj_trace;
# 2 "little_script.mq5" 2

class CA {
};
void OnStart() {
   CA *a;
   a = dbg_heap_obj_trace.location_recorder(6, "little_script.mq5") = new CA;
   if (a == NULL) {
     Print("NULL Pointer!");
     return;
   }
   delete dbg_heap_obj_trace - a;
}

Please see the two bold marked lines

This is for clarity.

Matthias


PS: cpp is part of the GNU compiler collection of cygwin

 
Dr Matthias Hammelsbeck #:

Hi,

just for clarity and better understanding.

In contribution #6 of this thread I presented my version of an include file for checking and identifying memory leaks. Let us name this file "check_for_memory_leaks.mqh".

The following little script with name "little_script.mq5" uses this header file:

Now I want to preprocess the source code by the following command:

cpp little_script.mq5 -E

The output is

Please see the two bold marked lines

This is for clarity.

Matthias


PS: cpp is part of the GNU compiler collection of cygwin

Nice displaying.

I was thinking to integrate a object search function for manual identification....

Also, I think it could be interesting to print out IDs for all objects that have not been deleted as a CSV line in the journal.

Then this line could be used as input to the mem leak finder to make it "DebugBreak" when this specific ID is being created, in a second run. - I think it could make debugging much easier, because the debugger would halt when this object is created and the surrounding circumstances could be analyzed.

I hope my explanation was understandable.

BTW, how did you make GCC interpret a .mq5 file as a c/c++ file? I haven't been able to make use of the preprocessor like you did. I tried with clang and GCC...
 
Dominik Egert #:

BTW, how did you make GCC interpret a .mq5 file as a c/c++ file? I haven't been able to make use of the preprocessor like you did. I tried with clang and GCC...

Neither gcc nor g++ work with extension .mq5; but cpp does! God knows why

 
Dr Matthias Hammelsbeck #:

Neither gcc nor g++ work with extension .mq5; but cpp does! God knows why

Its CPP... Oh, thank you for sharing.

You like that macro magic trick to substitute/inject code into given source files, don't you. But you are also already seeing the dangers/issues/hidden errors it can bring.

I had spent hours debugging code with a hidden and unconscious substitution to find a typo...


 
Dominik Egert #:
Its CPP... Oh, thank you for sharing.

You like that macro magic trick to substitute/inject code into given source files, don't you. But you are also already seeing the dangers/issues/hidden errors it can bring.

I had spent hours debugging code with a hidden and unconscious substitution to find a typo...


Thank for the tip. Yes I know about the dangers/issues you mentioned. That is why I use macros very seldom and preferentially only during the development and testing stage of a project.

And I'm using the statement   "cpp <file> -E"   for preprocessing the source code in order to see the real code.

I try to avoid these techniques during the life stage with real money...


Matthias


BTW: In the header file   " check_for_memory_leaks.mqh"   I removed/outcommented the first line   "#include <Generic/HashMap>"   before calling  cpp...

 
Dr Matthias Hammelsbeck #:

Thank for the tip. Yes I know about the dangers/issues you mentioned. That is why I use macros very seldom and preferentially only during the development and testing stage of a project.

And I'm using the statement   "cpp <file> -E"   for preprocessing the source code in order to see the real code.

I try to avoid these techniques during the life stage with real money...


Matthias


BTW: In the header file   " check_for_memory_leaks.mqh"   I removed/outcommented the first line   "#include <Generic/HashMap>"   before calling  cpp...

Yes. - Do you want to publish this in Code-Base maybe?? For me this is fine, you may go ahead, if you wish to do so.... - Maybe you would claim GPLv2 license on it. Thats what I do with my published code.
 
Dominik Egert #:
Yes. - Do you want to publish this in Code-Base maybe?? For me this is fine, you may go ahead, if you wish to do so.... - Maybe you would claim GPLv2 license on it. Thats what I do with my published code.

I think about it.

 
Dominik Egert #:
Yes. - Do you want to publish this in Code-Base maybe?? For me this is fine, you may go ahead, if you wish to do so.... - Maybe you would claim GPLv2 license on it. Thats what I do with my published code.

Please see https://www.mql5.com/en/code/45873

This is my first publication, may be clumsy 

Reporting Memory Leaks in Strategy Tester
Reporting Memory Leaks in Strategy Tester
  • www.mql5.com
Monitoring of memory leaks in the strategy tester
 
Dr Matthias Hammelsbeck #:

Please see https://www.mql5.com/en/code/45873

This is my first publication, may be clumsy 

You should post it as library. Aside of that, looks good.

Edit:
What about author and license, don't you want to add that as header to the file?