]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/debugger.rb
[plugin] del.icio.us ceased to exist.
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / debugger.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Debugging/profiling for rbot
5 #
6 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
7 # Copyright:: (C) 2006-2007 Giuseppe Bilotta
8 # License:: GPL v2
9
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',
15     :default => false,
16     :desc => "Set to true if you want the profiler to dump strings, false otherwise")
17   Config.register Config::StringValue.new('debug.logdir',
18     :default => "",
19     :desc => "Directory where profile/string dumps are to be stored")
20
21   def dirname
22     @bot.config['debug.logdir']
23   end
24
25   def initialize
26     super
27     @prev = Hash.new(0)
28     @curr = Hash.new(0)
29     @delta = Hash.new(0)
30     @file = File.open(datafile("memory_profiler.log"), 'w')
31     @thread = @bot.timer.add(@bot.config['debug.interval']) {
32         begin
33           GC.start
34           @curr.clear
35
36           curr_strings = []
37
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
41               curr_strings.push o
42             end
43           end
44
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|
48                 f.puts s
49               end
50             end
51             curr_strings.clear
52           end
53
54           @delta.clear
55           (@curr.keys + @prev.keys).uniq.each do |k,v|
56             @delta[k] = @curr[k]-@prev[k]
57           end
58
59           @file.puts "Top 20"
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
62           end
63           @file.flush
64
65           @delta.clear
66           @prev.clear
67           @prev.update @curr
68           GC.start
69         rescue Exception => err
70           error "** memory_profiler error: #{err}"
71         end
72     }
73     @bot.timer.block(@thread)
74   end
75
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"
80   end
81
82   def start_it(m, params)
83     begin
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}"
89     end
90   end
91
92   def stop_it(m, params)
93     begin
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}"
99     end
100   end
101
102   def dump_strings(m, params)
103     curr_strings = []
104
105     m.reply "Dumping strings ..."
106     begin
107       GC.start
108       ObjectSpace.each_object do |o|
109         if o.class == String
110           curr_strings.push o
111         end
112       end
113
114       File.open(datafile("memory_profiler_strings.log.#{Time.now.to_i}"), 'w') do |f|
115         curr_strings.sort.each do |s|
116           f.puts s
117         end
118       end
119       GC.start
120       m.reply "... done"
121     rescue Exception => err
122       m.reply "dumping strings failed"
123       error "dumping strings failed: #{err}"
124     end
125   end
126
127 end
128
129
130 plugin = DebugPlugin.new
131
132 plugin.default_auth( 'start', false )
133 plugin.default_auth( 'stop', false )
134 plugin.default_auth( 'dumpstrings', false )
135
136 plugin.map 'debug start', :action => 'start_it'
137 plugin.map 'debug stop', :action => 'stop_it'
138 plugin.map 'debug dumpstrings', :action => 'dump_strings'
139
140