null+****@clear*****
null+****@clear*****
2011年 1月 10日 (月) 15:47:03 JST
Kouhei Sutou 2011-01-10 06:47:03 +0000 (Mon, 10 Jan 2011)
New Revision: 4a4a16c14573e21fdf6be698d824c07c3803bb42
Log:
add a tool to detect memory leak.
Added files:
tools/groonga-check-memory-leak.rb
Added: tools/groonga-check-memory-leak.rb (+79 -0) 100755
===================================================================
--- /dev/null
+++ tools/groonga-check-memory-leak.rb 2011-01-10 06:47:03 +0000 (cc3a260)
@@ -0,0 +1,79 @@
+#!/usr/bin/env ruby
+
+unless respond_to?(:spawn, true)
+ puts("Ruby 1.9 is required.")
+ exit(false)
+end
+
+require 'ostruct'
+require 'optparse'
+require 'tempfile'
+require 'stringio'
+
+options = OpenStruct.new
+options.groonga = "groonga"
+options.show_result = false
+
+option_parser = OptionParser.new do |parser|
+ parser.banner += " DATABASE COMMAND_FILE1 ..."
+
+ parser.on("--groonga=PATH",
+ "Use PATH as groonga command path") do |path|
+ options.groonga = path
+ end
+
+ parser.on("--[no-]show-result",
+ "Show result of command") do |boolean|
+ options.show_result = boolean
+ end
+end
+
+database, *command_files = option_parser.parse!(ARGV)
+if database.nil?
+ puts(option_parser)
+ exit(false)
+end
+
+command_files.each do |path|
+ File.open(path) do |file|
+ file.each_line do |command|
+ command = command.chomp
+ base_name = File.basename($0, ".*")
+ log = Tempfile.new("#{base_name}-log")
+ command_file = Tempfile.new("#{base_name}-command")
+ command_file.puts(command)
+ command_file.close
+ command_line = [options.groonga,
+ "--log-path", log.path,
+ "--file", command_file.path]
+ command_file << "-n" unless File.exist?(database)
+ command_line << database
+ result = Tempfile.new("#{base_name}-result")
+ pid = spawn(*command_line, :out => result.fileno)
+ pid, status = Process.waitpid2(pid)
+ unless status.success?
+ puts("failed to run: (#{status.exitstatus}): " +
+ "[#{command_line.join(' ')}]")
+ puts("command:")
+ puts(command)
+ puts("result:")
+ result.open
+ puts(result.read)
+ exit(false)
+ end
+ if options.show_result
+ result.open
+ puts(result.read)
+ end
+ log.open
+ log.each_line do |log_line|
+ case log_line
+ when /grn_fin\((\d+)\)/
+ n_unfreed_allocations = $1.to_i
+ puts("maybe memory leak: #{n_unfreed_allocations}: <#{command}>")
+ exit(false)
+ end
+ end
+ end
+ end
+end