4 # :title: Debugging/profiling for rbot
6 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
7 # Copyright:: (C) 2006-2007 Giuseppe Bilotta
10 class DebugPlugin < Plugin
11 Config.register Config::IntegerValue.new('debug.interval',
12 :default => 10, :validate => Proc.new{|v| v > 0},
13 :desc => "Number of seconds between memory profile dumps")
14 Config.register Config::BooleanValue.new('debug.dump_strings',
16 :desc => "Set to true if you want the profiler to dump strings, false otherwise")
17 Config.register Config::StringValue.new('debug.logdir',
19 :desc => "Directory where profile/string dumps are to be stored")
22 @bot.config['debug.logdir']
30 @file = File.open(datafile("memory_profiler.log"), 'w')
31 @thread = @bot.timer.add(@bot.config['debug.interval']) {
38 ObjectSpace.each_object do |o|
39 @curr[o.class] += 1 #Marshal.dump(o).size rescue 1
40 if @bot.config['debug.dump_strings'] and o.class == String
45 if @bot.config['debug.dump_strings']
46 File.open(datafile("memory_profiler_strings.log.#{Time.now.to_i}"), 'w') do |f|
47 curr_strings.sort.each do |s|
55 (@curr.keys + @prev.keys).uniq.each do |k,v|
56 @delta[k] = @curr[k]-@prev[k]
60 @delta.sort_by { |k,v| -v.abs }[0..19].sort_by { |k,v| -v}.each do |k,v|
61 @file.printf "%+5d: %s (%d)\n", v, k.name, @curr[k] unless v == 0
69 rescue Exception => err
70 error "** memory_profiler error: #{err}"
73 @bot.timer.block(@thread)
76 def help( plugin, topic="" )
77 "debug start => start the periodic profiler; " + \
78 "debug stop => stops the periodic profiler; " + \
79 "debug dumpstrings => dump all of the strings"
82 def start_it(m, params)
84 @bot.timer.unblock(@thread)
85 m.reply "profile dump started"
86 rescue Exception => err
87 m.reply "couldn't start profile dump"
88 error "couldn't start profile dump: #{err}"
92 def stop_it(m, params)
94 @bot.timer.block(@thread)
95 m.reply "profile dump stop"
96 rescue Exception => err
97 m.reply "couldn't stop profile dump"
98 error "couldn't stop profile dump: #{err}"
102 def dump_strings(m, params)
105 m.reply "Dumping strings ..."
108 ObjectSpace.each_object do |o|
114 File.open(datafile("memory_profiler_strings.log.#{Time.now.to_i}"), 'w') do |f|
115 curr_strings.sort.each do |s|
121 rescue Exception => err
122 m.reply "dumping strings failed"
123 error "dumping strings failed: #{err}"
130 plugin = DebugPlugin.new
132 plugin.default_auth( 'start', false )
133 plugin.default_auth( 'stop', false )
134 plugin.default_auth( 'dumpstrings', false )
136 plugin.map 'debug start', :action => 'start_it'
137 plugin.map 'debug stop', :action => 'stop_it'
138 plugin.map 'debug dumpstrings', :action => 'dump_strings'