Skip to content

fix: FFI LibC not loading on Windows#1

Merged
headius merged 1 commit intoheadius:fiddle-fixesfrom
danini-the-panini:ds-windows-fiddle-fix
Mar 13, 2017
Merged

fix: FFI LibC not loading on Windows#1
headius merged 1 commit intoheadius:fiddle-fixesfrom
danini-the-panini:ds-windows-fiddle-fix

Conversation

@danini-the-panini
Copy link
Copy Markdown

This was causing gem list to fail. Apparently, there are quite a number of libc functions and variables that are not available on Windows.

This was causing `gem list` to fail. Apparently, there are quite a number of libc functions and variables that are not available on Windows.
@headius headius merged commit ccac67e into headius:fiddle-fixes Mar 13, 2017
@danini-the-panini danini-the-panini deleted the ds-windows-fiddle-fix branch March 14, 2017 07:12
headius pushed a commit that referenced this pull request Nov 29, 2018
  1. lexically contained closures will return since it knows it is safe to do so (e.g. nonlocal -> local return conversion)
  2. other closures will copy to the return value of the method and jump to the end of the method

I believe #2 is wrong and it is not currently possible to hit with the limitations in what we will inline.  I still added it as it seemed like some code should be there to handle this scenario when/if we decide to support it.  I think the premise of what #2 does is right; but I do not see how we can guarantee where we jump to could possibly have the same variable in a return instr (or copy to some other significant variable).

For posterity, if I delete #1 and run the following script I feel this should still work but it doesn't:

```ruby
def try_fdopen()
  1.times do
    return :exit_closure
  end
  :exit_try_fdopen
end


def foo
  i = 0
  while i < 1000 do
    p try_fdopen
    i += 1
  end
end


foo
```
headius pushed a commit that referenced this pull request Sep 23, 2021
headius pushed a commit that referenced this pull request Feb 21, 2024
Using Prism through Chicory
headius added a commit that referenced this pull request May 24, 2024
This restructures the "mangled" JVM method name used for the JVM
stacktrace and mined for the Ruby backtrace to make it more
readable to normal users.

Instead of "RUBY$method$foo$1"

we get "❤ def foo #1"

The heart is the RUBY marker, def indicates a method, and the # is
the same scope numbering the JIT had before. The delimiter is a
unicode non-breaking space.

This shows in the JVM backtrace similar to these examples:

	at blah.️❤ def foo$1(blah.rb:2)
	at blah.️❤ def bar$2(blah.rb:6)
	at blah.️❤ {} go$6(blah.rb:17)
	at blah.️❤ def times$4(blah.rb:12)
	at blah.️❤ def go$5(blah.rb:17)
	at blah.️❤ {} \=\^main\_$0(blah.rb:20)
	at blah.️❤ def times$4(blah.rb:12)

But still can be parsed by the Ruby backtrace miner to produce the
proper Ruby backtrace elements.

The format of this is negotiable.
headius added a commit that referenced this pull request May 28, 2024
This restructures the "mangled" JVM method name used for the JVM
stacktrace and mined for the Ruby backtrace to make it more
readable to normal users.

Instead of "RUBY$method$foo$1"

we get "❤ def foo #1"

The heart is the RUBY marker, def indicates a method, and the # is
the same scope numbering the JIT had before. The delimiter is a
unicode non-breaking space.

This shows in the JVM backtrace similar to these examples:

	at blah.️❤ def foo$1(blah.rb:2)
	at blah.️❤ def bar$2(blah.rb:6)
	at blah.️❤ {} go$6(blah.rb:17)
	at blah.️❤ def times$4(blah.rb:12)
	at blah.️❤ def go$5(blah.rb:17)
	at blah.️❤ {} \=\^main\_$0(blah.rb:20)
	at blah.️❤ def times$4(blah.rb:12)

But still can be parsed by the Ruby backtrace miner to produce the
proper Ruby backtrace elements.

The format of this is negotiable.
headius added a commit that referenced this pull request Oct 30, 2024
This buffer is used by a few tests that wrap non-IO objects with
a duck-typed wrapper, as seen here:

  def z.read(size
    @buf ||= TestZlib.create_gzip_stream("hello")
    @buf.slice!(0, size)
  end

If this buffer is not encoded as BINARY, then the slice! call may
treat the requested length as a character count. With the buffer
using the default UTF-8 this may lead to binary bytes being
misinterpreted as prefix bytes, and the resulting slice will
contain more bytes than were requested.

This is bad form for an IO#read implementation; it should never
return more bytes than requested. A second bug in IOInputStream
blindly attempts to copy all those bytes into its buffer, resulting
in an ArrayIndexOutOfBoundsException (bug #1 in jruby#8391).

The fix here opens the StringIO using encoding: "BINARY" to ensure
the slice length can only be interpreted as a byte count, so the
read slicing never returns more than the number of bytes requested.

Partial fix for jruby#8391.
headius added a commit that referenced this pull request Oct 30, 2024
Badly-behaved #read implementations may produce String output that
exceeds the requested length, as theorized in jruby#8391. If
this code blindly attempts to copy all bytes from such a String,
it may cause an ArrayIndexOutOfBoundsError when it writes over the
end of the passed-in buffer.

This change guards against such #read implementations by raising
a hard error; we do not maintain a buffer in this class, so we
can't just hold onto the extra bytes, and we don't want to just
silently discard them. A hard error will let a user of this class
find bad #read implementations more quickly and fix the real
problem.

Fixes bug #1 from jruby#8391.
headius added a commit that referenced this pull request Oct 30, 2024
This buffer is used by a few tests that wrap non-IO objects with
a duck-typed wrapper, as seen here:

  def z.read(size
    @buf ||= TestZlib.create_gzip_stream("hello")
    @buf.slice!(0, size)
  end

If this buffer is not encoded as BINARY, then the slice! call may
treat the requested length as a character count. With the buffer
using the default UTF-8 this may lead to binary bytes being
misinterpreted as prefix bytes, and the resulting slice will
contain more bytes than were requested.

This is bad form for an IO#read implementation; it should never
return more bytes than requested. A second bug in IOInputStream
blindly attempts to copy all those bytes into its buffer, resulting
in an ArrayIndexOutOfBoundsException (bug #1 in jruby#8391).

The fix here opens the StringIO using encoding: "BINARY" to ensure
the slice length can only be interpreted as a byte count, so the
read slicing never returns more than the number of bytes requested.

Partial fix for jruby#8391.
headius added a commit that referenced this pull request Oct 30, 2024
Badly-behaved #read implementations may produce String output that
exceeds the requested length, as theorized in jruby#8391. If
this code blindly attempts to copy all bytes from such a String,
it may cause an ArrayIndexOutOfBoundsError when it writes over the
end of the passed-in buffer.

This change guards against such #read implementations by raising
a hard error; we do not maintain a buffer in this class, so we
can't just hold onto the extra bytes, and we don't want to just
silently discard them. A hard error will let a user of this class
find bad #read implementations more quickly and fix the real
problem.

Fixes bug #1 from jruby#8391.
headius added a commit that referenced this pull request Oct 30, 2024
This buffer is used by a few tests that wrap non-IO objects with
a duck-typed wrapper, as seen here:

  def z.read(size
    @buf ||= TestZlib.create_gzip_stream("hello")
    @buf.slice!(0, size)
  end

If this buffer is not encoded as BINARY, then the slice! call may
treat the requested length as a character count. With the buffer
using the default UTF-8 this may lead to binary bytes being
misinterpreted as prefix bytes, and the resulting slice will
contain more bytes than were requested.

This is bad form for an IO#read implementation; it should never
return more bytes than requested. A second bug in IOInputStream
blindly attempts to copy all those bytes into its buffer, resulting
in an ArrayIndexOutOfBoundsException (bug #1 in jruby#8391).

The fix here opens the StringIO using a BINARY encoding to ensure
the slice length can only be interpreted as a byte count, so the
read slicing never returns more than the number of bytes requested.

Partial fix for jruby#8391.
headius added a commit that referenced this pull request Oct 30, 2024
Badly-behaved #read implementations may produce String output that
exceeds the requested length, as theorized in jruby#8391. If
this code blindly attempts to copy all bytes from such a String,
it may cause an ArrayIndexOutOfBoundsError when it writes over the
end of the passed-in buffer.

This change guards against such #read implementations by raising
a hard error; we do not maintain a buffer in this class, so we
can't just hold onto the extra bytes, and we don't want to just
silently discard them. A hard error will let a user of this class
find bad #read implementations more quickly and fix the real
problem.

Fixes bug #1 from jruby#8391.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants