user type segfault

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

user type segfault

Paul Kienzle-2
Hi,

Here's a foolproof method of generating a segfault:

octave> x = make_int(1)
octave> clear functions
octave> x

It fails with any user defined type, since once
the oct-file is unloaded the virtual octave_value
functions are no longer available.  The following
code works around this:

  symbol_record *fn = fbi_sym_tab->lookup("myconstructor")
  fn->unprotect();
  fn->make_eternal();
  fn->make_as_static();
  fn->protect();

Now the constructor is no longer cleared so the oct-file
is no longer unloaded so the virtual functions are
still available.

I've defined lock_function(string) in variables.cc
which does this.  Call lock_function("myconstructor")
when you call mytype::register_type().

Paul Kienzle
[hidden email]

Paul Kienzle <[hidden email]>
        * variables.cc,variables.h: define lock_function which
        prevents the named DEFUN_DLD function from being cleared.

Index: variables.h
===================================================================
RCS file: /cvs/octave/src/variables.h,v
retrieving revision 1.69
diff -c -p -r1.69 variables.h
*** variables.h 2002/12/28 04:02:31 1.69
--- variables.h 2003/02/11 19:41:29
*************** extern std::string builtin_string_variab
*** 84,89 ****
--- 84,90 ----
  extern int builtin_real_scalar_variable (const std::string&, double&);
  extern octave_value builtin_any_variable (const std::string&);
 
+ extern void lock_function (const std::string&);
  extern void link_to_global_variable (symbol_record *sr);
  extern void link_to_builtin_or_function (symbol_record *sr);
 
Index: variables.cc
===================================================================
RCS file: /cvs/octave/src/variables.cc,v
retrieving revision 1.242
diff -c -p -r1.242 variables.cc
*** variables.cc 2003/01/04 03:11:42 1.242
--- variables.cc 2003/02/11 19:41:29
*************** name_matches_any_pattern (const std::str
*** 1317,1322 ****
--- 1317,1335 ----
    return retval;
  }
 
+ void
+ lock_function(const std::string& nm)
+ {
+   symbol_record *sr = fbi_sym_tab->lookup(nm,true);
+   if (sr)
+     {
+       sr->unprotect();
+       sr->make_eternal();
+       sr->mark_as_static();
+       sr->protect();
+     }
+ }
+
  static inline bool
  is_local_variable (const std::string& nm)
  {


Reply | Threaded
Open this post in threaded view
|

Re: user type segfault

Andy Adler
On Tue, 11 Feb 2003, Paul Kienzle wrote:

> Here's a foolproof method of generating a segfault:
>
> octave> x = make_int(1)
> octave> clear functions
> octave> x
>
> It fails with any user defined type, since once
> the oct-file is unloaded the virtual octave_value
> functions are no longer available.  The following
> code works around this:
>
>   symbol_record *fn = fbi_sym_tab->lookup("myconstructor")
>   fn->unprotect();
>   fn->make_eternal();
>   fn->make_as_static();
>   fn->protect();
>
> Now the constructor is no longer cleared so the oct-file
> is no longer unloaded so the virtual functions are
> still available.
>
> I've defined lock_function(string) in variables.cc
> which does this.  Call lock_function("myconstructor")
> when you call mytype::register_type().

Won't this prevent unloading of functions for those
who are doing the compile-run-debug cycle of code
development?

Is there any way then to force the unloading of
the oct file?

Andy



Reply | Threaded
Open this post in threaded view
|

user type segfault

John W. Eaton-6
In reply to this post by Paul Kienzle-2
On 11-Feb-2003, Paul Kienzle <[hidden email]> wrote:

| I've defined lock_function(string) in variables.cc
| which does this.  Call lock_function("myconstructor")
| when you call mytype::register_type().

Matlab has mlock, mislocked, and munlock.  Any objection to those
names (and implementing the other two :-)?

jwe


Reply | Threaded
Open this post in threaded view
|

Re: user type segfault

Paul Kienzle-2
In reply to this post by Andy Adler
On Tue, Feb 11, 2003 at 03:34:02PM -0500, Andy Adler wrote:
> > I've defined lock_function(string) in variables.cc
> > which does this.  Call lock_function("myconstructor")
> > when you call mytype::register_type().

This will change to mlock shortly.

> Won't this prevent unloading of functions for those
> who are doing the compile-run-debug cycle of code
> development?

I don't think it will.  Should it?  

Having live variables of a type kicking around, and
changing the definition of the type out from underneath
is bound to cause some problems.  I prefer developer-beware
in this case.

>
> Is there any way then to force the unloading of
> the oct file?

I am also defining mislocked and munlock.

It is mostly working now, but I'm going to do some
more tests before resubmitting.

- Paul


Reply | Threaded
Open this post in threaded view
|

Re: user type segfault

David Bateman-3
According to Paul Kienzle <[hidden email]> (on 02/11/03):

> On Tue, Feb 11, 2003 at 03:34:02PM -0500, Andy Adler wrote:
> > > I've defined lock_function(string) in variables.cc
> > > which does this.  Call lock_function("myconstructor")
> > > when you call mytype::register_type().
>
> This will change to mlock shortly.
>
> > Won't this prevent unloading of functions for those
> > who are doing the compile-run-debug cycle of code
> > development?
>
> I don't think it will.  Should it?  
>
> Having live variables of a type kicking around, and
> changing the definition of the type out from underneath
> is bound to cause some problems.  I prefer developer-beware
> in this case.
>
> >
> > Is there any way then to force the unloading of
> > the oct file?
>
> I am also defining mislocked and munlock.
>
> It is mostly working now, but I'm going to do some
> more tests before resubmitting.
>
> - Paul

Just one wish, is it possible to fool the register_type() call into
doing the locking? If it is then no other changes are needed in other
source files to fix this for all existing loadable types. Other each
loadable type with need to be modified to perform the locking.

Regards
David

--
David Bateman                                [hidden email]
Motorola CRM                                 +33 1 69 35 25 00 (Ph)
Espace Technologique, Commune de St Aubin    +33 1 69 35 25 01 (Fax)
91193 Gif-Sur-Yvette FRANCE

The information contained in this communication has been classified as:

[x] General Business Information
[ ] Motorola Internal Use Only
[ ] Motorola Confidential Proprietary


Reply | Threaded
Open this post in threaded view
|

Re: user type segfault

Paul Kienzle
David Bateman wrote:

>Just one wish, is it possible to fool the register_type() call into
>doing the locking? If it is then no other changes are needed in other
>source files to fix this for all existing loadable types. Other each
>loadable type with need to be modified to perform the locking.
>
Not really, or at least not nicely.

I'm guessing that the register_type call is used by the builtin types as
well, so we
will need macros in defun-dld.h to override it.  E.g.,
    inline void nop(void) {}
    #define register_type register_type(), mlock(__DLDNAME__),nop
Then
    mytype::register_type()
becomes
   mytype::register_type(),mlock(__DLDNAME__),nop()
Problem 1: register_type is a circular definition.  Is that allowed?
Problem 2: how do we define __DLDNAME__?
__DLDNAME__ can't be a C++ constant because it must exist in
the global scope.  Multiple DEFUN_DLD's in the same file would
collide.  I don't know how to define a macro within a macro.

Paul Kienzle
[hidden email]