Skip to content
This repository has been archived by the owner on Feb 1, 2021. It is now read-only.

GSL::Vector::View usage is not safe, crashes Ruby #21

Open
rbalint opened this issue Jun 11, 2015 · 6 comments
Open

GSL::Vector::View usage is not safe, crashes Ruby #21

rbalint opened this issue Jun 11, 2015 · 6 comments

Comments

@rbalint
Copy link

rbalint commented Jun 11, 2015

Hi,
From https://www.gnu.org/software/gsl/manual/html_node/Vector-views.html :

A vector view is a temporary object, stored on the stack, which can be used to operate on a subset of vector elements. Vector views can be defined for both constant and non-constant vectors, using separate types that preserve constness. A vector view has the type gsl_vector_view and a constant vector view has the type gsl_vector_const_view. In both cases the elements of the view can be accessed as a gsl_vector using the vector component of the view object. A pointer to a vector of type gsl_vector * or const gsl_vector * can be obtained by taking the address of this component with the & operator.

When using this pointer it is important to ensure that the view itself remains in scope—the simplest way to do so is by always writing the pointer as &view.vector, and never storing this value in another variable.

The following simple test demonstrates the problem:

require 'gsl'
GC.stress = true
x = (1..100000).to_gsl_vector[(0..-1)]
p x

Result:

/home/rbalint/interp-gsl-vector-gone.rb:5: [BUG] Segmentation fault at 0x007f6509358010
ruby 2.1.5p273 (2014-11-13) [x86_64-linux-gnu]

-- Control frame information -----------------------------------------------
c:0004 p:---- s:0011 e:000010 CFUNC  :inspect
c:0003 p:---- s:0009 e:000008 CFUNC  :p
c:0002 p:0045 s:0005 E:000f90 EVAL   /home/rbalint/interp-gsl-vector-gone.rb:5 [FINISH]
c:0001 p:0000 s:0002 E:000f78 TOP    [FINISH]

-- Ruby level backtrace information ----------------------------------------
/home/rbalint/interp-gsl-vector-gone.rb:5:in `<main>'
/home/rbalint/interp-gsl-vector-gone.rb:5:in `p'
/home/rbalint/interp-gsl-vector-gone.rb:5:in `inspect'

-- C level backtrace information -------------------------------------------
/usr/lib/x86_64-linux-gnu/libruby-2.1.so.2.1(+0x18a837) [0x7f650903e837]

I think rb-gsl should not expose GSL views because it seems to be impossible to implement it properly.

@blackwinter
Copy link
Owner

Thanks, I'll look into it.

@rbalint
Copy link
Author

rbalint commented Jun 15, 2015

To correct myself if it is not impossible to implement views, but hard due to some parts are stored on the stack. They can be moved to heap, but this is not trivial.

@blackwinter
Copy link
Owner

Hi Balint,

I'm sorry, but I have to retract my earlier statement. At the moment, I don't have time to work on this library. I only created this fork to add support for newer Ruby and GSL versions and I'm not familiar with the inner workings of this code or GSL. I can give you commit access if you want and assist you in any way I can.

Cheers,
Jens

@rbalint
Copy link
Author

rbalint commented Jun 20, 2015

Hi Jens,
Sorry, but I'm not familiar with the codebase either and I'm not sure if I can find time for fixing this problem in the near future. :-(
If I come up with something useful I'll submit a pull request.
Cheers,
Balint

@blackwinter
Copy link
Owner

Sure, I totally understand. I'm no longer working on this library, so I leave it to the new maintainer(s) to decide what to do about this issue.

@rbalint
Copy link
Author

rbalint commented Jun 23, 2015

To help people using ruby-gsl in the meantime if you keep the vector in scope in does not get GC-ed and the program works properly.

$ cat interp-gsl-vector-gone.rb
require 'gsl'
GC.stress = true
in_scope_vector = (1..100000).to_gsl_vector
x = in_scope_vector[(0..-1)]
p x
$ ruby /home/rbalint/interp-gsl-vector-gone.rbGSL::Vector::View
[ 1.000e+00 2.000e+00 3.000e+00 4.000e+00 5.000e+00 6.000e+00 7.000e+00 ... ]
$

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants