Skip to content

Instantly share code, notes, and snippets.

@csfrancis
Last active August 29, 2015 14:14
Show Gist options
  • Save csfrancis/46e360d401609275246c to your computer and use it in GitHub Desktop.
Save csfrancis/46e360d401609275246c to your computer and use it in GitHub Desktop.
Cause MRI to SIGBUS
#!/usr/bin/env ruby
unless RUBY_PLATFORM.include?('linux') && File.open('/proc/sys/kernel/randomize_va_space').read.chomp != 0
puts "This script only runs on linux and requires ASLR to be enabled"
exit 1
end
def recurse(i)
[i].each { |i| recurse(i) }
end
THRESHOLD = 805306368 # 768MB
if ARGV.empty?
c = 0
min_diff = nil
trap("INT") { puts "giving up after #{c} tries"; exit 1 }
while true do
diff = `#{$0} check`.chomp.to_i
min_diff = diff unless min_diff
if diff < min_diff
puts "new minimum diff: #{diff} (#{c})"
min_diff = diff
end
unless $?.exitstatus == 0
puts "found after #{c} iterations"
break
end
c += 1
end
elsif ARGV[0] == 'check'
a = File.open('/proc/self/maps').readlines.map(&:chomp).select {|l| /\[(heap|stack)\]$/.match(l) }
exit 0 unless a[0].include?('heap') || a.size != 2 # heap must be before the stack
diff = a.reduce { |heap,stack| /^([0-9a-f]+)-([0-9a-f]+)/.match(stack)[1].hex - /^([0-9a-f]+)-([0-9a-f]+)/.match(heap)[2].hex }
puts diff
if diff < THRESHOLD
STDERR.puts "#{a[0]}\n#{a[1]}"
h = {}
(THRESHOLD / 40).times { o = Object.new; h[o.object_id] = o }
recurse(1)
exit 1
end
end
@csfrancis
Copy link
Author

[vagrant] ~/tmp $ ./sigbus.rb
new minimum diff: 61814599680 (2)
new minimum diff: 56968851456 (22)
new minimum diff: 24749420544 (30)
new minimum diff: 4401184768 (141)
new minimum diff: 4396490752 (150)
new minimum diff: 4317462528 (563)
new minimum diff: 2114654208 (629)
new minimum diff: 1346527232 (2027)
new minimum diff: 1207037952 (14588)
7ffede687000-7ffee28b7000 rw-p 00000000 00:00 0 [heap]
7fff0f22f000-7fff0f250000 rw-p 00000000 00:00 0 [stack]
./sigbus.rb:9: [BUG] Bus Error at 0x007fff0f21efa8
ruby 2.1.5p273-shopify (development) [x86_64-linux]
... FULL STACK DUMP HERE ...
new minimum diff: 0 (18361)
found after 18361 iterations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment