Possible bug: ObjectFind freezes MT5

 

Hi,

I'm developing an indicator that tries to capture drawings (thus objects) in the graph and then work with them. Since the drawings are going to have a standarized naming, I'm using a call to ObjectFind to monitor if a new object has been drawn:

bool hasDObjWithThisId(const int dObjId, const DrawObjects dObject)
{   
   switch (dObject)
   {       
        case DO_ReversionLines:
                return ObjectFind(glChartID,"RevLine_" + IntegerToString(dObjId) + "_1") >= 0;
   }
}

The call to the above function is done some times inside OnCalculate each new tick:

int OnCalculate(const int rates_total,
                ...)
{
   int startPos;
   
   const bool isCalculatingForNow = prev_calculated == rates_total;
   
   if (prev_calculated == 0)
   {
      startPos = MathMax(rates_total - 2,1); //Don't need to calculate the entire history
                
      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,startPos);
      PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,startPos);
   }
   else if (isCalculatingForNow)
   {
      //Print("Is now");
      startPos = prev_calculated - 1;
   }   
   else
   {
      //Print("New candle produced");
      startPos = prev_calculated;
   }
   
   int totObj = ObjectsTotal(glChartID);
   
   for (int aaa = startPos; aaa < rates_total && !IsStopped(); ++aaa)
   {
      BullIndicationColors[aaa] = 0;
      BearIndicationColors[aaa] = 0;
      
      setToNoOp(aaa);
      
      if (totObj == 0)
         continue;

      //
      for (int bbb = 0; bbb < MAX_DRAW_OBJECTS; ++bbb)
      {
         if (hasDObjWithThisId(bbb,DO_Channel))
            ...

So, as you can see, nothing outside of this world. Now normally the code runs fine (checked with Prints), but eventually, at least if no object is drawn, the MT5 interface just freezes and Windows returns a "Not Responding" status, forcing me to close MT5. If, by the other hand, I remove the call to hasDObjWithThisId, no freeze happens, what points out it's the call to ObjectFind that is leading to the problem.

So my conclusion is that, for whatever reason, multiple calls to this function is making MT5 crash. It is updated and I haven't found any increase an RAM or processing consumption by MT5 before the freeze starts.

So how can I solve this problem? Is it a known bug? When will it be fixed?

 
Please provide a code that compiles to reproduce the issue.
 
Martin Bittencourt:

Hi,

I'm developing an indicator that tries to capture drawings (thus objects) in the graph and then work with them. Since the drawings are going to have a standarized naming, I'm using a call to ObjectFind to monitor if a new object has been drawn:

The call to the above function is done some times inside OnCalculate each new tick:

So, as you can see, nothing outside of this world. Now normally the code runs fine (checked with Prints), but eventually, at least if no object is drawn, the MT5 interface just freezes and Windows returns a "Not Responding" status, forcing me to close MT5. If, by the other hand, I remove the call to hasDObjWithThisId, no freeze happens, what points out it's the call to ObjectFind that is leading to the problem.

So my conclusion is that, for whatever reason, multiple calls to this function is making MT5 crash. It is updated and I haven't found any increase an RAM or processing consumption by MT5 before the freeze starts.

So how can I solve this problem? Is it a known bug? When will it be fixed?

try to reduce the number of chart candles. 

 
Soewono Effendi:
try to reduce the number of chart candles. 

Well my code already does that. As you may see above, when the indicator is first loading, it doesn't check since the start of the graph, but only from the last 2 candles, and when the graph is updating, it only checks in the current candle.

 

I dont think it's in ObjectFind().

Expression is not boolean 

true
false

And not all control paths return a value.

bool hasDObjWithThisId(const int dObjId, const DrawObjects dObject)
{   
   switch (dObject)
   {       
        case DO_ReversionLines:
                return ObjectFind(glChartID,"RevLine_" + IntegerToString(dObjId) + "_1") >= 0;
   }
 return(false);
}
If possible please provide all code or a working example.
 
Marco vd Heijden:

I dont think it's in ObjectFind().

Expression is not boolean 

And not all control paths return a value.

If possible please provide all code or a working example.

wow that wasn't a complete code ^^ only the part that matters :P

 
Alain Verleyen:
Please provide a code that compiles to reproduce the issue.

Please try this (it took something between 5-10 minutes to freeze in both tests):

#property copyright "Copyright 2020"

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

//--- others
long glChartID;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   glChartID = ChartID();
   
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
//---
   int startPos;
   
   const bool isCalculatingForNow = prev_calculated == rates_total;
   
   if (prev_calculated == 0)
   {
      startPos = MathMax(rates_total - 2,1); //Don't need to calculate the entire history
   }
   else if (isCalculatingForNow)
   {
      //Print("Is now");
      startPos = prev_calculated - 1;
   }   
   else
   {
      //Print("New candle produced");
      startPos = prev_calculated; //- 1: will make it recalculate once more the previous candle
   }
   
   const int totObj = ObjectsTotal(glChartID);
   
   for (int aaa = startPos; aaa < rates_total && !IsStopped(); ++aaa)
   {      
      if (totObj == 0)
         continue;
      
      for (int bbb = 0; bbb < 40; ++bbb)
      {
         //
         if (hasDObj())
            ;
      }
   }
   
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
bool hasDObj()
{   
   return ObjectFind(glChartID,"MW_MTC_DObj_SymTri_") >= 0; //Maybe has to do with long texts, so this is a real example of text size here
}
<ex5 file deleted>
 
Martin Bittencourt:

Please try this (it took something between 5-10 minutes to freeze in both tests):

What is this ex5 ?

I run the code posted but I don't have objects on the chart, do I have to do anything more to reproduce the freeze ?

 
Martin Bittencourt:

Well my code already does that. As you may see above, when the indicator is first loading, it doesn't check since the start of the graph, but only from the last 2 candles, and when the graph is updating, it only checks in the current candle.

that's what you assume  your code does.
The root of.all bugs.

I gave you a simple effective tips to solve your issue. Did you try it  ?

Good luck any way.
Happy bug hunting.
 
Alain Verleyen:

What is this ex5 ?

I run the code posted but I don't have objects on the chart, do I have to do anything more to reproduce the freeze ?

No, the freeze don't require any drawing to happen. Just run it and wait, that's how is happening here with me.

 
Soewono Effendi:
that's what you assume  your code does.
The root of.all bugs.

I gave you a simple effective tips to solve your issue. Did you try it  ?

Good luck any way.
Happy bug hunting.

\o/ You have the part of the code where the drawing starting point is done. Have you seen any bug on it? Because I've already done dozens of indicators and always used that same structure and it always worked as I wanted :| I can't see any bugs on it. With that in mind, I thank you for your tip, but it is already 'used' so to speak: I already used the minimalistic amount of candlesticks for my indicator to function.

Reason: