From 4a4a16c14573e21fdf6be698d824c07c3803bb42 Mon Sep 17 00:00:00 2001 From: Kouhei Sutou Date: Mon, 10 Jan 2011 15:47:03 +0900 Subject: [PATCH] add a tool to detect memory leak. --- tools/groonga-check-memory-leak.rb | 79 ++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100755 tools/groonga-check-memory-leak.rb diff --git a/tools/groonga-check-memory-leak.rb b/tools/groonga-check-memory-leak.rb new file mode 100755 index 0000000000..cc3a260f22 --- /dev/null +++ b/tools/groonga-check-memory-leak.rb @@ -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