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 BotConfig.register BotConfigIntegerValue.new('debug.interval',
12 :default => 10, :validate => Proc.new{|v| v > 0},
13 :desc => "Number of seconds between memory profile dumps")
14 BotConfig.register BotConfigBooleanValue.new('debug.dump_strings',
16 :desc => "Set to true if you want the profiler to dump strings, false otherwise")
17 BotConfig.register BotConfigStringValue.new('debug.logdir',
19 :desc => "Directory where profile/string dumps are to be stored")
26 @file = File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler.log",'w')
27 @thread = @bot.timer.add(@bot.config['debug.interval']) {
34 ObjectSpace.each_object do |o|
35 @curr[o.class] += 1 #Marshal.dump(o).size rescue 1
36 if @bot.config['debug.dump_strings'] and o.class == String
41 if @bot.config['debug.dump_strings']
42 File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler_strings.log.#{Time.now.to_i}",'w') do |f|
43 curr_strings.sort.each do |s|
51 (@curr.keys + @delta.keys).uniq.each do |k,v|
52 @delta[k] = @curr[k]-@prev[k]
56 @delta.sort_by { |k,v| -v.abs }[0..19].sort_by { |k,v| -v}.each do |k,v|
57 @file.printf "%+5d: %s (%d)\n", v, k.name, @curr[k] unless v == 0
65 rescue Exception => err
66 error "** memory_profiler error: #{err}"
69 @bot.timer.block(@thread)
72 def help( plugin, topic="" )
73 "debug start => start the periodic profiler; " + \
74 "debug stop => stops the periodic profiler; " + \
75 "debug dumpstrings => dump all of the strings"
78 def start_it(m, params)
80 @bot.timer.unblock(@thread)
81 m.reply "profile dump started"
82 rescue Exception => err
83 m.reply "couldn't start profile dump"
84 error "couldn't start profile dump: #{err}"
88 def stop_it(m, params)
90 @bot.timer.block(@thread)
91 m.reply "profile dump stop"
92 rescue Exception => err
93 m.reply "couldn't stop profile dump"
94 error "couldn't stop profile dump: #{err}"
98 def dump_strings(m, params)
101 m.reply "Dumping strings ..."
104 ObjectSpace.each_object do |o|
110 File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler_strings.log.#{Time.now.to_i}",'w') do |f|
111 curr_strings.sort.each do |s|
117 rescue Exception => err
118 m.reply "dumping strings failed"
119 error "dumping strings failed: #{err}"
126 plugin = DebugPlugin.new
128 plugin.default_auth( 'start', false )
129 plugin.default_auth( 'stop', false )
130 plugin.default_auth( 'dumpstrings', false )
132 plugin.map 'debug start', :action => 'start_it'
133 plugin.map 'debug stop', :action => 'stop_it'
134 plugin.map 'debug dumpstrings', :action => 'dump_strings'