Created version for 17.01.

git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@1789 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
eiffel-org
2017-03-10 08:53:03 +00:00
parent 65b7ae1274
commit cb0518b8e1
2887 changed files with 59843 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
[[Property:title|Exploring an application dynamic state]]
[[Property:weight|2]]
[[Property:uuid|0dd359d5-4f84-75c6-1c8c-c4091e916670]]
To view the dynamic state of a debugged application, just stop it at the point where you want to see its context. The debugger tools will automatically be popped up then, yielding the call stack of the application, as well as the state of the objects located in the object tree, which include at least the object corresponding to the level of the call stack where the call stack cursor [[Image:callstack-active-arrow-icon]] is.
To see at which point the features in the call stack have stopped, just click the feature on which you want this information in the call stack. Doing this will change the cursor position in the call stack and display the flat view of the feature in the context tool.
To follow an object state between pauses of the application, pick and drop it into the object tree, which will make it stay in it.
You can also query features dynamically by using the evaluation tool, which can be very useful to have glimpses of the C memory of the system, for instance.
{{seealso|<br/>
[[Interrupting an application|Pausing an application]] <br/>
[[Call stack tool]] <br/>
[[Object tool]] <br/>
[[Expression evaluation|Evaluation tool]] }}

View File

@@ -0,0 +1,12 @@
[[Property:title|Handling exceptions]]
[[Property:weight|4]]
[[Property:uuid|43ce73b9-3ac4-4f71-34a3-f359a66d9082]]
It is possible to raise and catch exceptions in Eiffel. Catching exceptions is done by using the rescue keyword. The [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] class provides helper features to analyze the caught exception and handle it.
The [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] class also provides ways to raise exception, via its feature [[ref:libraries/base/reference/exceptions_flatshort|raise]] .
When an exception is raised while the application is being debugged, the application stops immediately and the debugger displays the context in which the exception occurred, whether or not the exception is rescued.
{{seealso|<br/>
[[ET: Design by Contract (tm), Assertions and Exceptions|Reference of exceptions]] }}

View File

@@ -0,0 +1,5 @@
[[Property:title|Running and debugging]]
[[Property:weight|4]]
[[Property:uuid|58896f87-21d7-917d-6d91-661523d8afa9]]

View File

@@ -0,0 +1,18 @@
[[Property:title|Interrupting an application]]
[[Property:weight|1]]
[[Property:uuid|89bc6f76-ca23-950f-485a-35973022554b]]
There are two ways a debugged application can be interrupted: its execution can be paused, or it can be killed.
Two methods can be used to pause a debugged application:
* The [[Pause an application]] , located in both the debug menu and the project toolbar.
* Breakpoints, which make it easy to stop the application at a precise point.
To kill a debugged application, use the [[Stop a debugged application]] , located in both the debug menu and the project toolbar.
{{seealso|<br/>
[[Running an application|Running a program]] <br/>
[[Using breakpoints|Using breakpoints]] }}

View File

@@ -0,0 +1,72 @@
[[Property:title|Profiling]]
[[Property:weight|7]]
[[Property:uuid|cd9f3f2d-25bf-4b1a-eaf9-9b9d056228eb]]
The profiler is a tool that gives dynamic execution time information. It is very useful to detect which parts of a program need to be optimized most.
To use the profiler, the first thing to do is to enable it.
To enable the profiler:
* Open the [[General Target Options|Project Settings]] dialog.
* In the '''Target''' section, enable '''Profile'''.
* Click '''OK'''.
* You must [[Generating executables|recompile]] your project for the changes to take effect.
By default the profiler will profile the entire program. However it is possible to enable or disable the profiler on certain clusters only. To do this:
* Open the [[Group Options|Project Settings]] dialog.
* In the '''Clusters''' property, check the '''Profile''' boolean value in the clusters where you want the profiler to be enabled.
* Click '''Apply''' or '''OK'''.
* You must [[Generating executables|recompile]] your project for the changes to take effect.
It is also possible to dynamically start and stop the profiler in a program. To do this:
* Create an object of type [[ref:libraries/base/reference/profiling_setting_chart|PROFILING_SETTING]] .
* Call [[ref:libraries/base/reference/profiling_setting_flatshort|start_profiling]] on this object to start the profiler.
* Call [[ref:libraries/base/reference/profiling_setting_flatshort|stop_profiling]] on this object to stop the profiler.
{{tip|To profile only part of a program, turn off the profiler at the very beginning of the program, turn it on just before the part of the code that should be profiled, and turn it back off after this section. Typically, it results in the following code: }}
In the root feature:
<code>
local
ps: PROFILING_SETTING
-- Other local variables if necessary.
do
create ps.make
ps.stop_profiling
-- Real program execution.
ps.start_profiling
end</code>
And in the feature(s) that needs to be profiled:
<code></code>
<code>
local
ps: PROFILING_SETTING
-- Other local variables if necessary.
do
create ps.make
ps.start_profiling
-- What needs to be profiled.
ps.stop_profiling
end</code>
{{note|Even if the profiler should only work in certain sections of code, the '''Profiling''' check box of the [[General Target Options|Projects Settings]] dialog must be checked or the '''profile''' option must be set on certain clusters. }}
Once the profiler has been enabled and the program has been recompiled, it is necessary to launch the program.
{{tip|It is possible to profile debuggable(frozen/melted) executables as well as finalized ones. It is more interesting to profile finalized executables, though, since the execution speed is more representative of what will be obtained by your end users. }}
When the program exits, a file named 'profinfo' should be generated next to it.
All that's left to do is launch the [[Profiler wizard]] and follow the instructions.
{{seealso|<br/>
[[Generating executables|Generating executables]] <br/>
[[Running an application|Running a program]] <br/>
[[Tuning a program|Tuning a program]] }}

View File

@@ -0,0 +1,28 @@
[[Property:title|Running an application]]
[[Property:weight|0]]
[[Property:uuid|61be4ec3-d50c-21b9-0649-fac9cd7796b9]]
There are several ways to launch an application. Not all are available depending on the way you compiled your system.
Melted and frozen executables can be debugged. Several methods can be used to launch such an executable:
* The default [[Run and stop at breakpoints]] . It launches the executable located in the EIFGENs/target_name/W_code directory under the project directory. The execution stops whenever a breakpoint is encountered.
* The [[Run without breakpoints]] . It has the same behavior except that the execution won't stop when a breakpoint is met.
* The step commands, which execute only a small part of the program at a time:
** The [[Step into a feature]] , which tries to enter the feature that is about to be called.
** The [[Execute one line at a time]] , which executes one execution line.
** The [[Step out of a feature]] , which launches the application and stops it as soon as the application exits the feature it is stopped in.
{{tip|All the above commands can be accessed either in the '''Project''' toolbar or in the '''Debug''' menu. <br/>
They can be used either to launch the program or to resume its execution after it has been paused. }}
* It is also possible to select '''Run to breakpoint''' in a [[Breakpoint editing|breakpoint context menu]] to have the application be launched and executed until it reaches the selected execution line.
Finalized executables can also be run, but they are not debuggable and cannot be interrupted. To run a finalized executable, use the [[Run a finalized executable]] , located in the '''Project''' menu and the '''Project''' toolbar.
{{seealso|<br/>
[[Generating executables|Compiling an executable]] <br/>
[[Using breakpoints|Using breakpoints]] <br/>
[[Interrupting an application|Interrupting an application]] }}

View File

@@ -0,0 +1,22 @@
[[Property:title|Setting the command line arguments]]
[[Property:weight|6]]
[[Property:uuid|4aed0363-4aa9-89ce-aaa7-6dce00410afb]]
To debug a program that uses command line parameters, it is possible to have the debugger call the generated program with certain command line arguments automatically.
To change the command line arguments used when debugging:
* Open the menu entry <code>Execution > Execution Parameters ..</code>
* In this dialog, you can change the current arguments, working directory, and add, change or remove environment variables.
** Use the <code>[Add]</code> button to add a new execution profile.
** Select the '''Arguments''' line, and press '''[Enter]''' to set the arguments value (or double click on the related grid cell).
** Same for Working directory
** To change the environment variable, follow the instructions, i.e double click or press enter to Add a variable, or right click to select from existing variable list. Once the variable line is added, by Right-clicking on the variable line, it is possible to:
*** fill with current variable value (if any),
*** unset it (this way, at execution time, the variable will not be set)
* Click '''[Run]''' to launch the execution in the EiffelStudio debugger.
* It is also possible to launch the execution outside EiffelStudio using the '''[Run Workbench]''' button.
{{tip|To get the command line arguments in a program, it is possible to either define the root feature as taking an array of [[ref:libraries/base/reference/string_8_chart|STRING_8]] objects, or to use the [[ref:libraries/base/reference/arguments_chart|ARGUMENTS]] class, which provides a lot of functionality linked with command line arguments. }}

View File

@@ -0,0 +1,220 @@
[[Property:title|Tracing]]
[[Property:weight|8]]
[[Property:uuid|ecb9dd1e-52a9-25c4-b27b-4b5ec806b115]]
=Introduction=
The '''tracing facility''' allows you to see a structured log of the flow of control through your system, feature by feature. By default, execution traces are written to standard output.
{{note|The tracing facility is not supported on the Microsoft .NET platform.}}
=The "Trace" project setting=
You can make tracing usable for a particular cluster by setting the '''Trace''' setting to '''True''' in your project settings for a particular cluster.
To do this:
* Open the [[Group Options|Project Settings]] dialog.
* Under '''Clusters''' select the cluster you want to see traced.
* Set the value of '''Trace''' to '''True'''.
* Click '''Apply''' or '''OK'''.
* You must [[Generating executables|recompile]] your project for the changes to take effect.
This will cause a trace entry to be written to the console for any feature execution on a class in the cluster(s) you selected for tracing. To get a feel for this, look at the following trace outputs, built on the default Eiffel application ("Hello Eiffel World!).
First, here's what the "Hello Eiffel World!" output looks like without using the tracing facility.
[[Image:Tracing 01 off]]
Next, here's the output when the '''Trace''' project setting is set to '''True''' on the root cluster.
[[Image:Tracing 01 on]]
Last, here's the output when '''Trace''' is '''True''' for both the root cluster and EiffelBase.
[[Image:Tracing 01 with EiffelBase]]
=Dynamic control=
It is also possible to enable and disable the trace dynamically. To do this:
* Create an object of type [[ref:libraries/base/reference/tracing_setting_chart|TRACING_SETTING]] .
* Call [[ref:libraries/base/reference/tracing_setting_flatshort|enable_tracing]] on this object to start the trace.
* Call [[ref:libraries/base/reference/tracing_setting_flatshort|disable_tracing]] on this object to stop the trace.
{{tip|To enable tracing on only part of a system, disable tracing at the very beginning of the program, enable it just before the part of the code that should be traced, and then disable it again after this section. The code below illustrates this tip. }}
In the root feature:
<code>
local
ts: TRACING_SETTING
-- Other local variables if necessary.
do
create ts.make
ts.disable_tracing
-- Program execution continues.
...
-- Restore tracing before exiting for proper cleanup.
ts.enable_tracing
end
</code>
Then, in a feature in which tracing is desired:
<code>
local
ts: TRACING_SETTING
-- Other local variables if necessary.
do
create ts.make
ts.enable_tracing -- Enable trace
-- Section needing trace.
...
ts.disable_tracing -- Disable trace
end
</code>
{{warning| Enabling/disabling tracing as shown above has to be done within the same routine otherwise the computed depth would be inaccurate and this would cause some unpredictable results.}}
=Using a trace handler=
You can do more complex tracing tasks by using a trace handler. The deferred class <code>TRACE_HANDLER</code> contains a deferred feature <code>trace</code> which you can effect in a descendant of <code>TRACE_HANDLER</code>. Your effective version of <code>trace</code> will be called whenever a trace event occurs. <code>{TRACE_HANDLER}.trace</code> looks like this:
<code>
trace (a_type_id: INTEGER; a_c_class_name, a_c_feature_name: POINTER; a_depth: INTEGER; a_is_entering: BOOLEAN)
-- Trigger a trace operation from a feature represented by `a_c_feature_name' defined in
-- class `a_c_class_name' and applied to an object of type `a_type_id' at a call depth `a_depth'.
-- If `a_is_entering' we are entering the routine, otherwise we are exiting it.
require
a_type_id_non_negative: a_type_id >= 0
a_depth_non_negative: a_depth >= 0
deferred
end
</code>
You may notice in the specification for <code>trace</code> above that the arguments representing the class and feature names are of type <code>POINTER</code> (versus some variant of <code>STRING</code>).
To make this facility more approachable for common tasks, EiffelBase also contains another class, a deferred descendant of <code>TRACING_HANDLER</code>, called <code>STRING_TRACING_HANDLER</code> in which the <code>trace</code> feature's arguments for class and feature names are strings, and the argument for type is an instance of <code>TYPE</code> rather than an integer type id as in <code>TRACING_HANDLER</code>. <code>{STRING_TRACING_HANDLER}.trace</code> looks like this:
<code>
trace (a_type: TYPE [detachable ANY]; a_class_name, a_feature_name: detachable STRING; a_depth: INTEGER; a_is_entering: BOOLEAN)
-- Trigger a trace operation from a feature represented by `a_feature_name' defined in
-- class `a_class_name' and applied to an object of type `a_type' at a call depth `a_depth'.
-- If `a_is_entering' we are entering the routine, otherwise we are exiting it.
require
a_depth_non_negative: a_depth >= 0
deferred
end
</code>
Suppose we wanted to write trace long entries in a private log file for the entry and exit of a number of routines during the run of a simple application. We could create a descendant of <code>STRING_TRACING_HANDLER</code> that looks like this:
<code>
class
EXAMPLE_HANDLER
inherit
STRING_TRACING_HANDLER
feature
trace (a_type: TYPE [ANY]; a_class_name, a_feature_name: STRING_8; a_depth: INTEGER_32; a_is_entering: BOOLEAN)
-- <Precursor>
do
trace_log_file.put_string (create {STRING}.make_filled ('>', a_depth))
if a_is_entering then
trace_log_file.put_string (" Is entering " + "{" + a_class_name + "}." + a_feature_name + "%N")
else
trace_log_file.put_string (" Is leaving " + "{" + a_class_name + "}." + a_feature_name + "%N")
end
end
trace_log_file: PLAIN_TEXT_FILE
-- Log file
once
create Result.make_open_write ("my_log_file.txt")
end
close_log_file
-- Close log file
do
trace_log_file.close
end
end
</code>
In <code>EXAMPLE_HANDLER</code> the procedure <code>trace</code> is effected to write the desired information to the <code>log_file</code>.
Then we could use <code>EXAMPLE_HANDLER</code> in a class that might look like this:
<code>
class
APPLICATION
create
make
feature
make
-- Run application.
local
tracing_setting: TRACING_SETTING
tracing_handler: EXAMPLE_HANDLER
do
create tracing_setting
tracing_setting.enable_tracing
create tracing_handler
tracing_handler.activate
call_depth_one
tracing_handler.deactivate
tracing_handler.close_log_file
tracing_setting.disable_tracing
end
call_depth_one
-- Call depth one routine
do
call_depth_two
end
call_depth_two
-- Call depth two routine
do
call_depth_three
end
call_depth_three
-- Call depth three routine
do
end
end
</code>
In <code>{APPLICATION}.make</code>, the instances of <code>TRACING_SETTING</code> and <code>EXAMPLE_HANDLER</code> are created. Tracing is enabled and the handler is activated. After the section of interest, the handler is deactivated, the log file closed, and tracing disabled.
Now consider a system in which <code>{APPLICATION}.make</code> is the root, <code>APPLICATION</code> is the only class in the root cluster, and that the project setting '''Trace''' is true for the root cluster only. After running the system, the content of <code>my_log_file.txt</code> would be:
<code lang="text">
> Is entering {APPLICATION}.call_depth_one
>> Is entering {APPLICATION}.call_depth_two
>>> Is entering {APPLICATION}.call_depth_three
>>> Is leaving {APPLICATION}.call_depth_three
>> Is leaving {APPLICATION}.call_depth_two
> Is leaving {APPLICATION}.call_depth_one
</code>

View File

@@ -0,0 +1,15 @@
[[Property:title|Using breakpoints]]
[[Property:weight|3]]
[[Property:uuid|f25c8058-8278-7ee3-79cb-ff97e224e74a]]
To change the status of one breakpoint, it is possible to use the [[Breakpoint editing|breakpoints menu]] , which changes the state of a single breakpoint at a time.
To change the status of several breakpoints at the same time, the easiest way is to use the [[Breakpoint commands|breakpoints-related commands]] , which have actions at feature-scope, class-scope and system-scope.
{{seealso|<br/>
[[Running an application|Running an application]] <br/>
[[Interrupting an application|Interrupting an application]] <br/>
[[Breakpoints|Breakpoints reference]] }}

View File

@@ -0,0 +1,29 @@
[[Property:title|Using debug clauses]]
[[Property:weight|5]]
[[Property:uuid|78e0273d-525e-a338-dfe4-d5fc27cd06d3]]
Eiffel provides ways to add debug code to features to help during their debugging. You may think of it as the well-known C construct: <code></code>
<code lang=c>#ifdef MY_DEBUG_FLAG/* Debug code is here */ #endif</code>
The corresponding construct in Eiffel is provided by the debug keyword. It is possible to wrap code inside a debug clause like this:
<code></code>
<code>
debug("MY_DEBUG_FLAG")
-- Debug code is here.
end</code>
It is then possible to enable or disable debug clauses globally.
To modify the debug clauses status:
* Open the [[Debug Options|Project Settings]] dialog.
* In the '''Debug''' section, you can enable/disable the debug clauses.
* Click '''OK'''.
* You must [[Generating executables|recompile]] your project for the changes to take effect.
{{tip|Debug clauses make it easy to remove all debug messages when finalizing a system. }}