On 2017-07-16 11:43+0100 Phil Rosenberg wrote:

Hi Alan et al

Please find attached some patches that show some bare bones start to using
setjmp and longjmp exception style error handling in plplot. Please have a
look at the log for a detailed description of what is going on and how it
works.

What this is: A first start with enough code to show the basic principles
of how this could work.

What this isn't: A fully working version that should go anywhere near the
actual repo. I have only tested to see if it compiles, builds and that x00c
runs. In fact I get some tcl related exception on exit, which I'm not sure
if I just caused or if it was there before.

I am sending out this super early untested code that may still have major
bugs and is based on whatever (quite old) plplot source I happened to have
on my machine so that you can see the PRINCIPLES of how it works. And
because I have other stuff on today so I might not get chance to look at
this for a while and I know Alan was keen to see something asap. So feel
free to be critical, but please not too critical :-)

Alan, have a look, have a play. Thoughts welcome.

Hi Phil:

Thanks for responding so far beyond my request.

I used "git am" apply your first two commits (which should be handled
as a separate topic) cleanly to a private topic branch I created here
called "memory_allocation".  That clean result was based on the tip of the 
current
master branch.

I similarly applied your four commits cleanly to a private topic branch which
I call "exception_handling".  i.e., I assumed for this topic branch
the memory_allocation topic would be merged before the exception
handling part of your commits, although I doubt that would be actually
necessary, i.e., both these topics are completely independent of each
other.

I extensively tested your "memory_allocation" topic as follows.

I configured cmake with the option -DVALGRIND_ALL_TESTS=ON and built
the test_c_psc target (which builds all our c standard examples
for the psc device and runs them all using valgrind).  Those
valgrind reports were perfect, i.e., the list of such
reports without the phrases "no leaks are possible" and "0 errors from 0
contexts") is empty as can be seen from

software@raven> ls examples/*.log
examples/valgrind.x00c.psc.log  examples/valgrind.x11c.psc.log  
examples/valgrind.x22c.psc.log
examples/valgrind.x01c.psc.log  examples/valgrind.x12c.psc.log  
examples/valgrind.x23c.psc.log
examples/valgrind.x02c.psc.log  examples/valgrind.x13c.psc.log  
examples/valgrind.x24c.psc.log
examples/valgrind.x03c.psc.log  examples/valgrind.x14c.psc.log  
examples/valgrind.x25c.psc.log
examples/valgrind.x04c.psc.log  examples/valgrind.x15c.psc.log  
examples/valgrind.x26c.psc.log
examples/valgrind.x05c.psc.log  examples/valgrind.x16c.psc.log  
examples/valgrind.x27c.psc.log
examples/valgrind.x06c.psc.log  examples/valgrind.x17c.psc.log  
examples/valgrind.x28c.psc.log
examples/valgrind.x07c.psc.log  examples/valgrind.x18c.psc.log  
examples/valgrind.x29c.psc.log
examples/valgrind.x08c.psc.log  examples/valgrind.x19c.psc.log  
examples/valgrind.x30c.psc.log
examples/valgrind.x09c.psc.log  examples/valgrind.x20c.psc.log  
examples/valgrind.x31c.psc.log
examples/valgrind.x10c.psc.log  examples/valgrind.x21c.psc.log  
examples/valgrind.x33c.psc.log

and the empty results from

software@raven> grep -L "no leaks are possible" examples/valgrind.x??c.psc.log
software@raven> grep -L "0 errors from 0 contexts" 
examples/valgrind.x??c.psc.log

Furthermore, I like what you have done with plmalloc, plrealloc, and
plfree where if inside those routines malloc, realloc, or free
respectively fail, plexit is called with appropriate error message.
Assuming, then you want to replace all our current direct calls to
malloc, realloc and free with these pl* variants, this solves a major
problem we have which was all the wide range of different treatments
of how malloc, realloc and free errors were checked, i.e., in the best
cases plexit is called, but more usually no error checking is done at
all!

So this is a most encouraging result.

However, there are some issues with this topic branch that I noticed

* This approach should be extended to calloc as well.

* You are not finished, e.g., I notice many direct calls to malloc
  still within our code base.

* The following two compile warnings need to be addressed:

[ 18%] Building C object src/CMakeFiles/plplot.dir/plcore.c.o
cd /home/software/plplot/HEAD/build_dir/src && /usr/lib/ccache/cc  
-DPLPLOT_HAVE_CONFIG_H -DUSINGDLL -Dplplot_EXPORTS -I/home/
software/plplot/HEAD/plplot.git/include 
-I/home/software/plplot/HEAD/plplot.git/lib/qsastime 
-I/home/software/plplot/HEAD/buil
d_dir -I/home/software/plplot/HEAD/build_dir/include  -O3 -fvisibility=hidden 
-Wuninitialized -fPIC    -I/usr/include -o CMake
Files/plplot.dir/plcore.c.o   -c 
/home/software/plplot/HEAD/plplot.git/src/plcore.c
/home/software/plplot/HEAD/plplot.git/src/plcore.c: In function 
‘plinitialisememorylist’:
/home/software/plplot/HEAD/plplot.git/src/plcore.c:117:9: warning: ignoring 
return value of ‘realloc’, declared with attribute warn_unused_result 
[-Wunused-result]
         realloc( pls->memorylist, n * sizeof ( void* ) );
         ^
/home/software/plplot/HEAD/plplot.git/src/plcore.c: In function ‘plmalloc’:
/home/software/plplot/HEAD/plplot.git/src/plcore.c:140:9: warning: ignoring 
return value of ‘realloc’, declared with attribute warn_unused_result 
[-Wunused-result]
         realloc( pls->memorylist, n * sizeof ( void* ) );
         ^

* Once you feel you have completed development of this private topic
  branch, then you should test it like I did above (assuming you have
  good access to a Linux box or I could do that testing if you like
  when the time comes), and assuming all the valgrind results are
  still clean, then you should merge it to the master branch
  completely independent of what happens with your exception handling
  topic branch.

That finishes the memory allocation topic, and I now want to move
on to the exception handling topic.

For that topic branch I built the x00c and ps targets OK (except for
the memory allocation branchh code warnings I mentioned above), but
that result segfaulted at run time, e.g.,

software@raven> examples/c/x00c -dev psc -o test.psc
Segmentation fault

Here are the valgrind results for this important memory management issue

software@raven> valgrind examples/c/x00c -dev psc -o test.psc
==24594== Memcheck, a memory error detector
==24594== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==24594== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==24594== Command: examples/c/x00c -dev psc -o test.psc
==24594== ==24594== Conditional jump or move depends on uninitialised value(s)
==24594==    at 0x53F1EE5: longjmp (longjmp.c:32)
==24594==    by 0x4E840B0: c_plenv (in 
/home/software/plplot/HEAD/build_dir/src/libplplot.so.14.0.0)
==24594==    by 0x400858: main (in 
/home/software/plplot/HEAD/build_dir/examples/c/x00c)
==24594== ==24594== Warning: client switching stacks? SP change: 0xffefffdc8 --> 0x3d8d115408920055
==24594==          to suppress, use: --max-stackframe=4435220191945818765 or 
greater
==24594== Use of uninitialised value of size 8
==24594==    at 0x53F1F52: __longjmp (__longjmp.S:60)
==24594== ==24594== Jump to the invalid address stated on the next line
==24594==    at 0x3D8D115408920055: ???
==24594==  Address 0x3d8d115408920055 is not stack'd, malloc'd or (recently) 
free'd
==24594== ==24594== ==24594== Process terminating with default action of signal 11 (SIGSEGV)
==24594==  Bad permissions for mapped region at address 0x3D8D115408920055
==24594==    at 0x3D8D115408920055: ???
==24594== Use of uninitialised value of size 8
==24594==    at 0x4A236C0: _vgnU_freeres (vg_preloaded.c:58)
==24594== ==24594== Invalid write of size 8
==24594==    at 0x4A236C0: _vgnU_freeres (vg_preloaded.c:58)
==24594==  Address 0x3d8d11540892004d is not stack'd, malloc'd or (recently) 
free'd
==24594== ==24594== ==24594== Process terminating with default action of signal 11 (SIGSEGV)
==24594==  General Protection Fault
==24594==    at 0x4A236C0: _vgnU_freeres (vg_preloaded.c:58)
==24594== ==24594== HEAP SUMMARY:
==24594==     in use at exit: 76,682 bytes in 288 blocks
==24594==   total heap usage: 360 allocs, 72 frees, 124,441 bytes allocated
==24594== ==24594== LEAK SUMMARY:
==24594==    definitely lost: 0 bytes in 0 blocks
==24594==    indirectly lost: 0 bytes in 0 blocks
==24594==      possibly lost: 0 bytes in 0 blocks
==24594==    still reachable: 76,682 bytes in 288 blocks
==24594==         suppressed: 0 bytes in 0 blocks
==24594== Rerun with --leak-check=full to see details of leaked memory
==24594== ==24594== For counts of detected and suppressed errors, rerun with: -v
==24594== Use --track-origins=yes to see where uninitialised values come from
==24594== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
Segmentation fault

So you need to address this before we can do any extensive run-time testing
of your exception handling ideas.  Of course, you did warn us that
this code was quite preliminary so issues like above are to be
expected. Furthermore, in my view, discussion of real code developers
can try for themselves always beats discussion of code that doesn't
exist yet. So I very much appreciate you supplying us with this
preliminary exception handling code to focus our further discussion.

I do have some general points to make from just looking at the broad
picture of what you are trying to accomplish here with the exception
handling macros PLTRY, PLCATCH, PLENDTRY, and PLTHROW.

* There is currently no ability for PLTHROW to propagate an error message. Is
  that a fundamental limitation of setjmp/longjmp based C exception
  handling or could that feature be easily implemented?  If the latter,
  then that gives us the option to use PLTHROW wherever errors occur
  rather than always calling plexit which then prints the error
  message before it uses PLTHROW.  So for example in plmalloc,
  plcalloc, plrealloc, and plfree you could use PLTHROW directly
  rather than calling plexit. However, if implementation of handling
  error messages for PLTHROW is difficult/impossible, then I would be
  content to call plexit everywhere so that there would only be one
  PLTHROW (within plexit after printing out the error message) in our
  code as now on this topic branch.

* Can you explain why you have implemented all the PLTRY blocks
  in src/plvpor.c (with presumably the idea in mind to use PLTRY
  in a lot more places?)  Wouldn't it be better to use just one
  PLTRY block?  For example, could you get away with just that one PLTRY
  block in the library initialization code? If so, the corresponding
  PLCATCH block there could write out a message saying you reached
  that catch block (to confirm that the whole exception handling system is
  fundamentally working within our C library), and then exit (for now)
  in just that one place rather than doing nothing about whatever
  PLplot library error was detected.

* I suggest you protect your exception handling code (but not the
  separate topic branch code concerning pl* versions of malloc,
  calloc, realloc, and free) with an PL_IMPLEMENT_EXCEPTION_HANDLING
  macro that is controlled (using #cmakedefine in plplot_config.h.in)
  by a cmake option in cmake/modules/plplot.cmake of the same name
  which defaults to OFF and which is self-documented as highly
  experimental. Once you do this, then it makes it possible to merge
  this topic quite rapidly to master (to facilitate further
  collaborative development of our exception handling system) since
  the user would have to go out of their way to set
  -DPL_IMPLEMENT_EXCEPTION_HANDLING=ON once they found
  PL_IMPLEMENT_EXCEPTION_HANDLING in CMakeCache.txt. And that file
  includes the self-documentation of each option so it should be
  obvious to such users that turning that option ON is highly
  experimental.

Alan
__________________________
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net); the Time
Ephemerides project (timeephem.sf.net); PLplot scientific plotting
software package (plplot.sf.net); the libLASi project
(unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
and the Linux Brochure Project (lbproject.sf.net).
__________________________

Linux-powered Science
__________________________

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel

Reply via email to