/[eiffelstudio]/trunk/Src/bench/Eiffel/switch/communication/status/dotnet/application_execution_dotnet.e
ViewVC logotype

Contents of /trunk/Src/bench/Eiffel/switch/communication/status/dotnet/application_execution_dotnet.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 43404 - (show annotations)
Tue Jun 1 20:05:13 2004 UTC (15 years, 8 months ago) by jfiat
File size: 34270 byte(s)
added preference to disable/enable "JIT debugging" in order to control the optimization due to JIT debugging

1 indexing
2 description : "Controls execution of debugged application under dotnet."
3 date : "$Date$"
4 revision : "$Revision$"
5
6 class APPLICATION_EXECUTION_DOTNET
7
8 inherit
9 APPLICATION_EXECUTION_IMP
10 redefine
11 make
12 end
13
14 APPLICATION_STATUS_EXPORTER
15 export
16 {NONE} all
17 end
18
19 SHARED_IL_DEBUG_INFO_RECORDER
20 export
21 {NONE} all
22 end
23
24 EB_SHARED_DEBUG_TOOLS
25 export
26 {NONE} all
27 end
28
29 ICOR_EXPORTER -- debug trace purpose
30 export
31 {NONE} all
32 end
33
34 EIFNET_EXPORTER
35 export
36 {NONE} all
37 end
38
39 COMPILER_EXPORTER
40 export
41 {NONE} all
42 end
43
44 EIFNET_DEBUGGER_INFO_ACCESSOR
45 export
46 {NONE} all
47 end
48
49 SHARED_DEBUG_VALUE_KEEPER
50 export
51 {NONE} all
52 end
53
54 create {SHARED_APPLICATION_EXECUTION}
55 make
56
57 feature {SHARED_APPLICATION_EXECUTION} -- Initialization
58
59 make is
60 --
61 do
62 Precursor
63 create eifnet_debugger.make
64 end
65
66 feature {EIFNET_DEBUGGER, EIFNET_EXPORTER} -- Trigger eStudio done
67
68 estudio_callback_notify is
69 -- Once the callback is done, when ec is back to life
70 -- it will process this notification.
71 do
72 debug ("debugger_trace_callback_notify")
73 print ("Notify callback: " + Eifnet_debugger_info.last_managed_callback_name + "%N")
74 end
75 callback_notification_processed := False
76 if eifnet_debugger /= Void then
77 if eifnet_debugger.data_changed then
78 if
79 status.is_stopped
80 and then not status.is_evaluating
81 then
82 eifnet_debugger.reset_data_changed
83 if Eifnet_debugger_info.last_managed_callback_is_exit_process then --| Exit Process |--
84 notify_execution_on_exit_process
85 else
86 notify_execution_on_stopped
87 end
88 elseif --| Evaluation |--
89 Eifnet_debugger_info.last_managed_callback_is_eval_complete
90 and then status.is_evaluating
91 then
92 eifnet_debugger.reset_data_changed
93 notify_evaluation_done
94 end
95 end
96 end
97 callback_notification_processed := True
98 debug ("debugger_trace_callback_notify")
99 print ("End of estudio notification%N")
100 end
101 end
102
103 feature {EIFNET_EXPORTER, EB_EXPRESSION_EVALUATOR_TOOL} -- Trigger eStudio status
104
105 callback_notification_processed: BOOLEAN
106 -- Is callback notification processed and done ?
107
108 feature {APPLICATION_EXECUTION} -- load and save
109
110 load_dotnet_debug_info is
111 -- Load debug information (so far only the breakpoints)
112 local
113 w_dlg: EV_WARNING_DIALOG
114 do
115 Il_debug_info_recorder.load
116 if not Il_debug_info_recorder.load_successful then
117 if (create {EV_ENVIRONMENT}).application /= Void then
118 create w_dlg.make_with_text (Il_debug_info_recorder.loading_errors_message)
119 w_dlg.show
120 else
121 io.error.put_string (Il_debug_info_recorder.loading_errors_message)
122 end
123 end
124 end
125
126 feature -- Properties
127
128 status: APPLICATION_STATUS_DOTNET is
129 -- Status of the running dotnet application
130 do
131 Result ?= Application.status
132 end
133
134 set_status (a_status: like status) is
135 -- Set the value of Application status to `a_status'
136 do
137 Application.set_status (a_status)
138 end
139
140 feature {APPLICATION_EXECUTION} -- Properties
141
142 is_valid_object_address (addr: STRING): BOOLEAN is
143 -- Is object address `addr' valid?
144 -- (i.e Does bench know about it)
145 do
146 Result := True
147 end -- FIXME: JFIAT
148
149 feature -- Bridge to Debugger
150
151 exit_process_occurred: BOOLEAN is
152 -- Did the exit_process occurred ?
153 require
154 eifnet_debugger_exists: eifnet_debugger /= Void
155 do
156 Result := eifnet_debugger.exit_process_occurred
157 end
158
159 exception_occurred: BOOLEAN is
160 -- Last callback is about exception ?
161 require
162 eifnet_debugger_exists: eifnet_debugger /= Void
163 do
164 Result := eifnet_debugger.last_managed_callback_is_exception
165 end
166
167 exception_handled: BOOLEAN is
168 -- Last Exception is handled ?
169 -- if True => first chance
170 -- if False => The execution will terminate after.
171 require
172 eifnet_debugger_exists: eifnet_debugger /= Void
173 do
174 Result := eifnet_debugger.last_exception_is_handled
175 end
176
177 exception_details: TUPLE [STRING, STRING] is
178 -- class details , module details
179 require
180 exception_occurred: exception_occurred
181 local
182 l_class_details: STRING
183 l_module_details: STRING
184 retried: BOOLEAN
185 l_exception_info: EIFNET_DEBUG_VALUE_INFO
186 l_icd_exception: ICOR_DEBUG_VALUE
187 do
188 if not retried then
189 l_icd_exception := eifnet_debugger.active_exception_value
190 if l_icd_exception /= Void then
191 create l_exception_info.make (l_icd_exception)
192 l_class_details := l_exception_info.value_class_name
193 l_module_details := l_exception_info.value_module_file_name
194 Result := [l_class_details, l_module_details]
195 end
196 end
197 rescue
198 retried := True
199 retry
200 end
201
202 exception_to_string: STRING is
203 -- Exception "ToString" output
204 require
205 exception_occurred: exception_occurred
206 local
207 retried: BOOLEAN
208 l_icd_exception: ICOR_DEBUG_VALUE
209 l_exception_info: EIFNET_DEBUG_VALUE_INFO
210 do
211 if not retried then
212 l_icd_exception := eifnet_debugger.active_exception_value
213 create l_exception_info.make (l_icd_exception)
214
215 Result := eifnet_debugger.to_string_value_from_exception_object_value (Void,
216 l_icd_exception,
217 l_exception_info.interface_debug_object_value
218 )
219 end
220 rescue
221 retried := True
222 retry
223 end
224
225 exception_message: STRING is
226 -- Exception "GetMessage" output
227 require
228 exception_occurred: exception_occurred
229 local
230 retried: BOOLEAN
231 l_icd_exception: ICOR_DEBUG_VALUE
232 l_exception_info: EIFNET_DEBUG_VALUE_INFO
233 do
234 if not retried then
235 l_icd_exception := eifnet_debugger.active_exception_value
236 if l_icd_exception /= Void then
237 create l_exception_info.make (l_icd_exception)
238
239 Result := eifnet_debugger.get_message_value_from_exception_object_value (Void,
240 l_icd_exception,
241 l_exception_info.interface_debug_object_value
242 )
243 if Result = Void then
244 --| This could means the prog did exit_process
245 --| or .. anything else
246 Result := l_exception_info.value_class_name
247 end
248 end
249 end
250 rescue
251 retried := True
252 retry
253 end
254
255 eifnet_debugger: EIFNET_DEBUGGER
256 -- Access to the Dotnet Debugger
257
258 icd_string_value_from_string_class_object_value (icd_string_instance: ICOR_DEBUG_OBJECT_VALUE): ICOR_DEBUG_STRING_VALUE is
259 -- ICorDebugStringValue of the `icd_string_instance'.
260 do
261 Result := eifnet_debugger.icd_string_value_from_string_class_object_value (icd_string_instance)
262 end
263
264 feature -- Execution
265
266 run (args, cwd: STRING) is
267 -- Run application with arguments `args' in directory `cwd'.
268 -- If `is_running' is false after the
269 -- execution of this routine, it means that
270 -- the application was unable to be launched
271 -- due to the time_out (see `eiffel_timeout_message').
272 -- Before running the application you must check
273 -- to see if the debugged information is up to date.
274 local
275 app: STRING
276 l_status: APPLICATION_STATUS_DOTNET
277 do
278 create eifnet_debugger.make
279 eifnet_debugger.initialize_debugger_session
280 if eifnet_debugger.is_debugging then
281 app := Eiffel_system.application_name (True)
282
283 eifnet_debugger.set_debug_param_directory (cwd)
284 eifnet_debugger.set_debug_param_executable (app)
285 eifnet_debugger.set_debug_param_arguments (args)
286
287 eifnet_debugger_info.set_jit_debugging_mode (optimized_jit_debugging_enabled)
288
289 process_before_running
290 create l_status.do_nothing
291 set_status (l_status)
292
293 eifnet_debugger.do_run
294
295 if status /= Void then
296 -- Application was able to be started
297 status.set_is_stopped (False)
298 end
299 end
300 end
301
302 continue (kept_objects: LINKED_SET [STRING]) is
303 -- Continue the running of the application and keep the
304 -- objects addresses in `kept_objects'. Objects that are not in
305 -- `kept_objects' will be removed and will be not under the
306 -- control of bench. Therefore, these addresses cannot be
307 -- referenced the next time we stop the application.
308 do
309 --| This is not require for dotnet system, but we may adapt it for others uses
310 -- keep_objects (kept_objects)
311 keep_only_objects (kept_objects)
312 -- cont_request.send_breakpoints
313 inspect application.execution_mode
314 when feature {EXEC_MODES}.step_into then
315 step_into
316 when feature {EXEC_MODES}.step_by_step then
317 step_next
318 when feature {EXEC_MODES}.out_of_routine then
319 step_out
320 else
321 process_before_running
322 eifnet_debugger.set_last_control_mode_is_continue
323
324 status.set_is_stopped (False)
325 eifnet_debugger.do_continue
326 end
327 end
328
329 interrupt is
330 -- Send an interrupt to the application
331 -- which will stop at the next breakable line number
332 do
333 if eifnet_debugger.icor_debug_process /= Void then
334 debug ("debugger_eifnet_data")
335 print ("IsRunning :: " + eifnet_debugger.icor_debug_process.is_running.out + "%N")
336 end
337
338 process_before_running
339 eifnet_debugger.set_last_control_mode_is_stop
340
341 eifnet_debugger.do_stop
342
343 debug ("debugger_eifnet_data")
344 print ("IsRunning :: " + eifnet_debugger.icor_debug_process.is_running.out + "%N")
345 end
346
347 --| Here debugger may not be synchronized |--
348 Eifnet_debugger_info.reset_current_callstack
349 Eifnet_debugger_info.init_current_callstack
350 debug ("DEBUGGER_TRACE_EIFNET")
351 debug_display_threads
352 end
353 eifnet_debugger.do_step_next
354 end
355 end
356
357 notify_newbreakpoint is
358 -- Send an interrupt to the application
359 -- which will stop at the next breakable line number
360 -- in order to record the new breakpoint(s) before
361 -- automatically resuming its execution.
362 do
363 send_breakpoints
364 end
365
366 kill is
367 -- Ask the application to terminate itself.
368 do
369 if eifnet_debugger.is_debugging then
370 eifnet_debugger.set_last_control_mode_is_kill
371 eifnet_debugger.terminate_debugger
372 end
373 end
374
375 process_termination is
376 -- Process the termination of the executed
377 -- application. Also execute the `termination_command'.
378 do
379 -- Eifnet_debugger.terminate_debugger_session
380 -- this is now called directly from EIFNET_DEBUGGER.on_exit_process
381 end
382
383 feature -- Controle execution
384
385 process_before_running is
386 local
387 l_entry_point_feature: E_FEATURE
388 do
389 debug ("debugger_trace_operation")
390 print ("%N%N")
391 print ("/\/\/\/\/\/\ Process before running /\/\/\/\/\/\/\/\/\%N")
392 print ("%N%N")
393 end
394
395 Application.debug_info.update
396 inspect Application.execution_mode
397 when feature {EXEC_MODES}.no_stop_points then
398 send_no_breakpoints
399 when feature {EXEC_MODES}.step_by_step, feature {EXEC_MODES}.step_into then
400 if not Application.is_running then
401 debug ("DEBUGGER_TRACE_STEPPING")
402 print ("Let's add a breakpoint at the entry point of the system%N")
403 end
404 l_entry_point_feature := Il_debug_info_recorder.entry_point_feature_i.e_feature
405 Application.enable_breakpoint (l_entry_point_feature, 1)
406 send_breakpoints
407 Application.remove_breakpoint (l_entry_point_feature , 1)
408 else
409 send_breakpoints
410 end
411 else
412 send_breakpoints
413 end
414
415 debug ("debugger_eifnet_data")
416 debug_display_threads
417 end
418
419 Eifnet_debugger_info.init_current_callstack
420 Eifnet_debugger_info.save_current_stack_as_previous
421 Eifnet_debugger.set_last_control_mode_is_nothing
422 end
423
424 debug_display_threads is
425 --
426 local
427 l_process: ICOR_DEBUG_PROCESS
428 l_enum_thread: ICOR_DEBUG_THREAD_ENUM
429 l_threads: ARRAY [ICOR_DEBUG_THREAD]
430 i: INTEGER
431 l_th: ICOR_DEBUG_THREAD
432 do
433 l_process := Eifnet_debugger_info.icd_process
434 if l_process /= Void then
435 l_enum_thread := l_process.enumerate_threads
436 if l_enum_thread /= Void and then l_enum_thread.count > 0 then
437 l_threads := l_enum_thread.next (l_enum_thread.count)
438 print ("[info] => " + l_threads.count.out + " Threads.%N")
439 print (" => last :: " + Eifnet_debugger_info.icd_thread.get_id.to_hex_string + "%N")
440 print (" => helper :: " + l_process.get_helper_thread_id.to_hex_string + "%N")
441
442 from
443 i := l_threads.lower
444 until
445 i > l_threads.upper
446 loop
447 l_th := l_threads.item (i)
448 print (" => " + l_th.get_id.to_hex_string
449 + "%N"
450 )
451 i := i + 1
452 end
453 end
454 end
455 end
456
457 feature -- Stepping
458
459 step_out is
460 -- Stepping out of the routine
461 do
462 process_before_running
463
464 debug ("debugger_trace_stepping")
465 print ("++++++++++++++++++++++++++++++++++++++++++++++++++++++%N")
466 print ("++ OPERATION :: APPLICATION_EXECUTION_DOTNET::step_out%N")
467 print ("++++++++++++++++++++++++++++++++++++++++++++++++++++++%N")
468 end
469 if eifnet_debugger.stepping_possible then
470 eifnet_debugger.set_last_control_mode_is_out
471
472 eifnet_debugger.do_step_out
473 status.set_is_stopped (False)
474 end
475 end
476
477 step_into is
478 -- Stepping into next routine
479 do
480 process_before_running
481
482 debug ("debugger_trace_stepping")
483 print ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++%N")
484 print ("++ OPERATION :: APPLICATION_EXECUTION_DOTNET::step_into%N")
485 print ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++%N")
486 end
487 eifnet_debugger.set_last_control_mode_is_into
488 step_range (True)
489 end
490
491 step_next is
492 -- Stepping to next step point
493 do
494 process_before_running
495
496 debug ("debugger_trace_stepping")
497 print ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++%N")
498 print ("++ OPERATION :: APPLICATION_EXECUTION_DOTNET::step_next%N")
499 print ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++%N")
500 end
501
502 if
503 (status.e_feature /= Void)
504 and then (status.break_index = status.e_feature.number_of_breakpoint_slots)
505 then
506 --| This is an optimisation when we are at the end of a routine
507 --| End of feature, go out ...
508 step_out
509 else
510 eifnet_debugger.set_last_control_mode_is_next
511 step_range (False)
512 end
513 end
514
515 feature {NONE} -- Stepping
516
517 step_range (a_bstep_in: BOOLEAN) is
518 -- Step over the next range
519 -- faster than stepping next for each dotnet step.
520 local
521 l_current_il_offset: INTEGER
522 l_call_stack_element: CALL_STACK_ELEMENT_DOTNET
523 do_not_use_range: BOOLEAN
524 l_ranges: ARRAY [TUPLE [INTEGER,INTEGER]]
525 do
526 do_not_use_range := False
527 if do_not_use_range then
528 if a_bstep_in then
529 eifnet_debugger.do_step_into
530 else
531 eifnet_debugger.do_step_next
532 end
533 status.set_is_stopped (False)
534 else
535 if eifnet_debugger.stepping_possible then
536 l_call_stack_element := status.current_stack_element_dotnet
537 if l_call_stack_element /= Void then
538 l_current_il_offset := l_call_stack_element.il_offset
539 debug ("debugger_trace_stepping")
540 print (" ### Current IL OffSet = 0x"+l_current_il_offset.to_hex_string+" ~ "+l_current_il_offset.out+" %N")
541 end
542 l_ranges := Il_debug_info_recorder.next_feature_breakable_il_range_for (
543 l_call_stack_element.dynamic_type,
544 l_call_stack_element.routine.associated_feature_i,
545 l_current_il_offset
546 )
547 end
548 if l_ranges /= Void then
549 debug ("debugger_trace_stepping")
550 print ("[>] Go for next point %N")
551 end
552 eifnet_debugger.do_step_range (a_bstep_in, l_ranges)
553 else
554 debug ("debugger_trace_stepping")
555 print ("[>] Go out of routine (from "+l_current_il_offset.to_hex_string+")%N")
556 end
557 eifnet_debugger.do_step_out
558 -- eifnet_debugger.do_step_range (a_bstep_in, <<[0 , l_current_il_offset]>>)
559 end
560 status.set_is_stopped (False)
561 end
562 end
563 end
564
565 feature {NONE} -- Entry Point
566
567 is_entry_point (f: E_FEATURE): BOOLEAN is
568 -- Is the entry point of the system ?
569 do
570 Result := (f.name).is_equal (Eiffel_system.System.creation_name)
571 and then f.written_class.is_equal (Eiffel_system.System.root_class.compiled_class)
572 end
573
574 feature -- Breakpoints controller
575
576 send_breakpoints is
577 -- Synchronise the EiffelStudio BreakPoints with the application ones in execution
578 local
579 l_bp_list: BREAK_LIST
580 l_bp_item: BREAKPOINT
581 do
582 l_bp_list := Application.debug_info.breakpoints
583
584 from
585 l_bp_list.start
586 until
587 l_bp_list.off
588 loop
589 l_bp_item := l_bp_list.item_for_iteration
590 inspect l_bp_item.update_status
591 when feature {BREAKPOINT}.Breakpoint_to_add then
592 debug ("debugger_trace_breakpoint")
593 print ("ADD BP :: " + l_bp_item.routine.associated_class.name_in_upper +"."+ l_bp_item.routine.name +" @ " + l_bp_item.breakable_line_number.out + "%N")
594 end
595 add_dotnet_breakpoint (l_bp_item)
596 l_bp_item.set_application_set
597 when feature {BREAKPOINT}.Breakpoint_to_remove then
598 debug ("debugger_trace_breakpoint")
599 print ("DEL BP :: " + l_bp_item.routine.associated_class.name_in_upper +"."+ l_bp_item.routine.name +" @ " + l_bp_item.breakable_line_number.out + "%N")
600 end
601 remove_dotnet_breakpoint (l_bp_item)
602 l_bp_item.set_application_not_set
603 when feature {BREAKPOINT}.Breakpoint_do_nothing then
604 debug ("debugger_trace_breakpoint")
605 print ("NADA BP %N")
606 end
607 end
608 l_bp_list.forth
609 end
610
611 debug ("debugger_trace_breakpoint")
612 Eifnet_debugger_info.display_bp_list_status
613 end
614 end
615
616 send_no_breakpoints is
617 -- Remove BreakPoints from the application ones in execution
618 -- to perform a NoStopPoint operation
619 local
620 l_bp_list: BREAK_LIST
621 l_bp_item: BREAKPOINT
622 do
623 l_bp_list := Application.debug_info.breakpoints
624
625 from
626 l_bp_list.start
627 until
628 l_bp_list.off
629 loop
630 l_bp_item := l_bp_list.item_for_iteration
631 if l_bp_item.is_set_for_application then
632 debug ("debugger_trace_breakpoint")
633 print ("REMOVE APPLICATION BP :: " + l_bp_item.routine.associated_class.name_in_upper +"."+ l_bp_item.routine.name +" @ " + l_bp_item.breakable_line_number.out + "%N")
634 end
635 remove_dotnet_breakpoint (l_bp_item)
636 l_bp_item.set_application_not_set
637 -- then next time we go with StopPoint enable ... we'll add them again
638 end
639 l_bp_list.forth
640 end
641 end
642
643 feature -- BreakPoints
644
645 add_dotnet_breakpoint (bp: BREAKPOINT) is
646 -- enable the `i'-th breakpoint of `f'
647 -- if no breakpoint already exists for 'f' at 'i', a breakpoint is created
648 local
649 f: E_FEATURE
650 i: INTEGER
651
652 l_feature_token: INTEGER
653 l_il_offset_list: LIST [INTEGER]
654 l_il_offset: INTEGER
655
656 l_module_name: STRING
657 l_class_c: CLASS_C
658 l_class_token: INTEGER
659
660 l_is_entry_point: BOOLEAN
661
662 l_class_type_list: TYPE_LIST
663 l_class_type: CLASS_TYPE
664 do
665 f := bp.routine
666 i := bp.breakable_line_number
667 debug ("debugger_trace_breakpoint")
668 print ("AddBreakpoint " + f.name + " index=" + i.out + "%N")
669 display_feature_info (f)
670 end
671
672 l_class_c := f.written_class
673 l_is_entry_point := is_entry_point (f)
674
675 --| loop on the different derivation of a generic class
676 l_class_type_list := l_class_c.types
677 from
678 l_class_type_list.start
679 until
680 l_class_type_list.after
681 loop
682 l_class_type := l_class_type_list.item
683 l_module_name := Il_debug_info_recorder.module_file_name_for_class (l_class_type)
684 l_class_token := Il_debug_info_recorder.class_token (l_module_name, l_class_type)
685 l_feature_token := Il_debug_info_recorder.feature_token_for_feat_and_class_type (f.associated_feature_i, l_class_type)
686
687 l_il_offset_list := Il_debug_info_recorder.feature_breakable_il_line_for (l_class_type, f.associated_feature_i, i)
688 if l_il_offset_list /= Void then
689 from
690 l_il_offset_list.start
691 until
692 l_il_offset_list.after
693 loop
694 l_il_offset := l_il_offset_list.item
695 eifnet_debugger.Eifnet_debugger_info.request_breakpoint_add (bp, l_module_name, l_class_token, l_feature_token, l_il_offset)
696
697 if l_is_entry_point and then Il_debug_info_recorder.entry_point_token /= l_feature_token then
698 eifnet_debugger.Eifnet_debugger_info.request_breakpoint_add (bp,
699 l_module_name, l_class_token, Il_debug_info_recorder.entry_point_token , l_il_offset
700 )
701 end
702 l_il_offset_list.forth
703 end
704 else
705 check False end -- Should not occurs, unless data are corrupted
706 end
707 l_class_type_list.forth
708 end
709 end
710
711 remove_dotnet_breakpoint (bp: BREAKPOINT) is
712 -- remove the `i'-th breakpoint of `f'
713 -- if no breakpoint already exists for 'f' at 'i', a breakpoint is created
714 local
715 f: E_FEATURE
716 i: INTEGER
717
718 l_feature_token: INTEGER
719 l_il_offset_list: LIST [INTEGER]
720 l_il_offset: INTEGER
721
722 l_module_name: STRING
723 l_class_c: CLASS_C
724 l_class_token: INTEGER
725
726 l_is_entry_point: BOOLEAN
727
728 l_class_type_list: TYPE_LIST
729 l_class_type: CLASS_TYPE
730
731 do
732 f := bp.routine
733 i := bp.breakable_line_number
734 debug ("debugger_trace_breakpoint")
735 print ("RemoveBreakpoint " + f.name + " index=" + i.out + "%N")
736 display_feature_info (f)
737 end
738
739 l_class_c := f.written_class
740
741 l_is_entry_point := is_entry_point (f)
742
743 --| loop on the different derivation of a generic class
744 l_class_type_list := l_class_c.types
745 from
746 l_class_type_list.start
747 until
748 l_class_type_list.after
749 loop
750 l_class_type := l_class_type_list.item
751 l_module_name := Il_debug_info_recorder.module_file_name_for_class (l_class_type)
752 l_class_token := Il_debug_info_recorder.class_token (l_module_name, l_class_type)
753 l_feature_token := Il_debug_info_recorder.feature_token_for_feat_and_class_type (f.associated_feature_i, l_class_type)
754
755 l_il_offset_list := Il_debug_info_recorder.feature_breakable_il_line_for (l_class_type, f.associated_feature_i, i)
756 if l_il_offset_list /= Void then
757 from
758 l_il_offset_list.start
759 until
760 l_il_offset_list.after
761 loop
762 l_il_offset := l_il_offset_list.item
763 eifnet_debugger.Eifnet_debugger_info.request_breakpoint_remove (bp, l_module_name, l_class_token, l_feature_token, l_il_offset)
764
765 if l_is_entry_point and then Il_debug_info_recorder.entry_point_token /= l_feature_token then
766 eifnet_debugger.Eifnet_debugger_info.request_breakpoint_remove (bp,
767 l_module_name, l_class_token, Il_debug_info_recorder.entry_point_token , l_il_offset
768 )
769 end
770 l_il_offset_list.forth
771 end
772 else
773 check False end -- Should not occurs, unless data are corrupted
774 end
775 l_class_type_list.forth
776 end
777 end
778
779 feature {NONE} -- Implementation
780
781 display_feature_info (f: E_FEATURE) is
782 -- Display info related to feature `f'
783 -- debug purpose only
784 require
785 f /= Void
786 local
787 l_class_c: CLASS_C
788
789 l_str: STRING
790 l_types: TYPE_LIST
791 l_class_type: CLASS_TYPE
792
793 l_class_token: INTEGER
794 l_module_name: STRING
795 do
796 l_str := "----%N"
797 l_str.append_string ("%TFeature :: ")
798
799 l_class_c := f.written_class
800
801 l_str.append_string ("%N%T Associated class="+ f.associated_class.name_in_upper + "%T")
802 l_str.append_string ("%N%T Written class="+ f.written_class.name_in_upper )
803
804 if l_class_c /= Void then
805 l_str.append_string ("%N%T class id=" + l_class_c.class_id.out + " [" + l_class_c.name_in_upper)
806
807 if l_class_c.is_generic then
808 l_str.append_string (" !Generic! ")
809 l_types := l_class_c.types
810 from
811 l_types.start
812 until
813 l_types.after
814 loop
815 l_class_type := l_types.item
816 l_module_name := Il_debug_info_recorder.module_file_name_for_class (l_class_type)
817 l_class_token := Il_debug_info_recorder.class_token (l_module_name, l_class_type)
818 l_str.append_string ("%T" + l_class_token.out)
819 l_str.append_string (" ~ 0x" + l_class_token.to_hex_string)
820 l_types.forth
821 end
822 else
823 l_types := l_class_c.types
824 l_class_type := l_types.first
825 l_module_name := Il_debug_info_recorder.module_file_name_for_class (l_class_type)
826 l_class_token := Il_debug_info_recorder.class_token (l_module_name, l_class_type)
827
828 l_str.append_string (":" + l_class_token.out)
829 l_str.append_string (" ~ 0x" + l_class_token.to_hex_string)
830 end
831 l_str.append_string ("]")
832 l_str.append_string ("%N")
833
834 end
835 l_str.append_string ("%T module_name="+Il_debug_info_recorder.module_file_name_for_class (l_class_type) )
836
837 print (l_str)
838 print ("%N")
839 end
840
841 feature -- Evaluation
842
843 notify_evaluation_done is
844 -- Notify that an evaluation is done.
845 do
846 debug ("debugger_trace")
847 print ("%N%T !!! notify_evaluation_done !!! %N")
848 end
849 end
850
851 feature {NONE} -- Events on notification
852
853 notify_execution_on_exit_process is
854 -- Notify the system is exiting
855 do
856 --| We need to stop
857 --| Already "stopped" but let's be sure ..
858
859 status.set_is_stopped (True)
860 eifnet_debugger.notify_exit_process_occurred
861 eifnet_debugger.on_exit_process
862 end
863
864 notify_execution_on_stopped is
865 local
866 need_to_continue: BOOLEAN
867 do
868 debug ("debugger_trace")
869 print ("%N*** REASON TO STOP *** %N")
870 print ("%T Callback = " + Eifnet_debugger_info.last_managed_callback_name +"%N")
871
872 if Eifnet_debugger_info.last_managed_callback_is_breakpoint then
873 display_breakpoint_info (Eifnet_debugger_info.icd_breakpoint)
874 end
875 end -- debug
876
877 --| Useless, but we may need it one day
878 -- Application_notification_controller.notify_on_before_stopped
879
880 --| on top of the stack = current stack/feature
881 application.set_current_execution_stack_number (1)
882
883 --| We need to stop
884 --| Already "stopped" but let's be sure ..
885 status.set_is_stopped (True)
886 status.set_top_level
887
888 --| CallStack
889 status.reload_call_stack --| since we stop, let's reload the whole callstack
890
891 debug ("debugger_trace_callstack")
892 io.put_new_line
893 print (" ########################################### %N")
894 print (" ### CallStack : Head level ## 0x"+Eifnet_debugger_info.last_step_complete_reason.to_hex_string +" ## %N")
895 print (" ########################################### %N")
896 --| uncomment next ligneto have different kind of debug output
897 -- io.put_new_line
898 -- print (frame_callstack_info (Eifnet_debugger.active_frame))
899 -- io.put_new_line
900 display_full_callstack_info
901 end
902
903 if Eifnet_debugger_info.last_managed_callback_is_step_complete then
904 status.set_reason_as_step
905 elseif Eifnet_debugger_info.last_managed_callback_is_breakpoint then
906 status.set_reason_as_break
907 need_to_continue := not do_stop_on_breakpoint
908 elseif Eifnet_debugger_info.last_managed_callback_is_exception then
909 status.set_reason_as_raise
910 status.set_exception (0, "Exception occurred .. waiting for information")
911 end
912 --| not true in case of empty stack .. when exception occurs during launching
913 -- set_current_execution_stack (1)
914 Application.set_current_execution_stack_number (Application.number_of_stack_elements)
915
916 if need_to_continue then
917 status.set_is_stopped (False)
918 eifnet_debugger_info.set_data_changed (False)
919 eifnet_debugger.do_continue
920 else
921 Application_notification_controller.notify_on_after_stopped
922 end
923 end
924
925 do_stop_on_breakpoint: BOOLEAN is
926 -- In case of conditional breakpoint, do we really stop on it ?
927 local
928 l_bp: BREAKPOINT
929 expr: EB_EXPRESSION
930 evaluator: DBG_EXPRESSION_EVALUATOR
931 do
932 if eifnet_debugger_info.last_control_mode_is_stepping then
933 debug ("debugger_trace")
934 print ("Stepping then continue ..%N")
935 end
936 Result := True
937 else
938 l_bp := Eifnet_debugger_info.current_breakpoint
939 if l_bp /= Void and then l_bp.has_condition then
940 debug ("debugger_trace")
941 print ("CONDITIONAL BP %N")
942 end
943 expr := l_bp.condition
944 if expr /= Void then
945 expr.evaluate
946 evaluator := expr.expression_evaluator
947 if evaluator.error_message = Void then
948 Result := evaluator.final_result_is_true_boolean_value
949 else
950 Result := False
951 end
952 else
953 Result := True
954 end
955 else
956 Result := True
957 end
958 end
959 end
960
961 display_breakpoint_info (icd_bp: ICOR_DEBUG_BREAKPOINT) is
962 -- display information related to `icd_bp'
963 -- debug purpose only
964 local
965 l_icd_bp: ICOR_DEBUG_BREAKPOINT
966 l_icd_func_bp: ICOR_DEBUG_FUNCTION_BREAKPOINT
967 l_function: ICOR_DEBUG_FUNCTION
968 do
969 print ("%T Breakpoint:%N")
970 l_icd_bp := icd_bp
971 l_icd_func_bp := l_icd_bp.query_interface_icor_debug_function_breakpoint
972 if l_icd_func_bp /= Void then
973
974 print ("%T - Offset = " + l_icd_func_bp.get_offset.out + "%N")
975 l_function := l_icd_func_bp.get_function
976 print ("%T - Function = " + l_function.to_string + "%N")
977 end
978 end
979
980 feature -- Call stack related
981
982 frame_callstack_info (a_frame: ICOR_DEBUG_FRAME): STRING is
983 -- obsolete "To remove soon or later, this is just a debug use for now"
984 -- Called by `select_actions' of `but_callstack_update'.
985 local
986 l_frame_il: ICOR_DEBUG_IL_FRAME
987 l_output: STRING
988
989
990 l_func: ICOR_DEBUG_FUNCTION
991 l_class_token: INTEGER
992 l_feature_token: INTEGER
993 l_module_name: STRING
994 l_module_display: STRING
995
996 l_class_type: CLASS_TYPE
997 l_class_name: STRING
998 l_feature_i : FEATURE_I
999 l_feature_name: STRING
1000
1001 l_eiffel_bp_slot: INTEGER
1002 l_il_offset: INTEGER
1003 do
1004 create l_output.make (100)
1005 if a_frame = Void then
1006 --| FIXME: JFIAT
1007 l_output := "Debugger not synchronized => no information available%N"
1008 else
1009 l_frame_il := a_frame.query_interface_icor_debug_il_frame
1010 if a_frame.last_call_succeed and then l_frame_il /= Void then
1011 l_func := l_frame_il.get_function
1012 l_feature_token := l_func.get_token
1013 l_class_token := l_func.get_class.get_token
1014 l_module_name := l_func.get_module.get_name
1015
1016 l_module_display := l_module_name.twin
1017 l_module_display.keep_tail (20)
1018 l_module_display.prepend_string (" ..")
1019
1020 if il_debug_info_recorder.has_info_about_module (l_module_name) then
1021 l_class_type := Il_debug_info_recorder.class_type_for_module_class_token (l_module_name, l_class_token)
1022 l_feature_i := Il_debug_info_recorder.feature_i_by_module_feature_token (l_module_name, l_feature_token)
1023 end
1024 if l_class_type /= Void then
1025 l_class_name := l_class_type.associated_class.name_in_upper
1026 else
1027 l_class_name := "<?"+ l_class_token.out + "?>"
1028 end
1029 if l_feature_i /= Void then
1030 l_feature_name := Il_debug_info_recorder.feature_i_by_module_feature_token (l_module_name, l_feature_token).feature_name
1031 else
1032 l_feature_name := "<?"+ l_feature_token.out + "?>"
1033 end
1034
1035 if l_class_type /= Void and then l_feature_i /= Void then
1036 l_il_offset := l_frame_il.get_ip
1037 l_eiffel_bp_slot := Il_debug_info_recorder.feature_eiffel_breakable_line_for_il_offset(l_class_type, l_feature_i, l_il_offset)
1038 l_output.append_string (" + <"
1039 + l_eiffel_bp_slot.out
1040 + " | "
1041 + l_il_offset.out + ":0x" + l_il_offset.to_hex_string + "> "
1042 + l_class_name + "." + l_feature_name + "%N"
1043 + "%T0x"+l_class_token.to_hex_string
1044 + " :: 0x"+ l_feature_token.to_hex_string
1045 + "%N%T Module=" + l_module_display
1046 )
1047
1048 l_output.append_string ("%N")
1049 else
1050 l_output.append_string (" - <"+ l_frame_il.get_ip.out + ":0x" + l_frame_il.get_ip.to_hex_string + "> ")
1051 l_output.append_string (" [???] ")
1052 if l_class_type /= Void then
1053 l_output.append_string ("%T " + l_class_name)
1054 end
1055 if l_feature_i /= Void then
1056 l_output.append_string ("." + l_feature_name)
1057 end
1058
1059 l_output.append_string ("%N")
1060 l_output.append_string ("%T0x" + l_class_token.to_hex_string )
1061 l_output.append_string (" :: 0x"+l_feature_token.to_hex_string)
1062 l_output.append_string (" module=" + l_module_display + "%N")
1063 end
1064
1065 end
1066 end
1067 Result := l_output
1068 end
1069
1070 display_full_callstack_info is
1071 -- obsolete "To remove soon or later, this is just a debug use for now"
1072 -- Called by `select_actions' of `but_callstack_update'.
1073 local
1074 l_active_thread: ICOR_DEBUG_THREAD
1075 l_enum_chain: ICOR_DEBUG_CHAIN_ENUM
1076 l_chain: ICOR_DEBUG_CHAIN
1077 l_enum_frames: ICOR_DEBUG_FRAME_ENUM
1078 l_chains: ARRAY [ICOR_DEBUG_CHAIN]
1079 l_frames: ARRAY [ICOR_DEBUG_FRAME]
1080 l_frame: ICOR_DEBUG_FRAME
1081 c: INTEGER
1082 i: INTEGER
1083 l_output: STRING
1084
1085 do
1086 l_active_thread := Eifnet_debugger.icor_debug_thread
1087
1088 l_enum_chain := l_active_thread.enumerate_chains
1089 if l_active_thread.last_call_succeed and then l_enum_chain.get_count > 0 then
1090 l_chains := l_enum_chain.next (l_enum_chain.get_count)
1091 from
1092 c := l_chains.lower
1093 until
1094 c > l_chains.upper
1095 loop
1096 l_chain := l_chains @ c
1097 if l_chain /= Void then
1098
1099 l_output := "%N ###################################################### %N"
1100 l_output.append_string (" Callstack from Chain : " + l_chain.item.out + "%N")
1101 l_output.append_string (" ###################################################### %N%N")
1102
1103 l_enum_frames := l_chain.enumerate_frames
1104 if l_chain.last_call_succeed and then l_enum_frames.get_count > 0 then
1105 l_frames := l_enum_frames.next (l_enum_frames.get_count)
1106 from
1107 i := l_frames.lower
1108 until
1109 i > l_frames.upper
1110 loop
1111 l_frame := l_frames @ i
1112 l_output.append_string ("... chain::" + c.out + " frame::" + i.out + " =%N")
1113 l_output.append_string (frame_callstack_info (l_frame))
1114 i := i + 1
1115 end
1116 end
1117 end
1118
1119 c := c + 1
1120 end
1121 end
1122
1123 io.put_new_line
1124 io.put_new_line
1125 io.put_string (l_output)
1126 io.put_new_line
1127 end
1128
1129 feature -- Object Keeper
1130
1131 recycle_kept_object is
1132 -- recycle the "keeper" container
1133 do
1134 Debug_value_keeper.recycle
1135 end
1136
1137 keep_only_objects (a_addresses: LIST [STRING]) is
1138 -- Remove all ref kept, and keep only the ones contained in `a_addresses'
1139 do
1140 Debug_value_keeper.keep_only (a_addresses)
1141 end
1142
1143 kept_object_item (a_address: STRING): ABSTRACT_DEBUG_VALUE is
1144 -- Keep this object addressed by `a_address'
1145 require
1146 know_about_object: know_about_kept_object (a_address)
1147 do
1148 Result := Debug_value_keeper.item (a_address)
1149 end
1150
1151 know_about_kept_object (a_address: STRING): BOOLEAN is
1152 -- Do we have a reference for the object addressed by `a_address' ?
1153 do
1154 Result := Debug_value_keeper.know_about (a_address)
1155 end
1156
1157 end -- class APPLICATION_EXECUTION_DOTNET

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23