![]() |
|
This chapter describes how to use the Wing IDE debugger.
![]() |
The Wing debugger consists of two parts: (1) the debug client, represented by
the debugger window in Wing IDE, and (2) the debug server, which resides within
another process space, possibly on another machine, and communicates with the client
via TCP/IP.
The debugger supports launching your application not just from Wing itself but also externally, as with CGI scripts or code running in an embedded scripting facility within a larger application. When externally launched, your code can attach to the Wing IDE debugger at any point in its execution, and may turn on and off debugging using a simple API. Because the debugger core is written in optimized C, debug overhead is relatively low; however, you should expect your programs to run about 50% slower within the debugger. |
Normally, Wing will start debugging in whatever file you have as your front- most window. Depending on the nature of your project, you may wish to specify a file as the default debug entry point.
To do this, right-click on one of your Python files in the Project Manager window and choose the Set As Main Debug File option from the popup menu. This file is subsequently executed whenever you start the debugger, except if you use the Debug Selection in the Project Manager's popup menu.
Note that the project manager will highlight the main entry point in red. You may clear the default main debug file subsequently by using the Clear Main Debug File item in the Project Manager window's popup menu.
Regardless of whether a main debug file is defined, you can also start debugging any open file with Debug Current File in the Debug menu, or by right-clicking on an entry in the project manager and choosing the Debug Selection popup menu item.
The main entry point defined for a project is also used by the source code analysis engine to determine the python interpreter version and python path to use for analysis. Thus, changing this value will cause all source files in your project to be reanalysed from scratch. See section 5.6 for details.
In some cases, you will also need to set up some properties to use when debugging. These are set either on a project-wide basis or may be specified on a per-file basis using the main entry point file for the debug session. Project-wide debug properties apply in all cases where a per-file value was not given; otherwise the per-file value overrides the project-wide values.
Only per-file debug properties set on the initially invoked file are used in the debug session. Even if other files with set properties are used in the debug session, any values set for them will be ignored.
Debug properties may be set project-wide from the Properties item in the Project menu. Per-file debug properties may be set from the Current File Debug Properties item in the Run menu, or from the Set Debug Properties item in the right-click popup menu on the project manager.
The project-wide properties dialog contains the following fields:
python
on the command line. If this fails, Wing will search for Python in
/usr/local
and /usr
(on Linux) or in the registry (on Windows).
PYTHONPATH
is used by Python to locate
modules that are imported at runtime with the import
statement. When
the Use environment checkbox in this area is checked, the
inherited PYTHONPATH
environment variable is used for debug sessions.
Otherwise, is Custom setting is selected, the specified PYTHONPATH
is
used.
Makefile
, before execution is started.
var=value
form
and must be specified one per line in the provided entry area. An entry in
the form var=
(without a value) will cause the given variable to
be undefined. Note that you are operating on the environment inherited
from the IDE and not defining a blank new environment space. When the
Use env radio button is checked, any entered values are ignored and the
inherited environment is used without changes.
All of these values are stored in the project file on a per-platform basis. This means that when a project is used both on Linux and on Windows (via file sharing or source code control), you must set values seperately for each platform. Wing shows and edits only the values for the platform you are currently running on.
If you are sharing a project file with other developers through a revision control system, it is important to know that any full or partial relative file and directory paths specified within the above values will be stored as a full path in the shared branch of the project file. This means that other developers must work in an environment that supports those paths.
The per-file debug properties dialog contains all the same fields as are available in the project-wide properties described above, with the following additions:
Values entered here will override any project-wide values.
The per-file and project-wide debug properties are also used by the source
code analysis engine in order to determine the Python interpreter version and
PYTHONPATH
to use in analysis. For this reason, changing either Python
Executable or Python Path in the debug properties dialogs will cause Wing to
reanalyse your entire source base from scratch. See section
5.6 for details.
A number of different styles of breakpoints are available for use with the Wing IDE debugger. These can be set on source code by opening the source file, placing the cursor on the line where a breakpoint is desired, and then either using items in the Breakpoints menu or pushing the breakpoints tool buttons (the rightmost group in the toolbar).
![]() |
You can also set, clear, and edit breakpoints by clicking on the margin to the left of the source editor, where breakpoints are indicated. Plain clicks will toggle to insert a regular breakpoint or remove an existing breakpoint. You can also shift-click to insert a temporary (one-time) breakpoint, control-click to insert a breakpoint and set an ignore count for it, or shift-control-click to insert a conditional breakpoint. When a breakpoint is already found on the line, shift-click will disable or enable it, control-click will set its ignore count, and shift-control-click will set or edit the breakpoint conditional. |
The following types of breakpoints are available:
true
(any non-zero, non-empty,
non-None
value, as defined by Python). You may edit the conditional of
any existing breakpoint with the Edit Breakpoint Condition item in
the Breakpoints menu.Once breakpoints have been defined, you can operate on them in a number of ways to alter their behavior. These operations are available as menu items in the Breakpoints menu, and toolbar icons:
There are several ways in which to start a debug session from within Wing:
Note that additional options exist for initiating a debug session from outside of Wing and for attaching to an already-running process. These are described in sections 6.13 and 6.12 below.
![]() |
If you are attempting to run your debug process against a non-standard version
of Python, for example one that has been compiled with altered values for
Py_TRACE_REFS or WITH_CYCLE_GC , or that has been altered in other ways, you
may need to recompile the debugger core module. Please refer to section
6.17 for more information.
|
Once the debugger is running, the following commands are available for controlling further execution of the debug program from Wing. These are accessible from the middle panel of the tool bar or from the Run menu:
When stopped on a given line of code, execution can be stepped line-by-line by using the Step Over, Step Into, and Step Out menu item or tool bar icons:
Whenever the debug program is paused at a breakpoint or during manual stepping, the current stack is displayed as a list in the top panel of the debugger window. This list shows all stack frames encountered between invocation of the program and the current run position. Outermost stack frames are higher up on the list.
Note that the stack displayed is a concatenation of all Python stack frames seen, and may include discontinuities if your code calls C/C++ or other non-Python code, which in turn makes calls back into Python. In this case, the C/C++ stack frames will be missing but the overall order and flow of invocation should be apparent from those stack frames that are visible.
When the debugger steps or stops at a breakpoint or exception, it selects the innermost stack frame by default.
In order to visit other stack frames further up or down the stack, use the Up Stack and Down Stack items in the Run menu or the up/down tool bar icons. You can also click directly on the surface of the stack in the top panel of the debugger window.
When you change stack frames, the variables views will be changed accordingly, and the current line of code at that stack frame is presented in an editor window.
The Wing IDE debugger provides two ways in which to look at variables: (1) in a hierarchical tree view that can be expanded and collapsed, and (2) in a textual view that can be set to show a desired number of hierarchical levels. These two views are in the second and third debugger window panels, respectively. Note that the relative sizes of these panels can be adjusted by dragging the resize indicators on the dividers between them.
![]() |
The variables data displayed by Wing is fetched from the debug server on the fly as you navigate. Because of this, you may experience a brief delay when a change in an expansion or stack frame results in a large data transfer. |
The tree view contains two top-level entries: (1) locals, which contains all the locals and parameters defined in the currently selected stack frame, and (2) globals, which are scoped to be accessible from all stack frames. Note that in the top-level scope, these two name spaces will be the same and will show the same data.
Simple values, such as strings and numbers, will be displayed
in the value column of the tree view area. Strings are always
contained in ""
(double quotes). Any value outside of quotes is
a number or internally defined constant such as None
or
Ellipsis
.
Complex values, such as instances, lists, and dictionaries, will be presented
with an angle-bracketed type and memory address (for example, <dict 0x80ce388>
)
and can be expanded by clicking on the expansion indicator in the Variable column.
The memory address uniquely identifies the construct. Thus, if you see the same
address in two places, you are looking at two object references to the same
instance.
Upon expansion of complex views, the position or name of each sub-entry will be displayed in the Variable column, and the value of each entry (possibly also complex values) will be displayed in the Value column. Nested complex values can be expanded indefinitely, even if this results in the traversal of cycles of object references.
Once you expand an entry, the debugger will continue to present that entry expanded, even after you step further or restart the debug session. Expansion state is saved for the duration of your Wing IDE session.
![]() |
Values that have not yet been defined in the flow of control are shown with
value <undefined> .
Some data types, such as those defined only within C/C++ code,
or those containing certain Python language internals, cannot be transferred
over the network. These are denoted with Value entries in the form
Values Class-scoped values seen within an instance are shown in italics.
When the debugger encounters a very long string, this is indicated in the
Value column by prepending
Other indicators such as |
By right-clicking on the surface of the tree view of variables, it is possible to obtain a popup menu that contains several commands useful in navigating data structures. Most of the items in this popup menu act upon the specific data value that was right-clicked upon:
The variable value zooming and tracking features are described in more detail in section 6.7.3 below.
The textual view is more useful in some cases than the tree view because (1) it can better display long strings, (2) whole structures are easily accessed without as much visual clutter, and (3) arbitrary sections of the view can be copied and pasted.
The layout textual view is very similar to the tree view, except that per-value expansion and collapse is not available. Instead, a hierarchy of values is displayed up to some selected depth of expansion for the entire set of values.
The Show More and Show Less buttons act like the Expand More and Expand Less popup menu items on the tree view surface, and are enabled and disabled in the same circumstances.
![]() |
Using Expand More on the textual variable view, like use of Expand More on the tree view, may result in significant delays on the user interface if expanding large structures to a depth of more than 3 or 4 levels. Caution is advisable in cases where endless traversal of bushy structures is possible. |
![]() |
It is possible to zoom variable values out to seperate windows by right-clicking on tree style variable views, either in the main debugger window or in any other zoomed-out tree style view. The resulting window presents the value using a tree, textual, or combination display, according to the configured defaults. The value is tracked during execution and will change on the display according to either its symbolic path, a direct object reference to the value (only for mutable values), or according to a combination of object reference to the parent value and symbolic name for the parent slot. |
The display style is controlled with the debug.default-var-view-style
preference and can be overridden from the Default Zoom Style item in the popup
menu. The selected display styles are the same as those described above: tree,
textual, or a combination view containing both types of views, as is found in
the main debugger window.
Before using this feature, it's a good idea to understand the subtleties of tracking values during execution. You will likely want to change how this is done during different debug tasks. The supported methods are:
locals
or globals
to the selected data value and tries to
reevaluate that path whenever the value may have changed. For example, if you
define a dictionary variable called testdict
in a function and set a
value testdict[1] = 'test'
, the zoomed out view for testdict[1]
would show any value for that slot of testdict
, even if you delete
testdict and recreate it. In other words, value tracking is independent of the
life of any object instances in the data path.
testdict
as
a whole, it would track the contents of that dictionary as long as it exists.
If you were to reassign the variable testdict
to another value, your
zoomed out display would still show the contents of the original dictionary
instance, rather than the new value of the variable testdict
. In other
words, the symbolic path to the value is completely disregarded and only
instance identity is used to track the value. Because it's meaningless to
track immutable types this way, this option is disabled or enabled according
to the values you select to zoom out into a seperate window.
locals
or
globals
, this is the same as tracking the value by symbolic path, because
the parent reference is to the locals
or globals
dictionary itself.
For any of these, if the value cannot be evaluated because it does not exist
at any given point in time, the debugger displays <undefined>
. This happens
when the last object reference to a reference-tracked value is discarded, or if
a selected symbolic path is undefined or unevaluable.
The type of tracking that is used is controlled by the
debug.default-var-track-style
preference and can be overridden from the
Default Zoom Tracking item in the popup menu, or by selecting one of the
specific Zoom and Track popup menu items (Zoom to Window simply uses the
configured default).
There are a number of ways in which variable display can be configured:
Currently, this can be done only by setting the two preferences,
debug.omit-types
and debug.omit-names
. These are
described in section 6.21.
huge
in the
variable display area and cannot be expanded further. The data size thresholds
are controlled with preferences debug.huge-list-threshold
and
debug.huge-string-threshold
, described in section 6.21
and in section 6.7.5.
debug.line-threshold
. If you want all values to be shown
uniformly, this preference should be set to 0
.
The Wing debugger tries to handle debug data as gently as possible to avoid entering into lengthy computations or triggering errors in the debug process while it is packaging debug data for transfer. Even so, not all debug data can be shown on the display. This section describes each of the reasons why this may happen:
debug.network-timeout
preference and then will display the variable
value as <network timeout during evaluate>
.
debug.huge-list-threshold
and
debug.huge-string-threshold
(described in section 6.21). On
the debugger display, oversized sequences and arrays are annotated as
huge
and <truncated>
is prepended to large truncated strings.
To avoid this, increase the value of the threshold preferences, but be
prepared for longer data transfer times. Note that setting these values too
high will cause the debugger to time out if the debug.network-timeout
value isn't also increased.
An alternative for viewing large data values is to use the Expression Evaluator (described in section 6.8) or Interactive Debug Probe (described in section 6.9) to view sub-parts of the data rather than tranferring the whole top-level portion of the value.
__cmp__
and __str__
in your code. If this code has bugs in it,
the debugger may reveal those bugs at times when you would otherwise not see
them.
The rare worst case scenario is crashing of the debug process if flawed C or C++ extension module code is invoked. In this case, the debug session is ended.
Much more usual, but still rare, are cases where Wing encounters an unexpected
Python exception while handling a debug data value. When this happens, Wing
displays the value as <error handling value>
. These errors are not
reported as normal program errors in the Error List dialog. However, setting
the preferences main.print-wing-debug-output
and
debug.-verbose-debugging
to true
will cause the exception that
is being raised to appear in the window from which Wing was launched from the
command line.
Wing remembers errors it encounters on debug values and stores these in the project file. These values will not be refetched during subsequent debugging, even if Wing is quit and restarted.
To override this behavior for an individual value, use the Force Reload
item in the right-click popup menu of a tree view variable area.
To clear the list of all errors previously encountered so that all values are
reloaded after subsequent stepping or restart of the debug session, use the
Clear Stored Value Errors
item in the Run
menu or tree display
right-click popup menu. This operates only on the list of errors known for
the current debug file, if a debug session is active, or for the main debug
file, if any, when no debug process is running.
Wing includes an interface for evaluating keyboard-entered expressions and viewing the result of the evaluation within a data display tree. Expressions are evaluated in the context of the current debug stack frame, so this feature is available only when a debug session is active and the debug program has been paused or has stopped at a breakpoint or exception. This also means that the value of the same typed expression may change as you move up and down the call stack in the main debugger window.
The Expression Evaluator item in the Windows menu will display the expression evaluator window. Expressions are typed into the panel at the top of the window and the Evaluate button is used to display the result of the evaluation below. Only expressions that evaluate to a value may be entered. Other statements, like variable assignments, import statements, and language constructs are rejected with an error. These may only be executed using the Interactive Debug Probe described in the next section.
A history list of expressions previously evaluated is also available via popup menu. Expressions selected from this menu are copied into the entry area and optionally evaluated immediately upon selection from the menu (only when the Evaluate Immediately checkbox is checked).
If an exception occurs during expression evaluation, this is reported with the Error List dialog and, if possible, the source location of the error is shown.
You may select from one of three display options when evaluating expressions: A single tree view, a textual view, or a tree/text combo view. These act exactly the same as those accessed from the main debugger window, as described in section 6.7. Once you have changed view modes, you must push the Evaluate button again before the view is filled with data.
In the rare cases where evaluating an expression results in changing the value of local or global variables, your debug program will continue in that changed context. Whenever a value is changed as a result of expression evaluation, the updated value will be propagated into any visible debugger variable display areas because Wing IDE refetches all displayed data values after the evaluation of each expression. However, since you may not notice these changes, caution is then required to avoid creating undesired side-effects in the running debug program. Otherwise, your program may not act as it would have during normal, uninterrupted execution.
Note that in this version of Wing, breakpoints are never reached as a result of expression evaluation, and any exceptions are reported only after the fact. This means that activity in the expression evaluation window has no effect on the debug run position or stack, even though an exception location in source code may in some cases by displayed.
An interactive probe that acts like the Python shell is available for evaluating and executing arbitrary Python code in the context of a debug program. Like the expression evaluator, this acts on the current debug stack frame, and thus is available only when there is an active debug session and the debug program is paused.
This tool is displayed by selecting the Interactive Debug Probe menu item in the Windows menu. It acts much like the Python interpreter when it is invoked from the command line. You may use most of Wing's source editor commands and key bindings within the interactive debug probe window, and can use the up/down arrow keys to traverse a history of recently typed commands.
If commands you type change any local, instance, or global data values, cause modules to be loaded or unloaded, set environment variables, or otherwise alter the run environment, your debug program will continue within that altered state. All visible variable display views are also updated after each line entered in the interactive shell in order to reflect any changes caused by your commands. But since you may not notice these changes, caution is required to avoid creating undesired side-effects in the running debug program. Otherwise, your program may not act as it would have during normal, uninterrupted execution.
One limitation is that private instance variables prefixed by double
underscore (such as self.__my_var
) cannot be directly inspected or
altered within the interactive shell. Python will report that the attribute is
not defined because it internally prefixes the class name where the private
variable is found. These can easily be viewed using the main debugger window
or expression evaluator, or you can look at self.__dict__
as a whole
and then use the fully qualified self._classname__my_var
to access or
alter the value.
Note that in this version of Wing, breakpoints are never reached as a result of entries typed into the interactive shell, and any exceptions are reported only after the fact with a textual traceback. This means that activity in the interactive shell window has no effect on the debug run position or stack, even though an exception location in source code may in some cases be displayed.
Preference debug.raise-from-interactive
can be used to determine
whether source code windows will be raised when exceptions occur here. See
section 6.21 for details.
Another shell tool is provided for execution of commands and evaluation of expressions outside of your debug program. This is the Interactive Python Shell, which may be accessed from the Windows menu.
Since this shell runs a seperate Python process that is independent of your debug process, it is always enabled and functions without regard to the state of any running debug process. As such, it acts very similarly to a regular command line Python shell.
The Interactive Python Shell always runs the same version of Python as is used for your debug process. This is described in more detail in section 6.2
To clear the state of the Python shell, press the New Session button. This will kill the external python process and restart it, thus clearing and resetting the state of the shell.
Note that in this version of Wing, breakpoints are never reached as a result
of entries typed into the interactive shell, and any exceptions are reported
only after the fact with a textual trace back. Preference
debug.raise-from-interactive
can be used to determine whether source
code windows will be raised when exceptions occur here. See section
6.21 for details.
During debug program execution, the debugger can be asked to stop on exceptions in the same way it would stop at breakpoints or in response to a Pause command.
A number of options for controlling when the debugger will stop on an exception are available from the Run menu's Exception Mode item:
stderr
and the program continues to execute, or exits, according to action
taken by the Python interpreter. This behavior is the same as if the
program were running outside of the debugger. You will, however, be
given a post-mortem error and traceback by Wing to distinguish clearly
from cases where a program has exited normally.Whenever stopping on an exception, Wing presents an Error List window containing the exception information and backtrace, and stops the program at the point of exception (so that the stack frame and variables for that point are displayed in the debugger window).
Once stopped at an exception, execution can be continued in the same way as at any other time, using the run menu or tool bar, or by selecting Close & Continue in the Error List window.
The Error List window can be used to indicate to the debugger that the current exception should be omitted from those at which the debugger will stop in the future. To do this, check the checkbox labeled "Don't show me this exception location again" and push the "Close" or "Close & Continue" button.
This causes the debugger to ignore all exceptions on that line, regardless of type.
The list of ignored exceptions may be cleared to blank subsequently with the Clear Ignored Exceptions item in the Run menu.
Debug processes normally contact Wing IDE automatically during startup. However, Wing IDE can also attach to debug processes that are already running but not yet in contact with the IDE. There are two cases where this is useful:
wingdbstub.py
, as described in section 6.13) cannot
reach the IDE at the configured host and port during initial startup, for
example because the IDE is not yet running or was not configured to accept
debug connections.In either case, the IDE can manage any number of detached processes, allowing you to attach to any one process at a time.
Wing will not allow attach/detach functionality unless it has available to it a password that can be used to control access. This is very important because an unsecured debug server provides the client (Wing IDE) full control of the host machine via the Interactive Debug Probe tool. Any Python command can be executed in this way, including programs that compromise the security of your machine and network.
Because Wing sets up an access control password during installation, attach
and detach will work out of the box as long as your debug processes are
launched from Wing IDE, by you from the command line, or in the context of
some service or program that is running under your user name on a machine that
has access to your ~/.wingide
directory (on Linux) or
WINGHOME\profiles\[username]
(on Windows).
If you plan to debug remotely, please refer to the instructions in section
6.13.3 and 6.13.5. Setting up your remote debugging
to work properly with encryption will also fullfill the requirements of the
attach/detach facility. Note, however, that you can use encryption type
none
to enable attach/detach but disable channel encryption.
The most common way of generating a process to which to attach is to first detach from a debug process. This is done by selecting the Detach from Process item in the Run menu or the detach icon in the toolbar.
Whenever a process is detached, it continues running as if outside of the debugger, without stopping at any breakpoints or exceptions. Even if a process is paused within the debugger at time of detaching from the IDE, the process will start running actively immediately after the IDE disconnects.
The Attach to Process or attach toolbar icon are available whenever no other
debug process is attached to the IDE. This brings up a dialog box that
includes a list of available processes to attach to. The list is built from
hard-wired host/port pairs given with the debug.attach-defaults
preference (('127.0.0.1', 50015)
by default), combined with known
processes that were previously attached to Wing IDE.
Wing updates the list of available processes as debug sessions are killed from the IDE, as they are seen to exit from the outside while attached to Wing, or when the process cannot be contacted by Wing.
To attach to a process, select it from the list and push the Attach button. You may also type in a host/port value manually if your choice is not on the list (see the next subsection below).
Once you are attached to a process, it continues running until it reaches a breakpoint, unhandled exception, or you push the Pause button or use the Pause item in the Run menu.
If Wing is not running or not listening for connections because Passive Listen has been disabled, then additional processes may be available that are not listed in the Attach dialog.
This is usually the case when debugging externally launched code (that uses
wingdbstub.py
as described in section 6.13). You may use
the kAttachPort
constant in wingdbstub.py
to set the port on
which such processes will listen for attach requests. It is important to set
unique values for this port for each concurrent, externally-launched process.
If the set port is in use, a random port number will be used instead and it
may be difficult to determine this number if the process cannot initially
contact Wing IDE to register.
In any case, any unregistered debug process can be reached from Wing IDE by
typing the host/port into the Attach dialog text areas. If you find yourself
typing a host/port value often, it is best to add that value to the
debug.attach-defaults
preference.
Note that improperly configuring wingdbstub.py
can also result in
failure to reach the IDE during startup, since the configured
kWingHostPort
must match your Wing IDE preferences. See section
6.13 to work through your configuration before resigning to
attaching manually.
Currently, Wing supports attaching only to a single debug process at a time. Whenever you detach from a process, it begins free-running and will not stop at any breakpoints or non-fatal exceptions. This limits what can be done with detach/attach from a single copy of Wing. If you wish to actively debug two processes at once, simultaneously controlling stepping, breakpoint activation, and execution (as in a client/server network program), it is best to run two copies of Wing at once.
This section describes how to start debugging from a process that is not launched by Wing. Examples of debug code that is launched externally include CGI scripts running under a web server, or embedded Python scripts running inside a larger application.
The following step-by-step instructions can be used to start debugging in externally launched code that is running on the same machine as Wing IDE:
wingdbstub.py
from the Wing IDE installation directory into
the same directory as your debug program.
import wingdbstub
debug.passive-listen
is set
to true
and (re)launch the IDE, or use the Network Mode section of
the Run menu to turn on passive listen.
C:\Program Files\Wing IDE\
). You can also edit these values in
wingdbstub.py if setting an env is inconvenient.
-O
option.
The debugger cannot determine line numbers and thus cannot do anything
meaningful when optimization is turned on.
![]() |
When an external process attaches to Wing IDE, the Kill item in the Run menu
and toolbar icon are disabled, because Wing recognizes that it has not itself
launched the debug process. To enable Kill in these cases also, set the
debug.enable-kill-external preference to true .
|
If you have problems making this work, try setting kSilent=0
variable
in wingdbstub.py
and launch the Python code from the command line where
you can see its error output. Even though CGIs and similar code may not work
properly this way, doing so can help to shed light on why a debug connection
is not being initiated properly.
In some cases you may also need to alter other preset configuration values at
the start of wingdbstub.py
. These values completely replace any values
set in Wing's project-wide or per-file debug properties, which are relevant
only when the debug program is launched from within Wing. The following
options are available:
kWingDebugDisabled=1
This is equivalent to setting the WINGDB_DISABLED
environment variable
before launching the debug program.
kWingHostPort
to specify the network location of Wing IDE,
so the debugger can connect to it when it starts. This is equivalent to
setting the WINGDB_HOSTPORT
environment variable before launching
the debug program. The default value is localhost:50005
. See section
6.13.3 below for details if you need to change this value.
kSilent
. This is equivalent to setting the
WINGDB_SILENT
environment variable before launching the debug program.
When set to 1
, debugger internal messages are not printed to
stderr
, so they will not appear (for example, in the web server log
file when running CGI scripts). However, to track down problems in launching
the debugger in the first place, you may need to temporarily set this value to
0
to see the debugger's internal error messages (which can be quite
verbose).
kEmbedded
to 1
when debugging embedded scripts. In
this case, the debug connection will be maintained across script invocations
instead of closing the debug connection when the script finishes. When this
is set to 1
, you must call wingdbstub.debugger.ProgramQuit()
before your program exits in order to cleanly close the debug connection
to the IDE. This is equivalent to setting the environment variable
WINGDB_EMBEDDED
.
kAttachPort
to define the default port at which the debug
process will listen for requests to attach. This is equivalent to setting the
WINGDB_ATTACHPORT
environment variable before launching the debug
program. This value is used when the debug process is running without being in
contact with Wing IDE, as might happen if it initially fails to connect to the
above-defined host and port, or if the IDE detaches from the process for a
period of time. This is described in more detail in section 6.12
below.
Setting any of the above-described environment variable equivalents will
override the value given in the wingdbstub.py
file.
![]() |
Whenever the debugger cannot contact Wing IDE (for example, if the IDE is not running or is listening on a different port), the debug program will be run without any debugger. This is useful since debug-enabled CGIs and other programs should work normally when Wing is not present. In this case, you can attach to the process using Attach to Process from the Run menu, as described in section 6.12. |
The description above covers only the case where you are running Wing and the debug code on the same machine. You can also ask the debugger to connect remotely over the network. This section describes how this is done with two machines of the same type. More information on working with machines of different type (e.g. Linux and Windows) can be found in section 6.17.
In order to do this, you need to check the following settings:
debug.network-server
preference to the name or IP address
of the network interface on which the debugger listens for connections.
This may be None
or ""
to indicate that the debugger should
listen on all the valid network interfaces on the host.
passive-hosts
preference list to include the host on
which the debug process will be run.
debug.network-server
and debug.network-port
.
bin/#.#.#/src/debug/server
and
bin/#.#.#/opensource/schannel
where #.#.#
is your Python
interpreter's version (for example 1.5.2
). If you're using a
version of Python not found in the primary Wing installation, you can
use the nearest lower release as long as the major.minor
versions match.
For example, the 2.1.0
binaries will work with 2.1.1
.
Unless you are low on disk space, the easiest way to do this is to transfer
the entire Wing IDE binary installation by copying over the contents of the
bin
directory inside your Wing installation.
On Linux you might use this command to pack up the necessary files:
cd WINGHOME tar cf dbgsvr.tar bin
Move those files to the machine you want to debug on and unpack them into a
directory to which your debug process will have access. This directory acts as
WINGHOME
on the debug server.
Once done, you should have at least the following directories under WINGHOME
on the machine where you wish to run your debug process, each filled with the
*.pyc
and *.pyd
(Windows) or *.so
(Linux) files that are in
your primary Wing installation:
bin/1.5.2/src/debug/server bin/1.5.2/opensource/schannel bin/2.0.0/src/debug/server bin/2.0.0/opensource/schannel bin/2.1.0/src/debug/server bin/2.1.0/opensource/schannel
If you're only using one version of Python, you can omit the directories for
the other versions that you are not using. If you're using a newer release of
the same major.minor
release of Python, for example 2.1.1
, you
should copy out the newest available version in that major.minor
series, for example 2.1.0
. Nothing outside of the the above directories
is used, so may also be removed or omitted from your original copy.
*.pyc
files are available on the debug server. You must also place a
copy of wingdbstub.py
with these files and import it as described in
section 6.13. You will need to set at least the value of
kWingHostPort
and kWingHome
inside of wingdbstub.py
in
order to tell the debugger where it should connect once your debug program has
been started and where it can find the debug server code that you've
transferred over from your primary Wing installation.
Note that during debugging, the client and server copies of the files must match or the debugger will either fail to stop at breakpoints or stop at the wrong place, and stepping through code may not work properly. Since there is no mechanism in this version of Wing for transferring code, you need to use NFS, Samba, FTP or some other file transfer mechanism to keep the remote files up to date as you edit them in Wing.
debug.location-map
preference to define one
or more mappings from remote file location to local file location. This
is described in more detail in the next section.
Then restart Wing, set a test breakpoint in the debug file, and try running
the debug process. If you have problems, set kSilent=0
in wingdbstub.py
and check whether the debug stub reports that it could not connect to Wing
IDE.
Wing currently requires access to debug files on disk both on the host where Wing IDE is running and where the debug process is running. Usually, this is facilitated by setting up file sharing between the two machines, using NFS, Samba, or other file sharing mechanism. Manual or semi-automatic FTP transfers will also work.
In cases where the full path to your source is not the same on both machines, you need to set up a mapping that tells Wing where it can find debug files. Note that making symbolic links to 'fake' file locations on the client or server does not work because file locations are resolved to actual full path location by the debug server.
The debug file mapping is defined with the debug.location-map
preference, which is a dictionary of remote host ip address (the host where
the debug process is running) and a list of mapping entries.
In addition to standard dotted-quad IP addresses, you may specify a special ip
address entry of "*"
to define a default mapping for all hosts that are
not otherwise specified in the location map.
The mapping entries themselves are arrays of tuples where each tuple is a
(remote_prefix,
local_prefix)
pair. The remote file name will be
a full path on the debug server's file system. The local file name will be
a URL, currently always starting with file:
. Note that the local file
URL should not contain backslashes (\
) even if the local host is
a Windows machine.
The default value for debug.location-map
is {'127.0.0.1':None}
which indicates that all files at top level on the local host should be
referred to with file:
URLs. This is equivalent to the more verbose
{'127.0.0.1':[('/','file:')]}
. It converts full paths on the debug
server to the client-side URLs without altering any part of the full path.
Here is an example setting for debug.location-map
that would be used if
running Wing on desktop1
and debugging some code on server1
with
IP address 192.168.1.1:
debug.location-map={ \ '127.0.0.1':None, \ '192.168.1.1':[('/home/apache/cgi', 'file:/svr1/home/apache/cgi')] \ }
In this example, the same files are located in /home/apache/cgi
on
server1
and in /server1/home/apache/cgi
on desktop1
,
because the entire file system on server1
is being NFS mounted on
desktop1
under /svr1
.
Note that the trailing \
is required for line continuation by the
preferences file format.
If you are debugging between Windows and Linux, some care is needed in specifying the conversion paths because of the different path name conventions on each platform. This entry would be used when running Wing IDE on a Linux host and the debug process on a Windows host with ip address 192.168.1.1:
debug.location-map={ \ '127.0.0.1':None, \ '192.168.1.1':[('c:\\src\\ide', 'file:/home/myuser/src/ide')], \ }
Note the double backslashes in the remote path and the use of forward slashes in the local URL specifier.
If running Wing IDE on a Windows host and the debug process on a Linux host with IP address 192.168.10, the following might be used instead for the same file locations:
debug.location-map={ '127.0.0.1':None, '192.168.1.1':[('/home/myuser/src/ide', 'file:c:/src/ide')], }
In the case where the Linux user myuser
home directory is mounted via
Samba to a Windows machine as the e:
drive, the following similar
configuration would be used (only the drive letter differs from the above):
debug.location-map={ '127.0.0.1':None, '192.168.1.1':[('/home/myuser/src/ide', 'file:e:/src/ide')], }
If you do not have NFS, Samba, or other file sharing, FTP or an FTP mirroring tool can be used to manually transfer files. Many FTP clients for Windows provide a mirroring capability.
If you plan to debug over an unsecured network, you may wish to enable Wing's channel encrypter. Currently, the type of encryption used for this is weak, but it is enough to defeat casual packet sniffing and other abuses. Please don't use it for security-critical applications!
To turn on encryption, you need to create a file called .wingdebugpw
which contains a single line of text that is used as the password at both ends
of the debug channel. The line should be in the form
[encrypt]:[password]
where [encrypt]
is one of none
or
rotor
, and [password]
is your password. If you specify only a
password and no encryption type, rotor
is used by default. The value
none
is used when a password is specified to control debug process
attach/detach, as described further in section 6.12 later.
Place a copy of this file into the .wingide
directory in your home
directory (on Linux) or WINGHOME\profiles\[username]
(on Windows).
Whenever this file is present, Wing will enable encryption using the password
in the file. You may need to restart Wing after placing, altering, or removing
this file.
You will also need to place another copy of this file in the same directory as
the remote debug program or within the .wingide
directory of the user
under which the debug program will run (or WINGHOME\profiles\[username]
on Windows).
It is important that both ends of the channel match with respect to whether or not this file is present, what type of encryption is specified, and the password that is given. Passwords are case sensitive. If only one of the files is present or if they do not match, then the debug session will fail to initiate properly, possibly without clear notice of error.
The password is currently stored unencrypted, so it is important to make
sure that the file is readable only by trusted users. Usually the best approach
is to change the file so it is readable only by a single user (for example
with chmod 400
on Linux), and then change ownership of the file to match
the user under which Wing or the debug program will run (for example, with
chown
on Linux).
Encryption will also be turned on for Wing-launched debug sessions as long as
~/.wingide/.wingdebugpw
(on Linux) or
WINGHOME\profiles\[username]\.wingdebugpw
(on Windows) is present and
specifies a non-none
encryption type. Since an encrypted channel is
noticeably slower than an unencrypted channel, you may wish to remove, rename,
or alter this file unless you really need encryption.
A simple API can be used to control debugging more closely, once you have
imported wingdbstub.py
the first time, as was described in section
6.13.1 above.
This is useful in cases where you want to be able to start and stop debugging on the fly several times during a debug run, for example to avoid debug overhead except within a small sub-section of your code.
To use the API, take the following steps:
wingdbstub.py
as described in section
6.13.1.
wingdbstub.debugger
to
make any of the following calls:
kEmbedded
was set to 1
in wingdbstub.py
.
This makes sure the debug connection to the IDE is closed cleanly.Here is a simple usage example:
import wingdbstub a = 1 # This line is debugged wingdbstub.debugger.SuspendDebug() x = 1 # This is executed without debugging wingdbstub.debugger.ResumeDebug() y = 2 # This line is debugged again
Note that SuspendDebug()
and ResumeDebug()
can be called as many
times as desired, and nested calls will be handled so that debugging is
only resumed when the number of ResumeDebug()
calls matches the number
of SuspendDebug()
calls.
It is possible to execute files outside of the debugger. This can be done with any Python code, Makefiles, and any other file that is marked as executable on disk. To do this, select the Execute Current File item in the Run menu to execute the currently at-front document, or use the project manager's popup menu item Execute Selected File.
Files executed in this way are run in a seperate process and any input or output occurs within the window from which Wing was launched (or is entirely hidden if Wing was launched from a desktop icon).
This is useful for triggering builds, executing utilities used in development,
or even to launch a program that is normally launched outside of Wing and
debugged using wingdbstub.py
.
Note that files executed in this way are always invoked as if from their enclosing directory and without any parameters. There is currently no facility for specifying parameters or redirecting input/output.
![]() |
Profiling under the debugger may yield inaccurate results since the debugger adds overhead that isn't always uniform across your code base. |
The Python profiler makes some assumptions about how it is started that conflict with the way the Wing debugger works. Because the debugger can start debugging on the fly in the context of already-running code, it confuses the profiler into using the wrong top-level scope for its activities.
This means that a file like the following will not work:
import profiledef main(): a = 1
profile.run("main()", "profile_tmp")
The profiler will raise an AttributeError
on main
because
it is looking for it in the top-level file, which is not your code
when running under Wing.
The way to solve this problem is to explicitely import and run the function you wish to profile, as follows:
import profiledef main(): a = 1
profile.run("import mymodule; mymodule.main()", "profile_tmp")
![]() |
There are certain situations that the debugger cannot handle, because of the way the Python programming language works. If you are having problems getting the debugger to stop at breakpoints or to display source as you step through your code, please read through the following limitations: |
*.pyc
files can be wrong if your move
your *.pyc
files around on disk. This may cause the IDE to fail to find
source for these files, or to fail to stop at breakpoints set in source files
whose *.pyc
files are moved in this way. A similar problem may result
from use of compileall.py
and some other utilities that don't record a
correct filename. It can also happen if running the same code using different
paths to the same working directory, as is possible on Linux with symbolic
links. However, the latter should only be a problem if you've removed the
symbolic links subsequently. Hint: You can open *.pyc
files in most
text editors to inspect the stored file names. Or just remove these files so
they can be regenerated with the correct file name information.
-O
optimization option
for the Python interpreter. This removes information about line numbers,
making it impossible to stop at breakpoints or step through code.
pdb
in code that you are running within the
Wing debugger. The two debuggers conflict because they attempt to use
the same debugger hooks in the Python interpreter.
__import__
in your code, you will break the
debugger's ability to stop at breakpoints unless you call the original
__import__
as part of your code whenever a module is actually imported.
To work around this, call debug.server.netserver.NotifyImport()
(but
only if you don't store and call the original __import__
, which should
really always be the case anyway!).
wingdbstub
, if you set sys.exitfunc
after
debugging has been started, the IDE will time out in certain rare cases
on a broken network connection after the debug program exits on an exception.
This only happens for exceptions that look like they will be handled because
a try/except block is present that might handle the exception, but where
the exception is not in the end handled and the debug program exits without
calling StopDebug()
. Work-arounds include setting sys.exitfunc
before importing wingdbstub
or adding a top-level try/except clause
that always calls StopDebug()
before exiting the debug program.
If you have paid for a license, you have access to the source code for Wing IDE. The debug server is written in Python and standard C and can be recompiled and used on platforms other than Linux and Windows. When this is done, your debug process runs on a remote host of any type and Wing runs on either Linux or Windows. The remote host does not have to be one that is supported for Wing IDE. For example, the debugger is known to compile and run under Lynx OS, which is a proprietary real-time operating system.
Another reason to recompile the debug server is if you are running against an
altered or experimental version of Python. For example, if the macros
Py_TRACE_REFS
or WITH_CYCLE_GC
are altered from the defaults
shipped with Python, the debug server running against that version of Python
will need to be recompiled.
If you run into any problems with the instructions that follow, please send
email to bugs@archaeopteryx.com
. We'll help you get things working.
How you port the debug server will vary slightly depending on whether or not your operating system supports shared libraries. If it does, you will compile and build a shared library that resides in the debug server source tree on your debug host. If it does not, you need to rebuild Python from source on your debug host with an added module for the debug server.
Both methods require the following two steps first:
http:www.wingide.com/support/downloads
. In
order to gain access to the source files on our website, you must have your
customer number and access password as emailed to you with your license files.
If your debug host supports shared libraries, take these steps next. If it does not, skip to the next sub-section.
src/debug/server/dbgtracermodule.c src/debug/server/dbgtracerhash.c src/debug/server/dbgtracerhash.h src/debug/server/Makefile src/debug/server/setup.pydist
Place copies of these into the WINGHOME/.bin/#.#.#
directory under on
the host where you plan to run your debug program. #.#.#
is the version
of Python that you plan to use for debugging and WINGHOME
is the
directory where you copied the debug server binaries as described in section
6.13.3.
For example, if you created /usr/lib/winghome
on your debug host and
places bin/1.5.2/src/debug/server
and bin/1.5.2/opensource/schannel
there, you would place the source files in bin/1.5.2/src/debug/server
(and not src/debug/server
).
bin/1.5.2/src/debug/server
.
There are three ways to do this, either (a) with the Makefile, (b) with the
distutils script (if you have distutils 1.0.1 or later on your machine), or (c)
with manual compilation. There is no difference in the results of each of these;
choose whichever is most convenient.
If you use the Makefile, you need to change PYPREFIX
and PYINCLUDE
inside the Makefile to match your Python installation. Then type make
.
If you use distutils, you just need to type python setup.pydist build_ext
.
If you want to compile manually, the commands are as follows (but with
the -I
option altered to match the location of your Python's include
directory):
gcc -I/usr/local/include/python1.5 -c dbgtracermodule.c -o dbgtracermodule.o gcc -I/usr/local/include/python1.5 -c dbgtracerhash.c -o dbgtracerhash.o gcc -shared -o dbgtracermodule.so dbgtracermodule.o dbgtracerhash.o
If you plan to run with more than one version of Python, the above steps must
be repeated for each of the versions, using each of
bin/1.5.2/src/debug/server
, bin/2.0.0/src/debug/server
, and
bin/2.1.0/src/debug/server
and the build configuration for locating the
appropriate header files.
When shared libraries are unavailable, you need to rebuild Python in order to statically link the Wing debug tracer into the executable. To do this:
src/debug/server/dbgtracermodule.c src/debug/server/dbgtracerhash.c src/debug/server/dbgtracerhash.h
Place these into the Modules
directory at the top-level of your
Python source tree.
Modules/Setup.local
file and add the following line
to it:
dbgtracer dbgtracerhash.c dbgtracermodule.c
./configure
to set up the build
environment.
make
to build your new Python executable.
make install
if you're running Python from
an installed location (such as /usr/local/bin/python
).
Repeat this with each version of Python that you plan to run. Once completed,
the command import dbgtracer
should complete successfully in a Python
script or when typed at the interactive Python prompt.
Once this is done, debugging happens in exactly the same way as any other
remote debugging. See section remotedebugging
for details.
Please drop us a note at info@wingide.com
to let us know what OS
and version you're using with your debug server!
Because of the way the Python interpreter supports debugging, the debug process may become unresponsive in environments where much time is spent running in non-Python code, such as C or C++. Whenever the Python interpreter is not called for long periods of time, messages from Wing IDE may be entirely ignored and the IDE may disconnect from the debug process as if it had crashed.
Examples of environments that can spend significant amounts of time outside of the Python interpreter include GUI kits such as Gtk, Qt, Tkinter, WXPython, and some web development tools like Zope. For the purposes of this section, we call these "non-Python mainloops".
Wing already supports Gtk, Qt, Tkinter, WXPython, and Zope. If you are using one of these, or you aren't using a non-Python mainloop at all, then you do not need to read further in this section.
Wing uses a network connection between the debug server (the debug process) and the debug client (Wing IDE) to control the debug process from the IDE and to inform the IDE when events (such as reaching a breakpoint or exception) occur in the debug process.
As long as the debug program is paused or stopped at a breakpoint or exception, the debugger remains in charge and it can respond to requests from the IDE. Once the debug program is running, however, the debugger itself is only called as long as Python code is being executed by the interpreter.
This is usually not a problem because most running Python program are executing a lot of Python code! However, in a non-Python mainloop, the program may remain entirely in C, C++, or another language and not call the Python interpreter at all for long periods of time. As a result, the debugger does not get a chance to service requests from the IDE. Pause or attach requests and new breakpoints may be completely ignored in this case, and the IDE may detach from the debug process because it is unresponsive.
Wing deals with this by installing its network sockets into each of the supported non-Python mainloops, when they are detected as present in the debug program. Once the sockets are registered, the non-Python mainloop will call back into Python code whenever there are network requests pending.
For those using an unsupported non-Python mainloop, Wing provides an API for adding the hooks necessary to ensure that the debugger's network sockets are serviced at all times.
If you wish to write support for a non-Python mainloop, you first need to
check whether there is any hope of registering the debugger's socket in that
environment. Any mainloop that already calls UNIX/BSD sockets select()
and is designed for extensible socket registration will work and is easy to
support. Gtk, Qt, and Zope all fell into this category.
In other cases, it may be necessary to write your own select()
call and
to trick the mainloop into calling that periodically. This is how the Tkinter
and WXPython hooks work. Some environments may additionally require writing
some non-Python glue code if the environment is not already set up to call
back into Python code.
Mainloop hooks are written as a seperate modules that are placed into
src/debug/server
within WINGHOME
. The module
_extensions.py
also found there includes a generic class that defines
the API functions required of each module, and is the place where new modules
must be registered (in the constant kSupportedMainloops
).
To add your own non-Python mainloop support, you need to:
_gtkhooks.py
) found
in src/debug/server
, as a framework for writing your hooks. Name
your module something like _xxxxhooks.py
where xxxx
is the
name of your non-Python mainloop environment.
_Setup()
, RegisterSocket()
, and
UnregisterSocket()
methods. Do not alter any code from the
examples except the code with in the methods. The name of the classes
and constants at the top level of the file must remain the same.
'.py'
to the list
kSupportedMainloops
in _extensions.py
The following is a copy of the Python code that supports socket registration
in Gtk. This file is also distributed as source with all copies of Wing,
and can be foundin src/debug/server
within WINGHOME
.
######################################################################### """ _gtkhooks.py - Gtk socket management hooks for the Wing IDE debuggerCopyright (c) 1999-2001, Archaeopteryx Software, Inc. All rights reserved.
Written by Stephan R.A. Deibel and John P. Ehresman
""" #########################################################################
import _extensions
# The name of the module to watch for that indicates presence of this # supported mainloop environment kIndicatorModuleName = 'gtk'
######################################################################### # GTK-specific support for managing the debug server sockets ######################################################################### class _SocketHook(_extensions._SocketHook): """ Class for managing the debug server sockets: This is used only when gtk is detected as being present in the debuggee's code. """
#----------------------------------- def __init__(self, err): """ Constructor """ _extensions._SocketHook.__init__(self, err) self.__fGtkHandlers = self.__fGtkModule = None
#------------------------------------ def _Setup(self, mod, s, cb_fct): """ Attempt to set up socket registration with the given module reference : This should be a reference to the indicator module for the supported environment. The first socket is registered with given action callback via _RegisterSocket(). Returns the socket if succeeded or None if fails (for example, because the module is not yet fully loaded and we cannot yet use it to start registering sockets. Note that the returned socket may be different than the socket passed in because some environments require a wrapper: The returned socket is then used in place of the original in the debug server code. """
# Check if module is fully loaded as far as the constructs we will need if mod.__name__ != 'gtk' or not hasattr(mod, 'GDK') or not hasattr(mod, 'input_add') or not hasattr(mod, 'input_remove') or not hasattr(mod.GDK, 'INPUT_READ') or not hasattr(mod.GDK, 'INPUT_EXCEPTION'): return None
# Try to register the first socket self.__fGtkModule = mod new_sock = self._RegisterSocket(s, cb_fct) if new_sock == None: self.__fGtkModule = None return None
# Success return new_sock
#----------------------------------- def _RegisterSocket(self, s, cb_fct): """ Function to register a socket with a mainloop: Subsequently the given callback function is called whenever there is data to be read on the socket. Returns the socket if succeeded; None if fails. As in _Setup(), the returned socket may differ from the one passed in, in which case the debug server will substitute the socket that is used in its code."""
# Try to use given module to register the socket: This may still fail # if module is in the process of being imported try:
# Register with GTK cond = self.__fGtkModule.GDK.INPUT_READ | self.__fGtkModule.GDK.INPUT_EXCEPTION handler_id = self.__fGtkModule.input_add(s, cond, cb_fct) self.__fGtkHandlers[s] = handler_id
# Done self.fErr.out("################## Socket registered with gtk: ", s) return s
# Failed but will keep checking except: self.fErr.out("################## 'gtk' module not fully loaded") return None
#----------------------------------- def _UnregisterSocket(self, s): """ Function to unregister a socket with the supported environment. The socket passed in should be the one returned from _Setup() or _RegisterSocket(). """
self.fErr.out("################ Deregistered socket with gtk: ", s) self.__fGtkModule.input_remove(self.__fGtkHandlers[s]) del self.__fGtkHandlers[s]
If you are having difficulties writing your non-Python mainloop hooks, please contact our Technical Support group via our website at http://archaeopteryx.com/support. We will be happy to assist you, and welcome the contribution of any hooks you may write.
Debugging CGI scripts can be annoying since any output from your program that is not understood by the web server will cause the server to write an error to its log files rather than displaying anything useful back to the browser.
Here are a few simple suggestions that may help you configure the debugger and verify that things are working correctly:
wingdbstub
or calling the debug API, insert the following temporary line of code:
print "Content-type: text/html<html>"
This will cause all subsequent data to be included in the browser window, even if your normal Content-type specifier code is not being reached.
import sys import cgi import traceback import string#------------------------------------ def DisplayError(): """ Output an error page with traceback, etc """
print "<H2>An Internal Error Occurred!</H2>" print "<I>Runtime Failure Details:</I><P>"
t, val, tb = sys.exc_info() print "<P>Exception = ", t, "<br>" print "Value = ", val, "", "<p>"
print "<I>Traceback:</I><P>" tbf = traceback.format_tb(tb) print "<pre>" for item in tbf: outstr = string.replace(item, '<', '<') outstr = string.replace(outstr, '>', '>') print string.replace(outstr, '', ''), "<BR>" print "</pre>" print "<P>"
cgi.print_environ() print "<BR><BR>"
wingdbstub.py
, you can set
kSilent=0
to receive extra information from the debug
server, in order to debug problems connecting back to Wing IDE.
This information is written to stderr
and thus will
be found in the web server's error log file.
CErrStream
object to send output either to stdout
, stderr
, or any other file
stream. Use this to send errors to the browser, web server error log,
or to a file, respectively.
/var/log/httpd/error_log
. Any errors not seen on the browser are
appended there.
wingdbstub
import in
each and every other top-level CGI in the same way. Because this
can be somewhat tedious, and because the import needs to happen
at the start of each file (in the __main__
scope), it makes
sense to develop your code so that all page loads for a site are through
a single entry point CGI and page-specific behavior is obtained
via dispatch within that CGI to other modules. With Python's
flexible import and invocation features, this is relatively easy to do.
The easiest way to get started with Zope plus Wing is to install the combined
Wing/Zope distribution provided on the CD in the zope
directory or from
our ftp site at ftp://wingide.com/wingide/support/zope/
.
The zope
directory on the CD also contains an HTML document called
zope-wing-howto.html
that describes how to use the combined
distribution, and how to use Wing with an existing Zope installation. This
document is also available on the web through our support library at
http://wingide.com/support/library
.
The following preferences exist for controlling Wing IDE's debug facility:
'raise-always'
to always raise the window, 'raise-never'
to never raise the window (except when explicitely opened from the debugger's
stack view), or 'raise-new'
to raise the window only when stepping
into a new file that isn't the same as the file in which the previous
known run location was found. Default='raise-always'
'raise-always'
or 'raise-never'
. Default='raise-always'
'raise-always'
or 'raise-never'
. Default='raise-always'
false
to disable; true
to enable).
This must be on when the debug program is not launched by Wing IDE
(for example, as with a CGI script). This is the startup default and may
be altered with the Network Mode section of the Run menu. Default=false
('127.0.0.1',)
( ('127.0.0.1', '50015'), )
"*"
to define a default that matches
all otherwise unmatched hosts. The mapping values are arrays of tuples
where each tuple is a (remote_prefix,
local_prefix)
pair. The
remote file name will be a full path name on the debug server file system
and the local file name will be a URL, currently always starting with
file:
. This should be used when files on the remote host are updated
via ftp, NFS, Samba, or other method from master copies on the local host, but
the full path file system locations on the local and remote hosts do not
match. See section 6.13.3 for examples and details.
Default= { '127.0.0.1':[('/','file:/'),]}
true
to allow
Wing to terminate processes that it did not launch but that connected
to its debugger from another locally running process. Whenever this is
set to false
, the Kill menu item and command are disabled when
attached to a debug process launched outside of Wing. Default=false
None
value uses
/usr/bin/env python
on Linux and the configured default on NT.
Otherwise, give the full path of the Python executable, for example
/usr/local/bin/python
or C:\dev\python
. This preference only
affects programs that are launched from Wing and is overridden by any values
specified in Wing's Project Properties or per-file Debug Properties.
Default=None
'never'
to never
stop, 'always' to always stop, or \verb
'unhandled'! to stop only on
unhandled exceptions. This is just the initial value that Wing
will use; it can be changed after starting Wing using the
Exception Mode item in the Run menu. Default='unhandled'
None
to indicate that the debugger
should listen on all valid network interfaces on the machine. Note that when
a debug session is launched from within Wing IDE (with the Run button),
it always connects from the loopback interface (127.0.0.1).
Default=None
wingdbstub
for debugging on a given host.
The debug server needs to be told the value specified here (as described in
sections 6.13.1 and 6.13.6). Note that this value is
ignored if the debug program is launched from the application, in which
case an available random port number is used instead. Default='50005'
5.0
3.0
true
then all debug program input/output happens in a seperate new
terminal window, if false
then input/output happens in the window from
which Wing was launched (if any; when Wing is launched from icon, the debug
processes output may be invisible). On Windows systems, this value is
currently always forced to true
, and a dos shell is used. Important: On
Linux systems where xterm
runs with setuid, your environment variables
are not propagated to the debug program unless explicitely listed in the
wingdb
script found in WINGHOME
. The values of
LD_LIBRARY_PATH
and PYTHONPATH
are propagated by the script that
ships with Wing, but you may need to add any additional environment variables
that your program depends on. Default=false
(but always forced to
true
on Windows)
true
to allow inspection of debug output after exit
of the debug program. This is only relevant when
debug.use-xterm
is set to true
. Default=true
('function', 'builtin_function_or_method',
'class', 'instance method', 'type', 'module', 'ufunc')
()
55
2000
64000
true
in order
to ask the debug server to use the __members__
attribute on values
that are otherwise opaque. This is useful in interpreting some values
defined and set in C extension modules. However, there are sometimes
bugs in these modules that cause crashing when this is used (for example, in
pygtk-0.6.5). Default=false
'tree'
for a dynamic tree display, 'text'
for a textual display,
and 'combo'
for a combination view like that found in the main debugger
window. These values can be overridden from the right-click popup that appears
over any tree formatted debugger variable display. Default='combo'
'symbolic'
, 'parent-ref'
, and 'ref'
. These
values can be overridden from the right-click popup that appears over any
tree formatted debugger variable display. See section 6.7.3
for more information on these choices. Default='symbolic'
true
0
to 255
,
that defines the color used behind the current run line during
debugging. Default=(255, 163, 163)
0
to 255
,
that defines the color used around the margin marker for the current
run position during debugging. Default=(255, 0, 0)
true
to obtain more
detailed information about problems that come up with the Wing debugger
itself (such as failure to start a debug session or unexpected termination
of a debug session). Default=false
Note that currently Wing must be restarted before any altered values take effect.