valgrind and ruby (long)
From:
Pat Eyler <pate@...>
Date:
2002-06-06 16:26:13 UTC
List:
ruby-core #149
-----------------------------------------------------------------------
Disclaimer: I'm not a strong enough programmer (Ruby or C) to be doing
development work on Ruby. Take everything I say with a grain of salt.
-----------------------------------------------------------------------
I saw another announcement about valgrind (an open-source memory
debugger for x86-GNU/Linux) today, and decided to throw Ruby at it to see
what came up. After installing valgrind (a painless process), I ran a
small ruby script with it. Here are the important bits:
[pate@gnupate RWN]$ valgrind --version
valgrind-20020601
[pate@gnupate RWN]$ ruby -v
ruby 1.6.7 (2002-03-01) [i686-linux]
[pate@gnupate RWN]$ cat scanRURL.rb
#!/usr/local/bin/ruby -w
class Scanner
def initialize(file)
@file = File.new(file, "r")
@announcements = Array.new
@hotTopics = Hash.new
end
HOT_TOPIC_THRESHOLD = 5
def scan
scanForAnnouncements
@file.rewind
scanForHotTopics
end
def outputAnnouncements
puts "Announcements"
puts "~~~~~~~~~~~~~~"
@announcements.each do |announcement|
puts announcement.subject
end
print "\n"
end
def outputHotTopics
print "Hot Topics\n"
print "~~~~~~~~~~~~\n"
@hotTopics.each_pair do |topic, occurance|
if occurance >= HOT_TOPIC_THRESHOLD
puts topic.subject
puts "\tOccured " + occurance.to_s + " times"
end
end
end
private
#
# Look for subjects that are anouncements - ANN denotes an announcement
#
def scanForAnnouncements
@file.each do |line|
if line =~ /^Subject:\s(\[?(ANN|Ann|ann).*$)/
@announcements << MailSubject.new($1)
end
end
end
#
# Look for topics that are discussed more than the HOT_TOPIC_THRESHOLD
#
def scanForHotTopics
@file.each do |line|
if line =~ /^Subject:\s(.*)$/
mailSubject = MailSubject.new($1)
if @hotTopics.has_key?(mailSubject)
occurances = @hotTopics[mailSubject]
@hotTopics[mailSubject] = occurances.next
else
@hotTopics.store(mailSubject, 1)
end
end
end
end
end
class MailSubject
include Comparable
attr_reader :fullSubject
attr_reader :subject
def initialize(subject)
@subject = subject
end
def <=>(other)
@subject <=> other.subject
end
def eql?(other)
@subject.eql?(other.subject)
end
def hash
subject.hash
end
def to_s
print "Full subject is: " + @fullSubject + "\n"
print "Subject is: " + @subject + "\n"
end
end
if $0 == __FILE__
if ARGV.size == 1
file = ARGV[0]
scanner = Scanner.new(file)
scanner.scan
scanner.outputAnnouncements
scanner.outputHotTopics
else
p "USAGE: ./scanList.rb FILE"
end
end
[pate@gnupate RWN]$ valgrind --leak-check=yes ./scanRURL.rb rubylang.0603
==9689== valgrind-20020601, a memory error detector for x86 GNU/Linux.
==9689== Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.
==9689== Estimated CPU clock rate is 298 MHz
==9689== For more details, rerun with: -v
==9689==
==9689== Conditional jump or move depends on uninitialised value(s)
==9689== at 0x80659D0: mark_locations_array (gc.c:359)
==9689== by 0x8066523: rb_gc (gc.c:1008)
==9689== by 0x8098629: load_file (ruby.c:857)
==9689== by 0x809830B: proc_options (ruby.c:727)
[elided some errors]
==9689== Conditional jump or move depends on uninitialised value(s)
==9689== at 0x80659F7: mark_locations_array (gc.c:364)
==9689== by 0x8066523: rb_gc (gc.c:1008)
==9689== by 0x8098629: load_file (ruby.c:857)
==9689== by 0x809830B: proc_options (ruby.c:727)
[elided some errors]
==9689== Conditional jump or move depends on uninitialised value(s)
==9689== at 0x8065B6C: rb_gc_mark (ruby.h:606)
==9689== by 0x8065A37: mark_locations_array (gc.c:379)
==9689== by 0x8066523: rb_gc (gc.c:1008)
==9689== by 0x8098629: load_file (ruby.c:857)
[elided some errors]
==9689== Use of uninitialised value of size 4
==9689== at 0x8065B81: rb_gc_mark (gc.c:452)
==9689== by 0x8065A37: mark_locations_array (gc.c:379)
==9689== by 0x8066523: rb_gc (gc.c:1008)
==9689== by 0x8098629: load_file (ruby.c:857)
[elided some errors]
==9689== Use of uninitialised value of size 4
==9689== at 0x8065B81: rb_gc_mark (gc.c:452)
==9689== by 0x8065A37: mark_locations_array (gc.c:379)
==9689== by 0x8066523: rb_gc (gc.c:1008)
==9689== by 0x8098629: load_file (ruby.c:857)
[the errors continue ... skipping to the end]
==9689== More than 30000 total errors detected. I'm not reporting any
more.
==9689== Final error counts will be inaccurate. Go fix your program!
==9689==
[output of command elided]
==9689==
==9689== ERROR SUMMARY: 30000 errors from 37 contexts (suppressed: 0 from
0)
==9689== malloc/free: in use at exit: 379208 bytes in 8308 blocks.
==9689== malloc/free: 82108 allocs, 73800 frees, 3639387 bytes allocated.
==9689== For counts of detected errors, rerun with: -v
==9689== searching for pointers to 8308 not-freed blocks.
==9689== checked 4608320 bytes.
==9689==
==9689== definitely lost: 0 bytes in 0 blocks.
==9689== possibly lost: 20 bytes in 1 blocks.
==9689== still reachable: 379188 bytes in 8307 blocks.
==9689==
==9689== 20 bytes in 1 blocks are possibly lost in loss record 1 of 6
==9689== at 0x40042D79: malloc (in /opt/lib/valgrind/valgrind.so)
==9689== by 0x806550D: ruby_xmalloc (gc.c:97)
==9689== by 0x80869AC: top_local_setup (parse.y:4800)
==9689== by 0x807ACDC: rb_yyparse (parse.y:286)
==9689==
==9689== LEAK SUMMARY:
==9689== possibly lost: 20 bytes in 1 blocks.
==9689== definitely lost: 0 bytes in 0 blocks.
==9689== still reachable: 379188 bytes in 8307 blocks.
==9689== Reachable blocks (those to which a pointer was found) are not
shown.
==9689== To see them, rerun with: --show-reachable=yes
==9689==