rhomobile-debug 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/CHANGELOG +2 -0
  2. data/LICENSE +21 -0
  3. data/README.md +8 -0
  4. data/lib/debugger.rb +281 -0
  5. metadata +70 -0
data/CHANGELOG ADDED
@@ -0,0 +1,2 @@
1
+ ## 1.0
2
+ * RhoStudio customization to support debugger
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2008-2010 Rhomobile, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,8 @@
1
+ Rhomobile debugger extension
2
+ -------------------------------------------------------------
3
+ Rhomobile debugger extension used by RhoStudio
4
+
5
+ More Info
6
+ -------------------------------------------------------------
7
+ * Intro to Rhodes & RhoSync: <http://docs.rhomobile.com>
8
+ * RhoStudio: <http://docs.rhomobile.com/rhostudio.tutorial>
data/lib/debugger.rb ADDED
@@ -0,0 +1,281 @@
1
+ require 'uri'
2
+ require 'timeout'
3
+
4
+ DEBUGGER_STEP_TYPE = ['STEP','STOVER','STRET','SUSP']
5
+ DEBUGGER_STEP_COMMENT = ['Stepped into','Stepped over','Stepped return','Suspended']
6
+
7
+ def debug_read_cmd(io,wait)
8
+ begin
9
+ if wait
10
+ cmd = io.readpartial(4096)
11
+ $_cmd << cmd if cmd !~ /^\s*$/
12
+ else
13
+ cmd = io.read_nonblock(4096)
14
+ $_cmd << cmd if cmd !~ /^\s*$/
15
+ end
16
+ rescue
17
+ # puts $!.inspect
18
+ end
19
+ end
20
+
21
+ def execute_cmd(cmd, advanced)
22
+ cmd = URI.unescape(cmd.gsub(/\+/,' ')) if advanced
23
+ puts "[Debugger] Executing: #{cmd.inspect}"
24
+ result = ""
25
+ error = '0';
26
+ begin
27
+ result = eval(cmd, $_binding).inspect
28
+ rescue Exception => exc
29
+ error = '1';
30
+ result = "#{$!}".inspect
31
+ end
32
+
33
+ cmd = URI.escape(cmd.sub(/[\n\r]+$/, ''), Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) if advanced
34
+ $_s.write("EV" + (advanced ? "L:#{error}:#{cmd}:" : ':'+(error.to_i != 0 ? 'ERROR: ':'')) + result + "\n")
35
+ end
36
+
37
+ def get_variables(scope)
38
+ if (scope =~ /^GVARS/)
39
+ cmd = "global_variables"
40
+ prefix = ""
41
+ vartype = "G"
42
+ elsif (scope =~ /^LVARS/)
43
+ cmd = "local_variables"
44
+ prefix = ""
45
+ vartype = "L"
46
+ elsif (scope =~ /^CVARS/)
47
+ if $_classname =~ /^\s*$/
48
+ return
49
+ end
50
+ cmd = "class_variables"
51
+ prefix = "#{$_classname}."
52
+ vartype = "C"
53
+ elsif (scope =~ /^IVARS/)
54
+ if ($_classname =~ /^\s*$/) or ($_methodname =~ /^\s*$/)
55
+ return
56
+ end
57
+ cmd = "instance_variables"
58
+ prefix = "self."
59
+ vartype = "I"
60
+ end
61
+ begin
62
+ vars = eval(prefix + cmd, $_binding)
63
+ $_s.write("VSTART:#{vartype}\n")
64
+ vars.each do |v|
65
+ if v !~ /^\$(=|KCODE)$/
66
+ begin
67
+ result = eval(v,$_binding).inspect
68
+ rescue Exception => exc
69
+ result = "#{$!}".inspect
70
+ end
71
+ $_s.write("V:#{vartype}:#{v}:#{result}\n")
72
+ end
73
+ end
74
+ $_s.write("VEND:#{vartype}\n")
75
+ rescue
76
+ end
77
+ end
78
+
79
+ def log_command(cmd)
80
+ # puts "[Debugger] Received command: #{cmd}"
81
+ end
82
+
83
+ def debug_handle_cmd(inline)
84
+ cmd = $_cmd.match(/^([^\n\r]*)([\n\r]+|$)/)[0]
85
+ processed = false
86
+ wait = inline
87
+ if cmd != ""
88
+ if cmd =~/^CONNECTED/
89
+ log_command(cmd)
90
+ puts "[Debugger] Connected to debugger"
91
+ processed = true
92
+ elsif cmd =~/^(BP|RM):/
93
+ log_command(cmd)
94
+ ary = cmd.split(":")
95
+ bp = ary[1].gsub(/\|/,':') + ':' + ary[2].chomp
96
+ if (cmd =~/^RM:/)
97
+ $_breakpoint.delete(bp)
98
+ puts "[Debugger] Breakpoint removed: #{bp}"
99
+ else
100
+ $_breakpoint.store(bp,1)
101
+ puts "[Debugger] Breakpoint added: #{bp}"
102
+ end
103
+ processed = true
104
+ elsif cmd =~ /^RMALL/
105
+ log_command(cmd)
106
+ $_breakpoint.clear
107
+ puts "[Debugger] All breakpoints removed"
108
+ processed = true
109
+ elsif cmd =~ /^ENABLE/
110
+ log_command(cmd)
111
+ $_breakpoints_enabled = true
112
+ puts "[Debugger] Breakpoints enabled"
113
+ processed = true
114
+ elsif cmd =~ /^DISABLE/
115
+ log_command(cmd)
116
+ $_breakpoints_enabled = false
117
+ puts "[Debugger] Breakpoints disabled"
118
+ processed = true
119
+ elsif inline and (cmd =~ /^STEPOVER/)
120
+ log_command(cmd)
121
+ $_step = 2
122
+ $_step_level = $_call_stack
123
+ $_resumed = true
124
+ wait = false
125
+ puts "[Debugger] Step over"
126
+ processed = true
127
+ elsif inline and (cmd =~ /^STEPRET/)
128
+ log_command(cmd)
129
+ if $_call_stack < 1
130
+ $_step = 0
131
+ comment = ' (continue)'
132
+ else
133
+ $_step = 3
134
+ $_step_level = $_call_stack-1;
135
+ comment = ''
136
+ end
137
+ $_resumed = true
138
+ wait = false
139
+ puts "[Debugger] Step return" + comment
140
+ processed = true
141
+ elsif inline and (cmd =~ /^STEP/)
142
+ log_command(cmd)
143
+ $_step = 1
144
+ $_step_level = -1
145
+ $_resumed = true
146
+ wait = false
147
+ puts "[Debugger] Step into"
148
+ processed = true
149
+ elsif inline and (cmd =~ /^CONT/)
150
+ log_command(cmd)
151
+ wait = false
152
+ $_step = 0
153
+ $_resumed = true
154
+ puts "[Debugger] Resuming"
155
+ processed = true
156
+ elsif cmd =~ /^SUSP/
157
+ log_command(cmd)
158
+ $_step = 4
159
+ $_step_level = -1
160
+ wait = true
161
+ puts "[Debugger] Suspend"
162
+ processed = true
163
+ elsif cmd =~ /^KILL/
164
+ log_command(cmd)
165
+ puts "[Debugger] Terminating..."
166
+ processed = true
167
+ System.exit
168
+ elsif inline and (cmd =~ /^EVL?:/)
169
+ log_command(cmd)
170
+ processed = true
171
+ execute_cmd cmd.sub(/^EVL?:/,""), (cmd =~ /^EVL:/ ? true : false)
172
+ elsif inline and (cmd =~ /^[GLCI]VARS/)
173
+ log_command(cmd)
174
+ get_variables cmd
175
+ processed = true
176
+ elsif inline
177
+ log_command(cmd)
178
+ puts "[Debugger] Unknown command"
179
+ processed = true
180
+ end
181
+ end
182
+ if processed
183
+ $_cmd = $_cmd.sub(/^([^\n\r]*)([\n\r]+(.*)|)$/, "\\3")
184
+ $_wait = wait if inline
185
+ end
186
+ processed
187
+ end
188
+
189
+ $_tracefunc = lambda{|event, file, line, id, bind, classname|
190
+ return if eval('Thread.current!=Thread.main', bind)
191
+ $_binding = bind;
192
+ $_classname = classname;
193
+ $_methodname = id;
194
+ file = file.to_s.gsub('\\', '/')
195
+ if file[0, $_app_path.length] == $_app_path
196
+ if event =~ /^line/
197
+
198
+ unhandled = true
199
+ step_stop = ($_step > 0) and (($_step_level < 0) or ($_call_stack <= $_step_level))
200
+ if (step_stop or ($_breakpoints_enabled and (not $_breakpoint.empty?)))
201
+ filename = file[$_app_path.length, file.length-$_app_path.length]
202
+ ln = line.to_i.to_s
203
+ if (step_stop or ($_breakpoints_enabled and ($_breakpoint.has_key?(filename + ':' + ln))))
204
+ fn = filename.gsub(/:/, '|')
205
+ cl = classname.to_s.gsub(/:/,'#')
206
+ $_s.write((step_stop ? DEBUGGER_STEP_TYPE[$_step-1] : "BP") + ":#{fn}:#{ln}:#{cl}:#{id}\n")
207
+ puts "[Debugger] " + (step_stop ? DEBUGGER_STEP_COMMENT[$_step-1] : "Breakpoint") + " in #{fn} at #{ln}"
208
+ $_step = 0
209
+ $_step_level = -1
210
+
211
+ $_wait = true
212
+ while $_wait
213
+ while debug_handle_cmd(true) do end
214
+ if System::get_property('main_window_closed')
215
+ $_wait = false
216
+ end
217
+ sleep if $_wait
218
+ end
219
+ unhandled = false
220
+ end
221
+ end
222
+
223
+ if unhandled
224
+ debug_handle_cmd(true)
225
+ end
226
+
227
+ elsif event =~ /^call/
228
+ $_call_stack += 1
229
+ elsif event =~ /^return/
230
+ $_call_stack -= 1
231
+ end
232
+ end
233
+
234
+ if $_resumed
235
+ $_resumed = false
236
+ $_s.write("RESUMED\n")
237
+ end
238
+ }
239
+
240
+
241
+ $_s = nil
242
+
243
+ begin
244
+ puts "[Debugger] Opening connection"
245
+ debug_host = (Rho::RhoConfig.debug_host.nil? or Rho::RhoConfig.debug_host == "") ? '127.0.0.1' : Rho::RhoConfig.debug_host
246
+ debug_port = (Rho::RhoConfig.debug_port.nil? or Rho::RhoConfig.debug_port == "") ? 9000 : Rho::RhoConfig.debug_port
247
+ $_s = timeout(30) { TCPSocket.open(debug_host, debug_port) }
248
+
249
+ puts "[Debugger] Connected: " + $_s.to_s
250
+ $_s.write("CONNECT\n")
251
+
252
+ $_breakpoint = Hash.new
253
+ $_breakpoints_enabled = true
254
+ $_step = 0
255
+ $_step_level = -1
256
+ $_call_stack = 0
257
+ $_resumed = false
258
+ $_cmd = ""
259
+ $_app_path = File.join(Rho::RhoApplication::get_base_app_path(), 'app/').gsub('\\', '/')
260
+
261
+ at_exit {
262
+ $_s.write("QUIT\n") if (not $_s.nil?)
263
+ }
264
+
265
+ set_trace_func $_tracefunc
266
+
267
+ Thread.new {
268
+ while true
269
+ debug_read_cmd($_s,true)
270
+ while debug_handle_cmd(false) do end
271
+ if ($_cmd !~ /^\s*$/) and (Thread.main.stop?)
272
+ $_wait = true
273
+ Thread.main.wakeup
274
+ end
275
+ end
276
+ }
277
+
278
+ rescue
279
+ puts "[Debugger] Unable to open connection to debugger: " + $!.inspect
280
+ $_s = nil
281
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rhomobile-debug
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ version: "1.0"
10
+ platform: ruby
11
+ authors:
12
+ - Rhomobile
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-06-30 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Rhomobile debugger extension
22
+ email: dev@rhomobile.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.md
29
+ - LICENSE
30
+ files:
31
+ - README.md
32
+ - LICENSE
33
+ - lib/debugger.rb
34
+ - CHANGELOG
35
+ has_rdoc: true
36
+ homepage: http://rhomobile.com
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ hash: 3
50
+ segments:
51
+ - 0
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.3.7
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Rhomobile debugger extension for RhoStudio
69
+ test_files: []
70
+