# Mmap causing a bus error

**URL:** <https://www.ruby-forum.com/t/mmap-causing-a-bus-error/67793>\
**Category:** Ruby\
**Created:** [September 6, 2006, 9:26pm UTC](https://www.ruby-forum.com/t/mmap-causing-a-bus-error/67793 "2006-09-06T21:26:55Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [September 6, 2006, 9:26pm UTC](https://www.ruby-forum.com/t/mmap-causing-a-bus-error/67793/1 "2006-09-06T21:26:55Z")

</div>

$ cat mmap-abort.rb

require ‘mmap’  
require ‘fileutils’

FileUtils.touch ‘output.txt’  
File.open(‘mmap.bin’, ‘w’) {|f| f.truncate 16} unless File.exist?  
‘mmap.bin’

m = Mmap.new ‘output.txt’, ‘rw’

(0…4).each do |x|  
fork do  
mmap = Mmap.new ‘mmap.bin’, ‘rw’  
range = (x_4)…(x_4+4)  
val = mmap[range].unpack(‘N’)[0]  
mmap[range] = [val+x].pack(‘N’)  
mmap.unmap  
end  
end

m \<\< “Done!\n”

# EOF

$ ruby mmap-abort.rb  
mmap-abort.rb:20: [BUG] Bus Error  
ruby 1.8.4 (2005-12-24) [powerpc-linux]

Aborted (core dumped)  
$

The line at the end – m \<\< “Done!\n” – is causing the abort. I’m  
seeing this behavior on all the Unix platforms I have access to …

SunOS ravenclaw 5.9 Generic\_112233-12 sun4u sparc SUNW,Sun-Blade-1500

Linux panic 2.6.17-1.2157\_FC5 #1 SMP Tue Jul 11 23:03:20 EDT 2006  
ppc64 ppc64 ppc64 GNU/Linux

Linux pong 2.6.17-1.2142\_FC4 #1 Tue Jul 11 22:41:14 EDT 2006 i686 i686  
i386 GNU/Linux

So, the interesting part is that if I open the “output.txt” file and  
add a single character to it, the problem disappears …

$ echo ‘x’ \> output.txt  
$ ruby mmap-abort.rb  
$ cat output.txt  
x  
Done!  
$

I can also make the problem go away by creating the mmap to output.txt  
after the each/fork block.

I can also make the problem go away by commenting out the “mmap.unmap”  
line at the end of the fork block.

The bus error is being caused by a call to memcpy in the “mm\_cat”  
method of the mmap source code – line 1480 of mmap.c

Any patches out there?

---

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [September 6, 2006, 10:15pm UTC](https://www.ruby-forum.com/t/mmap-causing-a-bus-error/67793/2 "2006-09-06T22:15:00Z")

</div>

On Thu, 7 Sep 2006, Tim P. wrote:

> (0…4).each do |x|
> 
> add a single character to it, the problem disappears …
> 
> I can also make the problem go away by commenting out the “mmap.unmap”  
> line at the end of the fork block.
> 
> The bus error is being caused by a call to memcpy in the “mm\_cat”  
> method of the mmap source code – line 1480 of mmap.c
> 
> Any patches out there?

harp:~ \> cat a.rb  
require ‘mmap’  
require ‘fileutils’

FileUtils.touch ‘output.txt’  
File.open(‘mmap.bin’, ‘w’) {|f| f.truncate 16} unless File.exist?  
‘mmap.bin’

m = Mmap.new ‘output.txt’, ‘rw’

(0…4).each do |x|  
fork do  
mmap = Mmap.new ‘mmap.bin’, ‘rw’  
range = (x_4)…(x_4+4)  
val = mmap[range].unpack(‘N’)[0]  
mmap[range] = [val+x].pack(‘N’)  
p mmap.to\_str  
mmap.unmap  
exit! # don’t let child unmap automatically  
end  
Process.wait # if you don’t do this it’ll be  
non-deterministic  
end

m \<\< “Done!\n”

harp:~ \> ruby a.rb  
“\000\000\000\000\000\000\000\010\000\000\000\020\000\000\000\030”  
“\000\000\000\000\000\000\000\t\000\000\000\020\000\000\000\030”  
“\000\000\000\000\000\000\000\t\000\000\000\022\000\000\000\030”  
“\000\000\000\000\000\000\000\t\000\000\000\022\000\000\000\e”

basically, you can’t carry the mmap across the fork and hope that the  
child’s  
at\_exit handlers don’t interfere with the parent. check this out:

```
 harp:~ > cat a.rb
 require 'mmap'
 STDOUT.sync = true
 Mmap.new __FILE__ , 'r'
 fork{ 42 } and Process.wait

 harp:~ > strace -f ruby a.rb 2>&1|egrep 'map|:[ABCD]:'|tail -3
 mmap2(NULL, 88, PROT_READ, MAP_SHARED, 3, 0) = 0xb75ae000
 [pid 2544] munmap(0xb75ae000, 88) = 0
 munmap(0xb75ae000, 88) = 0

```

and with exit!

```
 harp:~ > cat a.rb
 require 'mmap'
 STDOUT.sync = true
 Mmap.new __FILE__ , 'r'
 fork{ 42 and exit! } and Process.wait

 harp:~ > strace -f ruby a.rb 2>&1|egrep 'map|:[ABCD]:'|tail -3
 old_mmap(0xbab000, 4096, PROT_READ|PROT_WRITE, 

```

MAP\_PRIVATE|MAP\_FIXED, 3, 0x7000) = 0xbab000  
mmap2(NULL, 98, PROT\_READ, MAP\_SHARED, 3, 0) = 0xb75af000  
munmap(0xb75af000, 98) = 0

note the double munmap. i don’t know if this is os specific or not or  
if it’s  
expected or not - but preventing the child from freeing the map seems to  
fix  
it.

kind regards.

-a
