Application Hangs

LegacyForumLegacyForum Posts: 1,669 ✭✭
edited December 2016 in Insure++
There are times when running an executable that was built
with Insure++ that it appears to "hang".

Let us first characterize what "hanging" could be.

i.e.
Is it consuming CPU time?
Is it consuming all available RAM and swapping to disk?
Does it appear to be stuck in some kind of endless loop?
Does it appear to be deadlocked?
Or is this just exceedingly slow?

On Unix systems, you can use utilities like "top" and "ps" to
determine if it is consuming CPU time or exhausting available
RAM. On windows you can use the task manager to do the same thing.

Prior to starting the application if you add the option

insure++.symbolbanner on

to either your .psrc file(Unix) or under the insure control panel's
advanced tab(windows).

When you start you application up it will put out information
about what it is reading symbol table information about what
it's reading symbol table information from

Reading symbols for a.out... done.
Reading symbols for libpthread.so.0... done.
...

It will do that for the executable itself followed by it's dependent
libraries. This may take some time to go through all of it's
dependencies but you would see what it is going through as it
is going through them.

This is one of the most time consuming tasks insure goes through
at startup. Because of this what insure does is to cache this
symbol table information. So that on subsequent runs it will not
have to reread symbol table information for a library that has
not changed. This means the very first run of a large executable
that has dependencies on numerous libraries can take a significant
amount of time to start up but the next time you run it the startup
will be much faster.

If the performance hit that you are seeing does not occur during
this symbol table reading phase but some time after it. Then the
best thing to do would be to determine what is taking place at
the point where the greatest performance degradation is observed.

You can do that by attaching to the running process using your
systems debugger and checking the stack trace of what it's trying
to do at that point. If you get a few snapshots of the stack trace
each about a minute apart during this "hanging" phase those stack
trace snapshots would let us know what your executable is trying
to do as well as what insure is trying to do. It will also tell us
whether this is deadlocked in an endless loop or crawling along
at a snails pace.

This information would allow us to make an informed decision
about what is the best way to improve performance.

Some options that may improve performance for your are:

-----------
insure++.leaksearch off
insure++.suppress LEAK*
insure++.summarize leaks bugs outstanding

in your .psrc file. What these options will do is

The leaksearch option is set to on by default and this tells
insure that whenever it sees a pointer to memory that "may"
have leaked it searches through all of memory to confirm whether
or not it really has leaked or if the pointer may have just moved.
This is to keep insure from reporting something as leaked only
to find out later during execution that this is not truly leaked.
The catch to turning this option off is that you would not be
performing this double check so you may get some leaks reported
at runtime that we should not be reporting as leaks at all.
Which is where the "suppress LEAK*" option comes in.
This will suppress leaks from being reported at runtime but
neither of these options has any effect on getting the leaks
reported in the leak summary which is created after exit() has been
called. This is what the "summarize" option is for to tell
insure to create these summaries. The only concern of getting the
summaries created it is you have to be sure to exit cleanly if
you were to just kill the process you would not be able to get
these summaries.
-----------

insure++.checkinguninit off

This turns off full uninitialized memory checking,
pointers will still be checked, but not other types of variables.
-----------

insure++.signalignore all

This tells Insure++ not to trap signals. This has greatly
improved performance of GUI programs in many cases.
-----------

insure++.coveragemapdata off
insure++.coveragelogdata off

This turns off coverage analysis data gathering. Insure's error
checking will still be performed but you would not be able to
use the TCA tool with this set.
-----------

insure++.reportfile <some file name>

This will tell insure to send output to a file rather than to
the gui. This will eliminate the time it takes for insure to
format the output it puts out for the gui. It also will eliminate
the memory consumption of the gui itself.
-----------

insure++.demangle off

This turns off demangling of C++ function names in stack traces.
This can greatly speed up the generation of leak summary reports.
Depending on the compiler involved this could require a separate
system call to execute the compilers demangler for each C++
mangled name.

If you do this I would recommend sending output to a file as you
can then use the compilers demangler to demangle the entire report
all at once.
Like:

cat errorreport.txt | c++filt | more
-----------

insure++.ignorewild on

Alot of the time what you've got involved is things you really
don't build yourself. If insure sees things in there that is
questionable that for some reason it can not see enough details
about it then it will report them as wild. By turning this option
off it will essentially filter out some of the stuff that you
really don't have any control over and it will make your error
report alot easier for you to go through. The only catch to this
is it's possible for a writewild error to cause a core dump and
if this is turned off you wouldn't see it reported but this is
just a runtime option so if you did get a core dump and nothing
reported that could be the caused it you could always just
comment out that line in your .psrc file(with a '#' sign) and rerun.
-----------

insure++.fileignore <your source file name>

If you notice that most of the time is spent in executing
methods all coming from a certain file you can tell insure
not to instrument that particular file. This option during
compile time tells insure to not bother instrumenting this
file and instead to just pass this on directly to the compiler.
The limitation being that this file will only be checked at
the object level so some error that are in this file could
go undetected.
-----------

insure++.functionignore <your function name>

If you've observed a significant amount of time is spent in
one particular function you can tell insure to not add it's
instrumentation into that particular function while still
instrumenting the rest of the file.

This is particularly advantageous if you have a function with
a tight spinning loop that insure may insert several checks into.
A loop with only 5 instructions in it could easily be 25
instructions with insure's instrumentation and if that loop
it iterated through thousands of times it can dramatically
affect performance.
-----------
This discussion has been closed.