How to work out the cause of a STORE error

Debugging, Caché

Hi,

I have a process that is importing lots of data from an external file, but every now and then I come across a STORE error.

I know that the STORE error is occurring in the %Save method of the class but I know very little else and I think its something to do with a lage amounts of Related Objects.

Is there a method of finding out more information regarding this error i.e. which actual object was being saved etc etc.

Thanks

Jim

  • 0
  • 0
  • 823
  • 3
  • 5

Answers

Well, you have a version 2012.1, and this version was a last one where we have a limit for memory per process something about 48MB, while by default just only 16Mb. But beginning from 2012.2, by default we have about 260Mb and this value can be increased, but I would not recommend doing so.

A few suggestions:

- Set up an error trap and log the error to the application error log (do BACK^%ETN). The log will give more details about the <STORE> error, including the line of code from where it was thrown.

- Use ZWRITE to write out all of the local variables in the process partition. The output may offer clues as to what is using most of the available memory.

- Use the $STORAGE variable to determine the number of bytes available for local variable storage in the current process partition.

Please contact the Worldwide Response Center if you need further assistance debugging the error. We may need to have a look at your import code to better assist you.

Once your process receives a <STORE> error, it is almost out of memory. It is almost too late for the process to do any self-analysis as to the source of its problem. Still, if you use InterSystems ^%ETN error trap, you might have local variables, and they may show a pattern of waste.

If you believe you know approximately where your local variable waste is located, you can add debug statements like:

SET ^%DEBUG($JOB,$I(^%DEBUG))=$ZDT($H,3,1)_" Now at mumble "_$S

A more advanced approach is to run the code under trace, watching $STORAGE change with each line. Like this:

USER>SET f="/Users/salzer/Desktop/storage.txt"
USER>ZBREAK TRACE:all:f
USER>ZBREAK $:"T"::"WRITE $STORAGE"
USER>DO ^MEMORYLEAK
USER>ZBREAK /TRACE:OFF

Doing this your application will run rather slow. But if it is a batch load, that is fine. Batch loaders don't usually include time-outs. The result is a file that traces your application application and the memory it uses. Here is the start of a program to analyse that trace:

ZSTORE   ; SRS 2016-11-16
   KILL ^||ZSTORE
   SET f="/Users/salzer/Desktop/storage.txt"
   CLOSE f OPEN f:"RS":1 IF '$TEST { WRITE !,"Can't open ",f QUIT }
   USE f SET label="",last=0
   TRY {
     FOR i=0:1 {
       READ x
       IF x["Trace: ZBREAK at " { SET label=$EXTRACT(x,18,*) CONTINUE }
       IF last>0 {
         SET used=x-last,^||ZSTORE(label,$INCREMENT(^||ZSTORE))=used
       }
       SET last=+x
     }
   }
   CATCH err { }
   CLOSE f
   SET label="" WHILE 1 {
     SET label=$ORDER(^||ZSTORE(label)) IF label="" { QUIT }
     WRITE !,label
     SET i="",np=0 FOR n=0:1 {
       SET i=$ORDER(^||ZSTORE(label,i),1,v) IF i="" { QUIT }
       IF v'>0 { CONTINUE }
       IF np=0 { SET min=v,max=v,sum=v,np=1 CONTINUE }
       SET np=np+1
       IF v<min { SET min=v }
       IF v>max { SET max=v }
       SET sum=sum+v
     }
     WRITE " hits:",n IF np'>0 { CONTINUE }
     WRITE " positive:",np," min:",min," max:",max," avg:",sum/np
   }
   QUIT

Comments

Hi, my apologies. I should have mentioned that we are using Cache 2012.1 for Linux.

Thank you ever so much for all of your replies. They are really helpful.

 

I have been given so many useful tips that Ive solved the problem now.

 

Thank you.

 

Jim