Setjmp(), longjmp() in gnuplot

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Setjmp(), longjmp() in gnuplot

Timothée Lecomte
Hello !

I keep working on the wxwidgets terminal, and I am now facing a difficult problem.

When there are errors on a command line, gnuplot uses its functions int_error(token, string) to inform the user and stop parsing the command line. This function prints an error message and then calls bail_to_command_line() which is simply a wrapper for the standard longjmp(env) function. This is similar to "goto", and puts the program in its initial state by restoring the registers set in main().

As far as I understand, this would be perfect if I had not to use a separate thread for my terminal. Indeed, I want to send a command from the terminal (through a menu for example) to gnuplot. I use events defined in mouse.c, and more precisely a "command" event (which doesn't seem to be used very often, or maybe in OS/2 only). The do_event(event) is executed in my gui thread. When an error appears on the command, we obtain a longjump which is invalid for *this* gui thread... and it ends with a segmentation fault.

I can't simply delete the longjump, as it is necessary to stop command line parsing. If I do it, gnuplot either seems to enter in a infinite loop or terminante with an other segfault.

Of course, there's a solution : avoid any error in commands sent from my terminal. But it's like reinventing the wheel. (These errors can be various : for example, if I write a dialog to "set xlabel", and the user enters forbidden characters; or I want to send a "replot" while it's the "test" command which has opened the terminal, etc.)

Another solution would be to build the terminal as a separate process, like x11 or os/2 ones. But I think it's not an optimal design.

So I would be pleased if somebody can give me a tip in order to deal with this issue ;-) .

On my side, I will look more thoroughly to existing code to see how things are done (by windows gui, os/2 pm, etc. )

Greetings,
Timothée


Reply | Threaded
Open this post in threaded view
|

Re: Setjmp(), longjmp() in gnuplot

Ethan Merritt
Caveat: I don't really understand how your new terminal type is supposed
to work.  So maybe I have the wrong end of the stick here...

On Friday 24 June 2005 11:45 am, Timothée Lecomte wrote:
>
> As far as I understand, this would be perfect if I had not to use a
> separate thread for my terminal. Indeed, I want to send a command from
> the terminal (through a menu for example) to gnuplot. I use events
> defined in mouse.c, and more precisely a "command" event (which doesn't
> seem to be used very often, or maybe in OS/2 only). The do_event(event)
> is executed in my gui thread. When an error appears on the command, we
> obtain a longjump which is invalid for *this* gui thread... and it ends
> with a segmentation fault.

I would think the proper fix is to re-initialize the longjump at the
start of each thread creation.  Then if you get an error it will jump
to a per-thread error handler and exit the thread cleanly.

> Another solution would be to build the terminal as a separate process,
> like x11 or os/2 ones. But I think it's not an optimal design.
> So I would be pleased if somebody can give me a tip in order to deal
> with this issue ;-) .

I might understand better if you would briefly describe the flow of
control you are trying to achieve.  What does the new terminal type do
that existing terminals do not handle already?  Is the user expected to run
gnuplot from a command line, but when 'set term wxwidgets' is selected a
separate control window appears?   Or does the user run a wrapping program
that executes gnuplot underneath with the terminal pre-set to communicate with
the wrapping layer?  

If it's the latter, then I'm not sure you even  need a new terminal type.
You may be able to use 'set term x11' and direct the output to an embedded
panel of the wrapping program (see patchset #1027032).  I'm not saying this
is the best thing to do, but I point it out as a possibility.
 


--
Ethan A Merritt       [hidden email]
Biomolecular Structure Center
Mailstop 357742
University of Washington, Seattle, WA 98195


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. <a href="http://ads.osdn.com/?ad_idt77&alloc_id492&op=click">http://ads.osdn.com/?ad_idt77&alloc_id492&op=click
_______________________________________________
gnuplot-beta mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta
Reply | Threaded
Open this post in threaded view
|

RE: Setjmp(), longjmp() in gnuplot

Nigel Nunn
In reply to this post by Timothée Lecomte

Hi Timothée,

For my gnuplot-as-library driven from wxWidgets, I replaced
bail_to_command_line() with an "extern C" routine that throws
an exception back the C++ caller.  Then I wrap calls to the
gnuplot subsystem with try/catch, e.g.,

  try {

    lib_do_line("set term wx");
    lib_do_line("set grid");
    lib_do_line("plot sin(x)");
   
    // execute an arbitrary command string
    // generated during a simulation:
    lib_do_line( cmd.c_str() );

  } catch(...)  {
    // recover
  }

Nigel


----- Original Message -----

> I keep working on the wxwidgets terminal, and I am now
> facing a difficult problem.
>
> When there are errors on a command line, gnuplot uses its
> functions int_error(token, string) to inform the user and
> stop parsing the command line. This function prints an
> error message and then calls bail_to_command_line() which
> is simply a wrapper for the standard longjmp(env) function.
> This is similar to "goto", and puts the program in its
> initial state by restoring the registers set in main().
> --- [snip] ---


_____________________________________________________________________________________
This message is intended for the addressee named and may contain confidential and
privileged information. If you are not the intended recipient please note that
any form of distribution, copying or use of this communication or the information
in it is strictly prohibited and may be unlawful. If you receive this message in error,
please delete it and notify the sender.
Keep up to date with what's happening in Australian sport. Visit www.ausport.gov.au
_____________________________________________________________________________________


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. <a href="http://ads.osdn.com/?ad_idt77&alloc_id492&op=click">http://ads.osdn.com/?ad_idt77&alloc_id492&op=click
_______________________________________________
gnuplot-beta mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta
Reply | Threaded
Open this post in threaded view
|

Re: Setjmp(), longjmp() in gnuplot

Dave Denholm
In reply to this post by Timothée Lecomte
Timothée Lecomte <[hidden email]> writes:

> Hello !
>
> I keep working on the wxwidgets terminal, and I am now facing a
> difficult problem.
>
> When there are errors on a command line, gnuplot uses its functions
> int_error(token, string) to inform the user and stop parsing the
> command line. This function prints an error message and then calls
> bail_to_command_line() which is simply a wrapper for the standard
> longjmp(env) function. This is similar to "goto", and puts the program
> in its initial state by restoring the registers set in main().
>

It is *currently* "simply a wrapper" for longjmp. A good while ago, I
went through replacing lots of explicit longjmp calls with this
wrapper, precisely so that the behaviour could be changed in a central
way if it turned out to be necessary.

> As far as I understand, this would be perfect if I had not to use a
> separate thread for my terminal. Indeed, I want to send a command from
> the terminal (through a menu for example) to gnuplot. I use events
> defined in mouse.c, and more precisely a "command" event (which
> doesn't seem to be used very often, or maybe in OS/2 only). The
> do_event(event) is executed in my gui thread. When an error appears on
> the command, we obtain a longjump which is invalid for *this* gui
> thread... and it ends with a segmentation fault.
>
> I can't simply delete the longjump, as it is necessary to stop command
> line parsing. If I do it, gnuplot either seems to enter in a infinite
> loop or terminante with an other segfault.
>


Can't you just augment / replace bail_to_command_line() to make it do
what you need ?  Or you could save the existing jmpbuffer and do
another setjmp to basically intercept the longjmp calls, letting you
do any extra work, before you longjmp back to the original setjmp
location.




dd
--
Dave Denholm              <[hidden email]>       http://www.esmertec.com


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. <a href="http://ads.osdn.com/?ad_idt77&alloc_id492&op=click">http://ads.osdn.com/?ad_idt77&alloc_id492&op=click
_______________________________________________
gnuplot-beta mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta
Reply | Threaded
Open this post in threaded view
|

Re: Setjmp(), longjmp() in gnuplot

Timothée Lecomte
In reply to this post by Ethan Merritt
Ethan Merritt wrote:

>Caveat: I don't really understand how your new terminal type is supposed
>to work.  So maybe I have the wrong end of the stick here...
>
>On Friday 24 June 2005 11:45 am, Timothée Lecomte wrote:
>  
>
>>As far as I understand, this would be perfect if I had not to use a
>>separate thread for my terminal. Indeed, I want to send a command from
>>the terminal (through a menu for example) to gnuplot. I use events
>>defined in mouse.c, and more precisely a "command" event (which doesn't
>>seem to be used very often, or maybe in OS/2 only). The do_event(event)
>>is executed in my gui thread. When an error appears on the command, we
>>obtain a longjump which is invalid for *this* gui thread... and it ends
>>with a segmentation fault.
>>    
>>
>
>I would think the proper fix is to re-initialize the longjump at the
>start of each thread creation.  Then if you get an error it will jump
>to a per-thread error handler and exit the thread cleanly.
>  
>
I have just tried it. The remaining problem is that setjmp/longjmp were
designed for C, not C++. In particular, longjmp doesn't do any extra
work needed by C++, such as deleting objects. So if I initialize the
longjump when creating my terminal thread, it doesn't delete the old
window but open a new one when longjmp is used ! However, it does not
segfault... So the solution may be to check if another window is opened
and destroy it before to continue. That doesn't seem very efficient.

>>Another solution would be to build the terminal as a separate process,
>>like x11 or os/2 ones. But I think it's not an optimal design.
>>So I would be pleased if somebody can give me a tip in order to deal
>>with this issue ;-) .
>>    
>>
>
>I might understand better if you would briefly describe the flow of
>control you are trying to achieve.  What does the new terminal type do
>that existing terminals do not handle already?  Is the user expected to run
>gnuplot from a command line, but when 'set term wxwidgets' is selected a
>separate control window appears?   Or does the user run a wrapping program
>that executes gnuplot underneath with the terminal pre-set to communicate with
>the wrapping layer?  
>
>If it's the latter, then I'm not sure you even  need a new terminal type.
>You may be able to use 'set term x11' and direct the output to an embedded
>panel of the wrapping program (see patchset #1027032).  I'm not saying this
>is the best thing to do, but I point it out as a possibility.
>  
>
I will try to explain briefly.
I write a terminal like the x11, postscript, etc. So I use the standard
gnuplot interactive command line, type "set terminal wxt" and then any
plot command makes the plot window appears, as the x11 terminal works
for example. The window is opened in a thread inside gnuplot main
process. Thus, your precedent remark is pertinent.
I want to implement extra interactivity menus or toolbar. So I want to
send commands back to the command interpreter. I do that with do_event
which is precisely written for it.

Regards
Timothée


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. <a href="http://ads.osdn.com/?ad_idt77&alloc_id492&op=click">http://ads.osdn.com/?ad_idt77&alloc_id492&op=click
_______________________________________________
gnuplot-beta mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta
Reply | Threaded
Open this post in threaded view
|

Re: Setjmp(), longjmp() in gnuplot

Ethan Merritt
On Friday 24 June 2005 01:42 pm, Timothée Lecomte wrote:

> Ethan Merritt wrote:
>
> >
> >I would think the proper fix is to re-initialize the longjump at the
> >start of each thread creation.  Then if you get an error it will jump
> >to a per-thread error handler and exit the thread cleanly.
> >  
> >
> I have just tried it. The remaining problem is that setjmp/longjmp were
> designed for C, not C++.

I see. So your new driver is C++ only?  That is already a potential
problem since the rest of the gnuplot is distinctly not C++ code.
I fear it will limit the number of platforms on which your new
driver will actually compile and link into gnuplot successfully.
We'll find out, I guess.

> So if I initialize the  
> longjump when creating my terminal thread, it doesn't delete the old
> window but open a new one when longjmp is used ! However, it does not
> segfault... So the solution may be to check if another window is opened
> and destroy it before to continue. That doesn't seem very efficient.

Can't you do the same thing as the x11 driver?  When you send a new
plot command the driver looks to see if there is an existing window and if
so uses it.  If there is no existing window then it opens a new one.
See the difference?  You check for an old window, but instead of destoying
it you just use it explicitly for the new plot also.



--
Ethan A Merritt       [hidden email]
Biomolecular Structure Center
Mailstop 357742
University of Washington, Seattle, WA 98195


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. <a href="http://ads.osdn.com/?ad_idt77&alloc_id492&op=click">http://ads.osdn.com/?ad_idt77&alloc_id492&op=click
_______________________________________________
gnuplot-beta mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta
Reply | Threaded
Open this post in threaded view
|

Re: Setjmp(), longjmp() in gnuplot

Timothée Lecomte
Ethan Merritt wrote:

>On Friday 24 June 2005 01:42 pm, Timothée Lecomte wrote:
>  
>
>>Ethan Merritt wrote:
>>    
>>
>> The remaining problem is that setjmp/longjmp were
>>designed for C, not C++.
>>    
>>
>I see. So your new driver is C++ only?
>
It is C++ only, but until now I have managed to mix C and C++ without
problems. I have added a few lines in configure.in (for both c++ and
wxwidgets), written my terminal as a common wxt.trm whith C++ functions
defined in an external wxt.cpp file.

>That is already a potential problem since the rest of the gnuplot is distinctly not C++ code.
>I fear it will limit the number of platforms on which your new
>driver will actually compile and link into gnuplot successfully.
>We'll find out, I guess.
>  
>
According to c++ documentation, it should not be a problem (provided we
have a c++ compiler for the desired platform ;-). The C and C++ files
are compiled by their respective compilers, and then the C++ one link
everything. It works at least on my machine.

>>So if I initialize the  
>>longjump when creating my terminal thread, it doesn't delete the old
>>window but open a new one when longjmp is used ! However, it does not
>>segfault... So the solution may be to check if another window is opened
>>and destroy it before to continue. That doesn't seem very efficient.
>>    
>>
>
>Can't you do the same thing as the x11 driver?  When you send a new
>plot command the driver looks to see if there is an existing window and if
>so uses it.  If there is no existing window then it opens a new one.
>See the difference?  You check for an old window, but instead of destoying
>it you just use it explicitly for the new plot also.
>  
>
I think that all this setjmp/longjmp stuff makes it difficult. I've
tried some combinations, and even if objects are not destroyed, they are
not usable ! I can't tell anything to the frame.

On the other hand, I wrote things so that when user closes the terminal
window, in fact he only hides it, so on next plot it is still available
and it is asked to unhide. But setjmp/longjmp are not the same problem
unfortunately !

Timothée

Timothée


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. <a href="http://ads.osdn.com/?ad_idt77&alloc_id492&op=click">http://ads.osdn.com/?ad_idt77&alloc_id492&op=click
_______________________________________________
gnuplot-beta mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta
Reply | Threaded
Open this post in threaded view
|

Re: Setjmp(), longjmp() in gnuplot

Timothée Lecomte
In reply to this post by Ethan Merritt
Thanks to your different points of view, I finally got it working !

Nigel has the most "C++ friendly" solution, but I think I'm not enough
experiences with exceptions to override bail_to_command_line() with them.

However, as Ethan and Dave proposed, I can do my own setjump in the
thread which is sending the command. As I can't come back from a
longjump to my gui thread (because it contains c++ objects), I simply
have to use another thread. This "worker thread" has no object, so it is
"setjmp - safe". It verifies if it is called from the longjump to avoid
sending the command again.

This way, I only need to add a test to bail_to_command_line() to call
the good longjmp().

I hope you'll find this solution convenient !

Timothée


P.S. : Here's a gift : http://tipote.free.fr/wxt2.png
A screenshot of the current state of the terminal








-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. <a href="http://ads.osdn.com/?ad_idt77&alloc_id492&op=click">http://ads.osdn.com/?ad_idt77&alloc_id492&op=click
_______________________________________________
gnuplot-beta mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta
Reply | Threaded
Open this post in threaded view
|

Re: Setjmp(), longjmp() in gnuplot

Hans-Bernhard Bröker
In reply to this post by Ethan Merritt
Ethan Merritt wrote:
> I see. So your new driver is C++ only?  That is already a potential
> problem since the rest of the gnuplot is distinctly not C++ code.
> I fear it will limit the number of platforms on which your new
> driver will actually compile and link into gnuplot successfully.

Not any more than the fact that the desired output system for that
driver being C++ already limited it.  I.e. if wxWidgets runtime and
development support exists on the box, there's nothing to stop a gnuplot
build from using them.

If there's an actual problem to be caused by this, it'll be that the
link of the entire gnuplot will now have to be done with the C++
compiler's linker presets.  I.e. we'll pull in the C++ startup code.  On
  less sane platforms, that could indeed cause trouble.


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
gnuplot-beta mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta