Your SlideShare is downloading. ×
0
it’s only abuse if it crashes
the art of low-level ruby and other macabre tales


Eleanor McHugh
http://slides.games-with-...
with Kernel.syscall
process 1                                            process 2

  require ‘fcntl’                     ...
or the ruby/dl way
  require ‘dl’
  require ‘fcntl’
  LIBC = DL::dlopen ‘libc.dylib’
  open = LIBC[‘sem_open’, ‘ISII’]
  t...
ruby + malloc = fun
require ‘dl’

memory_buffer = DL::malloc 20
=> #<DL::PtrData:0x2d0870 ptr=0x820600 size=20 free=0x1b02...
and frustration
string = “hello ruby”
memory_buffer = string.to_ptr
=> #<DL::PtrData:0x41bea0 ptr=0x41be60 size=10 free=0x...
but we can fix that?
Signal.trap(:SEGV) { $stderr.puts "segfault triggered" }
Process.kill :SEGV, 0
$stderr.puts "but I car...
maybe with some tenderlove
require 'dl'
require ‘neversaydie’
memory = DL::malloc 1
4096.times do |i|
 begin
   puts "#{i}...
but what I really want
require 'dl'
SIGSEGV = DL::dlopen('libsigsegv.dylib')
install_handler = SIGSEGV['sigsegv_install_ha...
further reading
 http://www.jbrowse.com/text/rdl_en.html

 http://www.ruby-lang.org/en/downloads/

 http://slides.games-wi...
Upcoming SlideShare
Loading in...5
×

it's only abuse if it crashes

1,018

Published on

Lightning talk on Ruby/DL and Segfaults

Published in: Technology, Health & Medicine
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,018
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
18
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "it's only abuse if it crashes"

  1. 1. it’s only abuse if it crashes the art of low-level ruby and other macabre tales Eleanor McHugh http://slides.games-with-brains.net/
  2. 2. with Kernel.syscall process 1 process 2 require ‘fcntl’ Open, Wait, TryWait, Post = 268, 271, 272, 273 Open, Wait, Post, Close = 268, 271, 273, 269 s = syscall Open, “/tmp/s” s = syscall Open, “/tmp/s”, Fcntl::O_CREAT, 1911 begin syscall Wait, s t = Time.now puts “locked at #{Time.now}” syscall TryWait, s sleep 50 puts “locked at #{t}” puts “posted at #{Time.now}” rescue Exception => e syscall Post, s puts “busy at #{t}” syscall Close, s syscall Wait, s puts “waited #{Time.now - t} seconds” end produces: produces: locked at Thu May 28 01:03:23 +0100 2009 busy at Thu May 28 01:03:36 +0100 2009 posted at Thu May 28 01:04:13 +0100 2009 waited 47.056508 seconds
  3. 3. or the ruby/dl way require ‘dl’ require ‘fcntl’ LIBC = DL::dlopen ‘libc.dylib’ open = LIBC[‘sem_open’, ‘ISII’] try_wait = LIBC[‘sem_trywait’, ‘II’] wait = LIBC[‘sem_wait’, ‘II’] post = LIBC[‘sem_post’, ‘II’] close = LIBC[‘sem_close’, ‘II’] process 1 process 2 s = open.call(“/tmp/s”, Fcntl::O_CREAT, 1911)[0] s = open.call(“/tmp/s”) wait.call s t = Time.now puts “locked at #{Time.now}” if try_wait.call(s)[0] == 0 then sleep 50 puts “locked at #{t}” puts “posted at #{Time.now}” else post.call s puts “busy at #{t}” close.call s wait.call s puts “waited #{Time.now - t} seconds” => locked at Thu May 28 01:03:23 +0100 2009 end => posted at Thu May 28 01:04:13 +0100 2009 => busy at Thu May 28 01:03:36 +0100 2009 => waited 47.056508 seconds
  4. 4. ruby + malloc = fun require ‘dl’ memory_buffer = DL::malloc 20 => #<DL::PtrData:0x2d0870 ptr=0x820600 size=20 free=0x1b0257> memory_buffer[0] = “hello world!” => “hello world!000000000000000000000000" memory_buffer.free => #<DL::Symbol:0x40b760 func=0x1b0257 'void (free)(void *);'> memory_buffer.nil => nil
  5. 5. and frustration string = “hello ruby” memory_buffer = string.to_ptr => #<DL::PtrData:0x41bea0 ptr=0x41be60 size=10 free=0x1b0257> memory_buffer[0] = “goodbye world” memory_buffer += 1 => #<DL::PtrData:0x422000 ptr=0x41be61 size=9 free=0x0> puts memory_buffer, memory_buffer.to_str, string => “oodbye world” => “oodbye wo” => “hello ruby” memory_buffer -= 1 => (irb):51: [BUG] Segmentation fault
  6. 6. but we can fix that? Signal.trap(:SEGV) { $stderr.puts "segfault triggered" } Process.kill :SEGV, 0 $stderr.puts "but I carry on as usual" require 'dl' memory = DL::malloc 1 4096.times { |i| memory[0] = 42.chr * i } $stderr.puts "even genuine segfaults don't phase me" produces: segfault triggered but I carry on as usual
  7. 7. maybe with some tenderlove require 'dl' require ‘neversaydie’ memory = DL::malloc 1 4096.times do |i| begin puts "#{i} : #{(memory[1] = 42.chr * i).length}" rescue NeverSayDie => e $stderr.puts "even genuine segfaults don't phase me" break end end produces: even genuine segfaults don't phase me
  8. 8. but what I really want require 'dl' SIGSEGV = DL::dlopen('libsigsegv.dylib') install_handler = SIGSEGV['sigsegv_install_handler', 'IP'] deinstall_handler = SIGSEGV['sigsegv_deinstall_handler', '0'] leave_handler = SIGSEGV['sigsegv_leave_handler', 'IPPPP'] continuation = DL.callback('IPPP') do |address, b, c| raise RuntimeError, "segfault at #{address}" end handler = DL.callback('IPI') do |fault_address, serious| leave_handler.call continuation, fault_address, nil, nil end install_handler.call handler
  9. 9. further reading http://www.jbrowse.com/text/rdl_en.html http://www.ruby-lang.org/en/downloads/ http://slides.games-with-brains.net/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×