DebugClients/Ruby/Debuggee.rb

changeset 4553
a6b2acd1a355
parent 4552
b1ea4ea0190e
child 4554
f3428ddd577c
equal deleted inserted replaced
4552:b1ea4ea0190e 4553:a6b2acd1a355
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2005 - 2015 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 # Debuggee.rb is based in parts on debug.rb from Ruby and debuggee.rb.
7 # Original copyrights of these files follow below.
8 #
9 # debug.rb
10 # Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
11 # Copyright (C) 2000 Information-technology Promotion Agency, Japan
12 #
13 # debuggee.rb
14 # Copyright (c) 2000 NAKAMURA, Hiroshi
15
16 =begin edoc
17 File implementing the real debugger, which is connected to the IDE frontend.
18 =end
19
20 require 'continuation'
21
22 require 'DebugQuit'
23 require 'rbconfig'
24
25 class DEBUGGER__
26 =begin edoc
27 Class implementing the real debugger.
28 =end
29 MUTEX = Mutex.new
30
31 class Context
32 =begin edoc
33 Class defining the current execution context.
34 =end
35 def initialize
36 =begin edoc
37 Constructor
38 =end
39 if Thread.current == Thread.main
40 @stop_next = 1
41 else
42 @stop_next = 0
43 end
44 @last_file = nil
45 @file = nil
46 @line = nil
47 @no_step = nil
48 @frames = []
49 @frame_pos = 0 #LJ - for FR
50 @finish_pos = 0
51 @trace = false
52 @catch = ["StandardError"] #LJ - for FR
53 @suspend_next = false
54 end
55
56 def stop_next(n=1)
57 =begin edoc
58 Method to set the next stop point (i.e. stop at next line).
59
60 @param counter defining the stop point (int)
61 =end
62 @stop_next = n
63 end
64
65 def step_over(n=1)
66 =begin edoc
67 Method to set the next stop point skipping function calls.
68
69 @param counter defining the stop point (int)
70 =end
71 @stop_next = n
72 @no_step = @frames.size - @frame_pos
73 end
74
75 def step_out
76 =begin edoc
77 Method to set the next stop point after the function call returns.
78 =end
79 if @frame_pos != @frames.size
80 @finish_pos = @frames.size - @frame_pos
81 @frame_pos = 0
82 @stop_next -= 1
83 end
84 end
85
86 def step_continue
87 =begin edoc
88 Method to continue execution until next breakpoint or watch expression.
89 =end
90 @stop_next = 1
91 @no_step = -1
92 end
93
94 def step_quit
95 =begin edoc
96 Method to stop debugging.
97 =end
98 raise DebugQuit.new
99 end
100
101 def set_suspend
102 =begin edoc
103 Method to suspend all threads.
104 =end
105 @suspend_next = true
106 end
107
108 def clear_suspend
109 =begin edoc
110 Method to clear the suspend state.
111 =end
112 @suspend_next = false
113 end
114
115 def suspend_all
116 =begin edoc
117 Method to suspend all threads.
118 =end
119 DEBUGGER__.suspend
120 end
121
122 def resume_all
123 =begin edoc
124 Method to resume all threads.
125 =end
126 DEBUGGER__.resume
127 end
128
129 def check_suspend
130 =begin edoc
131 Method to check the suspend state.
132 =end
133 while MUTEX.synchronize {
134 if @suspend_next
135 DEBUGGER__.waiting.push Thread.current
136 @suspend_next = false
137 true
138 end
139 }
140 end
141 end
142
143 def stdout
144 =begin edoc
145 Method returning the stdout object.
146
147 @return reference to the stdout object
148 =end
149 DEBUGGER__.stdout
150 end
151
152 def break_points
153 =begin edoc
154 Method to return the list of breakpoints
155
156 @return Array containing all breakpoints.
157 =end
158 DEBUGGER__.break_points
159 end
160
161 def context(th)
162 =begin edoc
163 Method returning the context of a thread.
164
165 @param th thread object to get the context for
166 @return the context for the thread
167 =end
168 DEBUGGER__.context(th)
169 end
170
171 def attached?
172 =begin edoc
173 Method returning the attached state.
174
175 @return flag indicating, whether the debugger is attached to the IDE.
176 =end
177 DEBUGGER__.attached?
178 end
179
180 def set_last_thread(th)
181 =begin edoc
182 Method to remember the last thread.
183
184 @param th thread to be remembered.
185 =end
186 DEBUGGER__.set_last_thread(th)
187 end
188
189 def debug_silent_eval(str, binding_)
190 =begin edoc
191 Method to eval a string without output.
192
193 @param str String containing the expression to be evaluated
194 @param binding_ the binding for the evaluation
195 @return the result of the evaluation
196 =end
197 val = eval(str, binding_)
198 val
199 end
200
201 def thnum
202 =begin edoc
203 Method returning the thread number of the current thread.
204
205 @return thread number of the current thread.
206 =end
207 num = DEBUGGER__.instance_eval{@thread_list[Thread.current]}
208 unless num
209 DEBUGGER__.make_thread_list
210 num = DEBUGGER__.instance_eval{@thread_list[Thread.current]}
211 end
212 num
213 end
214
215 def debug_command(file, line, id, binding_)
216 =begin edoc
217 Method to execute the next debug command.
218 =end
219 MUTEX.lock
220 set_last_thread(Thread.current)
221 unless attached?
222 MUTEX.unlock
223 resume_all
224 return
225 end
226 @frame_pos = 0
227 @frames[0] = [binding_, file, line, id]
228 stdout.printf_line(@frames)
229 MUTEX.unlock
230 resume_all
231 eventLoop
232 end
233
234 def frame_set_pos(file, line)
235 =begin edoc
236 Method to set the frame position of the current frame.
237 =end
238 if @frames[0]
239 @frames[0][1] = file
240 @frames[0][2] = line
241 end
242 end
243
244 def check_break_points(file, pos, binding_, id)
245 =begin edoc
246 Method to check, if the given position contains an active breakpoint.
247
248 @param file filename containing the currently executed line (String)
249 @param pos line number currently executed (int)
250 @param binding_ current binding object
251 @param id (ignored)
252 @return flag indicating an active breakpoint (boolean)
253 =end
254 # bp[0] enabled flag
255 # bp[1] 0 = breakpoint, 1 = watch expression
256 # bp[2] filename
257 # bp[3] linenumber
258 # bp[4] temporary flag
259 # bp[5] condition
260 # bp[6] ignore count
261 # bp[7] special condition
262 # bp[8] hash of special values
263 return false if break_points.empty?
264 break_points.each do |b|
265 if b[0]
266 if b[1] == 0 and b[2] == file and b[3] == pos # breakpoint
267 # Evaluate condition
268 if b[5]
269 begin
270 if debug_silent_eval(b[5], binding_)
271 if b[6] == 0 # ignore count reached
272 # Delete once reached if temporary breakpoint
273 clear_break_point(file, pos) if b[4]
274 return true
275 else
276 b[6] -= 1
277 end
278 end
279 rescue StandardError, ScriptError
280 nil
281 end
282 else
283 if b[6] == 0 # ignore count reached
284 # Delete once reached if temporary breakpoint
285 clear_break_point(file, pos) if b[4]
286 return true
287 else
288 b[6] -= 1
289 end
290 end
291 elsif b[1] == 1 # watch expression
292 begin
293 bd = @frame_pos
294 val = debug_silent_eval(b[5], binding_)
295 if b[7].length() > 0
296 if b[7] == "??created??"
297 if b[8][bd][0] == false
298 b[8][bd][0] = true
299 b[8][bd][1] = val
300 return true
301 else
302 next
303 end
304 end
305 b[8][bd][0] = true
306 if b[7] == "??changed??"
307 if b[8][bd][1] != val
308 b[8][bd][1] = val
309 if b[8][bd][2] > 0
310 b[8][bd][2] -= 1
311 next
312 else
313 return true
314 end
315 else
316 next
317 end
318 end
319 next
320 end
321 if val
322 if b[6] == 0 # ignore count reached
323 # Delete once reached if temporary breakpoint
324 clear_watch_point(b[2]) if b[4]
325 return true
326 else
327 b[6] -= 1
328 end
329 end
330 rescue StandardError, ScriptError
331 if b[7].length() > 0
332 if b[8][bd]
333 b[8][bd][0] = false
334 else
335 b[8][bd] = [false, nil, b[6]]
336 end
337 else
338 val = nil
339 end
340 end
341 end
342 end
343 end
344 return false
345 end
346
347 def clear_break_point(file, pos)
348 =begin edoc
349 Method to delete a specific breakpoint.
350
351 @param file filename containing the breakpoint (String)
352 @param pos line number containing the breakpoint (int)
353 =end
354 delete_break_point(file, pos)
355 stdout.printf_clear_breakpoint(file, pos)
356 end
357
358 def add_break_point(file, pos, temp = false, cond = nil)
359 =begin edoc
360 Method to add a breakpoint.
361
362 @param file filename for the breakpoint (String)
363 @param pos line number for the breakpoint (int)
364 @param temp flag indicating a temporary breakpoint (boolean)
365 @param cond condition of a conditional breakpoint (String)
366 =end
367 break_points.push [true, 0, file, pos, temp, cond, 0]
368 end
369
370 def delete_break_point(file, pos)
371 =begin edoc
372 Method to delete a breakpoint.
373
374 @param file filename of the breakpoint (String)
375 @param pos line number of the breakpoint (int)
376 =end
377 break_points.delete_if { |bp|
378 bp[1] == 0 and bp[2] == file and bp[3] == pos
379 }
380 end
381
382 def enable_break_point(file, pos, enable)
383 =begin edoc
384 Method to set the enabled state of a breakpoint.
385
386 @param file filename of the breakpoint (String)
387 @param pos line number of the breakpoint (int)
388 @param enable flag indicating the new enabled state (boolean)
389 =end
390 break_points.each do |bp|
391 if (bp[1] == 0 and bp[2] == file and bp[3] == pos)
392 bp[0] = enable
393 break
394 end
395 end
396 end
397
398 def ignore_break_point(file, pos, count)
399 =begin edoc
400 Method to set the ignore count of a breakpoint.
401
402 @param file filename of the breakpoint (String)
403 @param pos line number of the breakpoint (int)
404 @param count ignore count to be set (int)
405 =end
406 break_points.each do |bp|
407 if (bp[2] == file and bp[3] == pos)
408 bp[6] = count
409 break
410 end
411 end
412 end
413
414 def clear_watch_point(cond)
415 =begin edoc
416 Method to delete a specific watch expression.
417
418 @param cond expression specifying the watch expression (String)
419 =end
420 delete_watch_point(cond)
421 stdout.printf_clear_watchexpression(cond)
422 end
423
424 def add_watch_point(cond, temp = false)
425 =begin edoc
426 Method to add a watch expression.
427
428 @param cond expression of the watch expression (String)
429 @param temp flag indicating a temporary watch expression (boolean)
430 =end
431 co1, co2 = cond.split()
432 if co2 == "??created??" or co2 == "??changed??"
433 break_points.push [true, 1, cond, 0, temp, co1, 0, co2, {}]
434 else
435 break_points.push [true, 1, cond, 0, temp, cond, 0, "", {}]
436 end
437 end
438
439 def delete_watch_point(cond)
440 =begin edoc
441 Method to delete a watch expression.
442
443 @param cond expression of the watch expression (String)
444 =end
445 break_points.delete_if { |bp|
446 bp[1] == 1 and bp[2] == cond
447 }
448 end
449
450 def enable_watch_point(cond, enable)
451 =begin edoc
452 Method to set the enabled state of a watch expression.
453
454 @param cond expression of the watch expression (String)
455 @param enable flag indicating the new enabled state (boolean)
456 =end
457 break_points.each do |bp|
458 if (bp[1] == 1 and bp[2] == cond)
459 bp[0] = enable
460 break
461 end
462 end
463 end
464
465 def ignore_watch_point(cond, count)
466 =begin edoc
467 Method to set the ignore count of a watch expression.
468
469 @param cond expression of the watch expression (String)
470 @param count ignore count to be set (int)
471 =end
472 break_points.each do |bp|
473 if (bp[1] == 1 and bp[2] == cond)
474 bp[6] = count
475 break
476 end
477 end
478 end
479
480 def excn_handle(file, line, id, binding_)
481 =begin edoc
482 Method to handle an exception
483
484 @param file filename containing the currently executed line (String)
485 @param pos line number currently executed (int)
486 @param id (ignored)
487 @param binding_ current binding object
488 =end
489 if $!.class <= SystemExit
490 set_trace_func nil
491 stdout.printf_exit($!.status)
492 return
493 elsif $!.class <= ScriptError
494 msgParts = $!.message.split(":", 3)
495 filename = File.expand_path(msgParts[0])
496 linenr = msgParts[1].to_i
497 exclist = ["", [filename, linenr, 0]]
498 stdout.printf_scriptExcn(exclist)
499 else
500 exclist = ["%s" % $!.class, "%s" % $!, [file, line]]
501 @frames.each do |_binding, _file, _line, _id|
502 next if [_file, _line] == exclist[-1]
503 exclist << [_file, _line, '', '']
504 end
505 stdout.printf_excn(exclist)
506 end
507 debug_command(file, line, id, binding_)
508 end
509
510 def skip_it?(file)
511 =begin edoc
512 Method to filter out debugger files.
513
514 Tracing is turned off for files that are part of the
515 debugger that are called from the application being debugged.
516
517 @param file name of the file to be checked (String)
518 @return flag indicating, whether the file should be skipped (boolean)
519 =end
520 if file =~ /\(eval\)/
521 return true
522 end
523
524 if not traceRuby? and
525 (file =~ /#{RbConfig::CONFIG['sitelibdir']}/ or
526 file =~ /#{RbConfig::CONFIG['rubylibdir']}/)
527 return true
528 end
529
530 if ["AsyncFile.rb", "AsyncIO.rb", "Config.rb", "DebugClient.rb",
531 "DebugClientBaseModule.rb", "DebugClientCapabilities.rb",
532 "DebugProtocol.rb", "DebugQuit.rb", "Debuggee.rb"].include?(
533 File.basename(file))
534 return true
535 end
536 return false
537 end
538
539 def trace_func(event, file, line, id, binding_, klass)
540 =begin edoc
541 Method executed by the tracing facility.
542
543 @param event the tracing event (String)
544 @param file the name of the file being traced (String)
545 @param line the line number being traced (int)
546 @param id object id
547 @param binding_ a binding object
548 @param klass name of a class
549 =end
550 context(Thread.current).check_suspend
551
552 if skip_it?(file) and not ["call","return"].include?(event)
553 case event
554 when 'line'
555 frame_set_pos(file, line)
556
557 when 'call'
558 @frames.unshift [binding_, file, line, id]
559
560 when 'c-call'
561 frame_set_pos(file, line)
562
563 when 'class'
564 @frames.unshift [binding_, file, line, id]
565
566 when 'return', 'end'
567 @frames.shift
568
569 when 'raise'
570 excn_handle(file, line, id, binding_)
571
572 end
573 @last_file = file
574 return
575 end
576
577 @file = file
578 @line = line
579
580 case event
581 when 'line'
582 frame_set_pos(file, line)
583 eventPoll
584 if !@no_step or @frames.size == @no_step
585 @stop_next -= 1
586 @stop_next = -1 if @stop_next < 0
587 elsif @frames.size < @no_step
588 @stop_next = 0 # break here before leaving...
589 else
590 # nothing to do. skipped.
591 end
592 if check_break_points(file, line, binding_, id) or @stop_next == 0
593 @no_step = nil
594 suspend_all
595 debug_command(file, line, id, binding_)
596 end
597
598 when 'call'
599 @frames.unshift [binding_, file, line, id]
600 if check_break_points(file, id.id2name, binding_, id) or
601 check_break_points(klass.to_s, id.id2name, binding_, id)
602 suspend_all
603 debug_command(file, line, id, binding_)
604 end
605
606 when 'c-call'
607 frame_set_pos(file, line)
608 ## if id == :require and klass == Kernel
609 ## @frames.unshift [binding_, file, line, id]
610 ## else
611 ## frame_set_pos(file, line)
612 ## end
613 ##
614 ## when 'c-return'
615 ## if id == :require and klass == Kernel
616 ## if @frames.size == @finish_pos
617 ## @stop_next = 1
618 ## @finish_pos = 0
619 ## end
620 ## @frames.shift
621 ## end
622
623 when 'class'
624 @frames.unshift [binding_, file, line, id]
625
626 when 'return', 'end'
627 if @frames.size == @finish_pos
628 @stop_next = 1
629 @finish_pos = 0
630 end
631 @frames.shift
632
633 when 'raise'
634 @no_step = nil
635 @stop_next = 0 # break here before leaving...
636 excn_handle(file, line, id, binding_)
637
638 end
639 @last_file = file
640 end
641 end
642
643 trap("INT") { DEBUGGER__.interrupt }
644 @last_thread = Thread::main
645 @max_thread = 1
646 @thread_list = {Thread::main => 1}
647 @break_points = []
648 @waiting = []
649 @stdout = STDOUT
650 @loaded_files = {}
651
652 class SilentObject
653 =begin edoc
654 Class defining an object that ignores all messages.
655 =end
656 def method_missing( msg_id, *a, &b )
657 =begin edoc
658 Method invoked for all messages it cannot handle.
659
660 @param msg_id symbol for the method called
661 @param *a arguments passed to the missing method
662 @param &b unknown
663 =end
664 end
665 end
666 SilentClient = SilentObject.new()
667 @client = SilentClient
668 @attached = false
669
670 class <<DEBUGGER__
671 =begin edoc
672 Class defining a singleton object for the debugger.
673 =end
674 def stdout
675 =begin edoc
676 Method returning the stdout object.
677
678 @return reference to the stdout object
679 =end
680 @stdout
681 end
682
683 def stdout=(s)
684 =begin edoc
685 Method to set the stdout object.
686
687 @param s reference to the stdout object
688 =end
689 @stdout = s
690 end
691
692 def break_points
693 =begin edoc
694 Method to return the list of breakpoints
695
696 @return Array containing all breakpoints.
697 =end
698 @break_points
699 end
700
701 def last_thread
702 =begin edoc
703 Method returning the last active thread.
704
705 @return active thread
706 =end
707 @last_thread
708 end
709
710 def attach( debugger )
711 =begin edoc
712 Method to connect the debugger to the IDE.
713
714 @param debugger reference to the object handling the
715 communication with the IDE.
716 =end
717 unless @attached
718 set_client( debugger )
719 @attached = true
720 interrupt
721 else
722 false
723 end
724 end
725
726 def client
727 =begin edoc
728 Method returning a reference to the client object.
729
730 @return reference to the client object.
731 =end
732 @client
733 end
734
735 def set_client( debugger )
736 =begin edoc
737 Method to set the client handling the connection.
738
739 @param debugger reference to the object handling the connection
740 =end
741 @client = Client.new( debugger )
742 DEBUGGER__.stdout = @client
743 end
744
745 def attached?
746 =begin edoc
747 Method returning the attached state.
748
749 @return flag indicating, whether the debugger is attached to the IDE.
750 =end
751 @attached
752 end
753
754 def quit(status = 0)
755 =begin edoc
756 Method to quit the debugger.
757
758 @param status exit status of the program
759 =end
760 @client.printf_exit(status)
761 STDERR.flush; STDOUT.flush
762 end
763
764 def waiting
765 =begin edoc
766 Method returning the waiting list.
767
768 @return the waiting list
769 =end
770 @waiting
771 end
772
773 def set_last_thread(th)
774 =begin edoc
775 Method to remember the last thread.
776
777 @param th thread to be remembered.
778 =end
779 @last_thread = th
780 end
781
782 def suspend
783 =begin edoc
784 Method to suspend the program being debugged.
785 =end
786 MUTEX.synchronize do
787 make_thread_list
788 for th, in @thread_list
789 next if th == Thread.current
790 context(th).set_suspend
791 end
792 end
793 # Schedule other threads to suspend as soon as possible.
794 Thread.pass
795 end
796
797 def resume
798 =begin edoc
799 Method to resume the program being debugged.
800 =end
801 MUTEX.synchronize do
802 make_thread_list
803 for th, in @thread_list
804 next if th == Thread.current
805 context(th).clear_suspend
806 end
807 waiting.each do |th|
808 th.run
809 end
810 waiting.clear
811 end
812 # Schedule other threads to restart as soon as possible.
813 Thread.pass
814 end
815
816 def context(thread=Thread.current)
817 =begin edoc
818 Method returning the context of a thread.
819
820 @param th threat the context is requested for
821 @return context object for the thread
822 =end
823 c = thread[:__debugger_data__]
824 unless c
825 thread[:__debugger_data__] = c = Context.new
826 end
827 c
828 end
829
830 def interrupt
831 =begin edoc
832 Method to stop execution at the next instruction.
833 =end
834 context(@last_thread).stop_next
835 end
836
837 def get_thread(num)
838 =begin edoc
839 Method returning a thread by number.
840
841 @param num thread number (int)
842 @return thread with the requested number
843 =end
844 th = @thread_list.key(num)
845 unless th
846 @stdout.print "No thread ##{num}\n"
847 throw :debug_error
848 end
849 th
850 end
851
852 def thread_list(num)
853 =begin edoc
854 Method to list the state of a thread.
855
856 @param num thread number (int)
857 =end
858 th = get_thread(num)
859 if th == Thread.current
860 @stdout.print "+"
861 else
862 @stdout.print " "
863 end
864 @stdout.printf "%d ", num
865 @stdout.print th.inspect, "\t"
866 file = context(th).instance_eval{@file}
867 if file
868 @stdout.print file,":",context(th).instance_eval{@line}
869 end
870 @stdout.print "\n"
871 end
872
873 def thread_list_all
874 =begin edoc
875 Method to list the state of all threads.
876 =end
877 for th in @thread_list.values.sort
878 thread_list(th)
879 end
880 end
881
882 def make_thread_list
883 =begin edoc
884 Method to create a thread list.
885 =end
886 hash = {}
887 for th in Thread::list
888 next if (th[:__debugger_hidden__])
889 if @thread_list.key? th
890 hash[th] = @thread_list[th]
891 else
892 @max_thread += 1
893 hash[th] = @max_thread
894 end
895 end
896 @thread_list = hash
897 end
898
899 def debug_thread_info(input, binding_)
900 =begin edoc
901 Method handling the thread related debug commands.
902
903 @param input debug command (String)
904 @param binding_ reference to the binding object
905 =end
906 case input
907 when /^l(?:ist)?/
908 make_thread_list
909 thread_list_all
910
911 when /^c(?:ur(?:rent)?)?$/
912 make_thread_list
913 thread_list(@thread_list[Thread.current])
914
915 when /^(?:sw(?:itch)?\s+)?(\d+)/
916 make_thread_list
917 th = get_thread($1.to_i)
918 if th == Thread.current
919 @stdout.print "It's the current thread.\n"
920 else
921 thread_list(@thread_list[th])
922 context(th).stop_next
923 th.run
924 return :cont
925 end
926
927 when /^stop\s+(\d+)/
928 make_thread_list
929 th = get_thread($1.to_i)
930 if th == Thread.current
931 @stdout.print "It's the current thread.\n"
932 elsif th.stop?
933 @stdout.print "Already stopped.\n"
934 else
935 thread_list(@thread_list[th])
936 context(th).suspend
937 end
938
939 when /^resume\s+(\d+)/
940 make_thread_list
941 th = get_thread($1.to_i)
942 if th == Thread.current
943 @stdout.print "It's the current thread.\n"
944 elsif !th.stop?
945 @stdout.print "Already running."
946 else
947 thread_list(@thread_list[th])
948 th.run
949 end
950 end
951 end
952
953 def eventLoop
954 =begin edoc
955 Method calling the main event loop.
956 =end
957 @client.eventLoop
958 end
959
960 def eventPoll
961 =begin edoc
962 Method calling the main function polling for an event sent by the IDE.
963 =end
964 @client.eventPoll
965 end
966
967 def traceRuby?
968 =begin edoc
969 Method to check, if we should trace into the Ruby interpreter libraries.
970 =end
971 @client.traceRuby?
972 end
973 end
974
975
976 class Context
977 def eventLoop
978 =begin edoc
979 Method calling the main event loop.
980 =end
981 DEBUGGER__.eventLoop
982 end
983
984 def eventPoll
985 =begin edoc
986 Method calling the main function polling for an event sent by the IDE.
987 =end
988 DEBUGGER__.eventPoll
989 end
990
991 def traceRuby?
992 =begin edoc
993 Method to check, if we should trace into the Ruby interpreter libraries.
994 =end
995 DEBUGGER__.traceRuby?
996 end
997 end
998
999 require 'DebugProtocol'
1000
1001 class Client
1002 =begin edoc
1003 Class handling the connection to the IDE.
1004 =end
1005 def initialize( debugger )
1006 =begin edoc
1007 Constructor
1008
1009 @param debugger reference to the object having the IDE connection.
1010 =end
1011 @debugger = debugger
1012 end
1013
1014 def eventLoop
1015 =begin edoc
1016 Method calling the main event loop.
1017 =end
1018 @debugger.eventLoop()
1019 end
1020
1021 def eventPoll
1022 =begin edoc
1023 Method calling the main function polling for an event sent by the IDE.
1024 =end
1025 @debugger.eventPoll()
1026 end
1027
1028 def traceRuby?
1029 =begin edoc
1030 Method to check, if we should trace into the Ruby interpreter libraries.
1031 =end
1032 @debugger.traceRuby
1033 end
1034
1035 def printf( *args )
1036 =begin edoc
1037 Method to print something to the IDE.
1038
1039 @param *args Arguments to be printed.
1040 =end
1041 @debugger.write("#{args.join(', ')}\n")
1042 end
1043
1044 def printf_line(frames)
1045 =begin edoc
1046 Method to report the current line and the current stack trace to the IDE.
1047
1048 @param frames reference to the array containing the stack trace.
1049 =end
1050 fr_list = []
1051 for bind, file, line, id in frames
1052 break unless bind
1053 break if file =~ /\(eval\)/
1054 fr_list << [file, line, id ? id.id2name : '', '']
1055 end
1056
1057 @debugger.write("%s%s\n" % [ResponseLine, fr_list.inspect])
1058 end
1059
1060 def printf_excn(exclist)
1061 =begin edoc
1062 Method to report an exception to the IDE.
1063
1064 @param exclist info about the exception to be reported
1065 =end
1066 @debugger.write("%s%s\n" % [ResponseException, exclist.inspect])
1067 end
1068
1069 def printf_scriptExcn(exclist)
1070 =begin edoc
1071 Method to report a ScriptError to the IDE.
1072
1073 @param exclist info about the exception to be reported
1074 =end
1075 @debugger.write("%s%s\n" % [ResponseSyntax, exclist.inspect])
1076 end
1077
1078 def printf_clear_breakpoint(file, line)
1079 =begin edoc
1080 Method to report the deletion of a temporary breakpoint to the IDE.
1081
1082 @param file filename of the breakpoint (String)
1083 @param line line number of the breakpoint (int)
1084 =end
1085 @debugger.write("%s%s,%d\n" % [ResponseClearBreak, file, line])
1086 end
1087
1088 def printf_clear_watchexpression(cond)
1089 =begin edoc
1090 Method to report the deletion of a temporary watch expression to the IDE.
1091
1092 @param cond expression of the watch expression (String)
1093 =end
1094 @debugger.write("%s%s\n" % [ResponseClearWatch, cond])
1095 end
1096
1097 def printf_exit(status)
1098 =begin edoc
1099 Method to report the exit status to the IDE.
1100
1101 @param status exit status of the program (int)
1102 =end
1103 @debugger.write("%s%d\n" % [ResponseExit, status])
1104 end
1105 end
1106
1107 class Context
1108 def current_frame
1109 =begin edoc
1110 Method returning the current execution frame.
1111
1112 @return current execution frame
1113 =end
1114 @frames[@frame_pos]
1115 end
1116
1117 def get_frame(frameno)
1118 =begin edoc
1119 Method returning a specific execution frame.
1120
1121 @param frameno frame number of the frame to be returned (int)
1122 @return the requested execution frame
1123 =end
1124 @frames[frameno]
1125 end
1126
1127 def current_binding
1128 =begin edoc
1129 Method returning the binding object of the current execution frame.
1130
1131 @return binding object of the current execution frame
1132 =end
1133 @frames[@frame_pos][0]
1134 end
1135
1136 def get_binding(frameno)
1137 =begin edoc
1138 Method returning the binding object of a specific execution frame.
1139
1140 @param frameno frame number of the frame (int)
1141 @return the requested binding object
1142 =end
1143 @frames[frameno][0]
1144 end
1145 end
1146
1147 Thread.main["name"] = 'Main'
1148 end

eric ide

mercurial