kdbg: import slightly modified version to make it build

This commit is contained in:
Ivailo Monev 2015-02-25 17:35:06 +00:00
commit 9b6418caa8
250 changed files with 64306 additions and 0 deletions

7
kdbg-2.5.5/BUGS Normal file
View file

@ -0,0 +1,7 @@
Here is an unsorted list of known deficiencies of kdbg.
- Handles only C and C++
- Cannot handle source file names which contain new-lines or
a sequence of the form
:[0-9]+:[0-9]+:beg

16
kdbg-2.5.5/CMakeLists.txt Normal file
View file

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 2.6)
set(KDBG_VERSION 2.5.5)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/kdbg/version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/kdbg/version.h)
find_package(KDE4 REQUIRED)
add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include(KDE4Defaults)
include(MacroLibrary)
#include(ManualStuff.cmake)
#include(ConfigureChecks.cmake)
add_subdirectory(kdbg)
add_subdirectory(po)

280
kdbg-2.5.5/COPYING Normal file
View file

@ -0,0 +1,280 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

View file

@ -0,0 +1,441 @@
Later versions
Please use the gitweb log at http://repo.or.cz/w/kdbg.git to browse
the changes.
Version 2.0.4
Fixed encoding of the Czech translation thanks to Jakub Galgonek.
Added support for QString in Qt4's debug libraries.
Fixed that the debugger window really comes to the foreground and
receives the focus when the debuggee stops at a breakpoint, when this
option is on (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=171845).
Added a filter edit box to the Attach to Process dialog to improve
usability.
Version 2.0.3
Fixed parsing of gdb output that mentions "operator<<", "operator>>",
"operator<", and "operator>" within text delimited by angle brackets <>.
This fixes a crash when any such function is disassembled and other
misbehaviors.
Fixed parsing stack frames that mention "operator<<" or "operator<".
Thanks to Charles Samuels, who pointed out the problem and provided
an initial fix.
Version 2.0.2
Fixed stack display for functions in an anonymous namespace and
for functions whose names involve template parameter lists (thanks to
André Wöbbeking).
Fixed environment list which would add back the entry from the edit box
even if it was just deleted.
Fixed that the Run/Continue button was enabled while the program was
running.
Fixed parsing of NaN (Not a Number) floating point values.
Version 2.0.1
Updated Hungarian translation (thanks to Tamas Szanto).
Worked around gdb 6.3 crashes at "info line main" command (thanks to
Stefan Taferner).
Updated XSLT debugger parser for xsldbg >= 3.4.0 (by Keith Isdale).
Version 2.0.0
References and const types are treated like the base type (thanks to
Shaheed).
Fixed parsing of large arrays with many different values, which were
terminated by "...".
Fixed the kdbg.desktop file: Encoding is UTF-8, install in XDG menu
location.
Fixed PS_COMMAND detection for Solaris' /bin/sh.
Version 1.9.7
Added a new animated button in the toolbar.
Fixed Norwegian translation file names.
Version 1.9.6
"<invalid float value>" in register dumps was not parsed correctly.
Fixed that variable popup location was computed incorrectly if tab
width is not 0.
Updated the manual.
Implemented printing of Qt4's QStrings.
Version 1.9.5
Fixed some issues when the items in the environment variable list
are selected.
Added a command line option to attach to a process (thanks to
Matthew Allen for the initial code).
Fixed the "Using host libthread_db" error message properly.
Fixed inappropriate icon sizes.
Version 1.9.4
Updated the build system to the latest auto* tools.
Worked around the problem that gdb reports "Using host libthread_db"
on Fedora Core when it processes the file command.
Version 1.9.3
Improved editing of values; it is now possible to edit variables also
in the watch window.
Version 1.9.2
The previous security fix only protects against accidents, not attacks,
as Matt Zimmerman pointed out. Did it right this time.
Basic editing of values in the local variables window is available.
More refinements are still necessary.
Version 1.9.1
Fixed security flaw regarding the program specific debugger command.
Configurable key bindings.
Version 1.9.0
Program arguments that are file names can be browsed for.
Added XSLT debugging (using xsldbg) by Keith Isdale.
The program counter can be changed via point and click.
Improved register formating by Daniel Kristjansson.
"Orphaned breakpoints", i.e. breakpoints that gdb cannot set
immediately, can be set. This helps debug shared libraries and
dynamically loaded modules.
Version 1.2.10
Fixed the "Using host libthread_db" error message.
Fixed inappropriate icon sizes.
Version 1.2.9
The previous security fix only protects against accidents, not attacks,
as Matt Zimmerman pointed out. Did it right this time.
Version 1.2.8
Fixed security flaw regarding the program specific debugger command.
Version 1.2.7
Fixed parsing of stack frames for recent gdbs.
Support vector registers (thanks to Daniel Thor Kristjansson for
initial code).
Work around bug in some gdbs which inhibits printing of QString values.
Version 1.2.6
Opening the Find dialog no longer toggles a breakpoint.
Make mouse wheel work (again) in source, variables, and watch windows.
When a pointer to a struct is expanded the struct is also expanded.
Improved toolbar and application icons.
Version 1.2.5
Now compiles for KDE 3.
Fixed make install for builddir != srcdir.
Fixed status bar flicker. This gives a nice speed-up by a factor of 4
when the contents of an array of 50 QStrings are displayed!
Version 1.2.4
Now compiles for KDE 3 (Beta1).
Support QString of Qt 3.x.
Improved (and fixed) the display of arrays with repeated values.
Fixed crash when a file is reloaded while disassembled code is
displayed.
Fixed parsing of stack frames involving signal handler invocations.
Version 1.2.3
Fixed invisible toolbar under KDE 2.x (really, this time, I promise).
Fixed crash when no line has the cursor (empty files).
Don't display a blank page when a non-existing file was tried to open.
Version 1.2.2
Fixed a special, but common case where removing a breakpoint didn't
work but add more on the same line instead (thanks to Ron Lerech).
Fixed invisible toolbar under KDE 2.1.2 (thanks to Neil Butterworth).
Fixed compilation for gcc 3.0 (thanks to Ben Burton):
Fixed make install if srcdir != builddir.
Changed encoding of German translations (and also Danish, Italian,
Norwegian, Romanian, Slovak, Swedish) to UTF-8, which fixes message
strings under KDE2 (at least for German - couldn't test the others).
Version 1.2.1
Working directory can be browsed for.
Added context menu to move the selected expression from the local
variables window to the watch window.
Fixed crash when environment variables are removed.
Fixed problems with trailing backslashes in watched expressions.
Fixed compilation on FreeBSD (openpty).
Version 1.2.0
Translations for: Hungarian, Japanese, Norwegian (Nynorsk), Serbian,
Turkish
Updated the User's Manual (English, Russian (thanks, Ilmar!), German).
Version 1.1.7beta1
Improved the program icon; made the installation more KDE2 compliant.
Enabled mouse wheel scrolling at various places.
Version 1.1.6
Added memory display.
Single-stepping by instruction.
Watchpoints. Finally! (On Linux/i386 works best with gdb 5!)
Version 1.1.5
Made Delete key work in the watch window.
Breakpoints can be enabled and disabled in the breakpoint list.
Detach from debugged program on exit (and when new program is debugged).
Added a list of recently opened executables (thanks to
Thomas Sparr <thomas.sparr@kreatel.se>).
Version 1.1.4
Fixed endless loop on shutdown.
Brought in line with KDE 1.91 (KDE 2 beta).
Version 1.1.3
Debugging of multi-threaded programs. Requires a gdb that supports
multi-threaded programs, like gdb 5.
Debugger window pops into the foreground when the program stops.
Made tab width a user-settable option.
Version 1.1.2
Display disassembled code.
Version 1.1.1
Use the KDE system fixed font for the source code window.
By default, do not log communication with gdb.
Added an integrated output window (based on code by Judin Max).
Program specific settings can be set. In particular: the debugger
command (required if you are debugging remote devices), the
terminal emulation needed for the program.
Verison 1.1.0
Use docking windows thanks to Judin Max <novaprint@mtu-net.ru>.
Added a register dump window. Based on code by Judin Max.
Implemented "balloons" (tool tips) that show variable values.
./configure fix for NetBSD thanks to
Berndt Josef Wulf <wulf@ping.net.au>.
There's now a Swedish translation thanks to
Örjan Lindbergh <orjan.lindbergh@telia.com>.
Version 1.0.2
Save and restore watched expressions.
More adjustments for the KRASH release.
Show <repeat...> count in QStrings like in normal C strings instead
of repeating the characters.
Use QListView instead of KTabListBox.
Version 1.0.1
Added a hack to set a remote target. Thanks to
Johnny Chan <johnnykc@iprg.nokia.com>.
Display function arguments. Based on suggestions by Johnny Chan.
KDE 2 fixes.
Support builddir != srcdir.
Version 1.0.0
Brought up-to-date for latest KDE 2.
Version 1.0beta3
Removal of minor misfeatures.
Prepared for KDE 2 and Qt 2 (it's a configure option:
--with-kde-version=2).
Added Russian documentation (thanks to
Ilmar S. Habibulin <ilmar@ints.ru>) and German documentation.
There is now a Spanish translation thanks to
Manuel Soriano <manu@europa3.com>.
Version 1.0beta2
Recognize strings with repeated characters: 'x' <repeats 34 times>.
Fix structs with no (additional) data members and other fixes
for gdb 4.18.
Save window size across sessions.
There is now an Italian translation thanks to
Massimo Morin <mmorin@schedsys.com>.
Version 1.0beta1
Fixed non-displaying QString (Qt2) with certain gdb 4.17's (at least
mine here, of SuSE 6.1, had a problem :-)
Fixed cases where gdb commands where executed after debuggee has exited.
Do not execute gdb commands after an interrupt.
Updated some translations. Still most are incomplete. Please help!
There is now a Polish translation thanks to
Jacek Wojdel <wojdel@kbs.twi.tudelft.nl>.
Version 0.3.1
The working directory for the program being debugged can be set
(Execution|Arguments).
There's now a global options dialog in place (File|Global Options).
At the moment the debugger program (which must be gdb, but it could be
an experimental gdb version, for example) and the terminal for program
output can be specified.
Fixed Makefiles to support make DESTDIR=/tmp/foo install (which is
needed by packagers and to create relocatable RPMs).
There's now a Danish translation thanks to
Steen Rabol <rabol@get2net.dk>.
Version 0.3.0
Starting with this version, Qt 1.42 and KDE 1.1 is required.
Ported to Qt 2.0 and KDE post-1.1! KDbg now runs with both
KDE 1.1 (using Qt 1.42) and the latest experimental KDE. You can of
course run one version and debug programs written for the other version.
KDbg can now display Qt 2.0's QString values (which are Unicode
strings)!
Environment variables can be set. Changes become effective the next time
the program being debugged is run.
The breakpoint list has been improved. It disables command buttons at
times when it is not possible to change breakpoints. The icons that
show the breakpoint status are now the same as those in the source
window.
Popup menus (context menus) for frequently used commands have been added
to the source code window (thanks to Tom Nguyen <ttomnguyen@yahoo.com>)
There's now a Russian translation thanks to
Ilmar Habibulin <ilmar@ints.ru>.
Internal restructuring. These changes are invisible. They just make
future extensions less cumbersome.
Version 0.2.5
This is the last version that supports Qt 1.33 and KDE 1.0.
There's now a Czech translation thanks to
Martin Spirk <spirk@kla.pvt.cz>.
Recognize and report when gdb dies unexpectedly. This happens commonly
when writing CORBA programs since gdb obviously has problems in
debugging C++ classes with virtual base classes.
Added conditional breakpoints and ignore counts.
Version 0.2.4
Added a toolbar button to load the executable. The button to open a
source file is still there. I hope it's clear which one does what.
Attaching to a running process is now possible (Execution|Attach).
Made more visible when gdb is busy using a gear wheel in the upper right
corner of the window like kfm.
Made the KTreeView widget more flexible by adding a bunch of virtual
keywords. (No, this doesn't have any influence on the look and feel of
KDbg.) While doing that, I fixed a small repainting bug.
ChangeLog starts here.

22
kdbg-2.5.5/README Normal file
View file

@ -0,0 +1,22 @@
This is KDbg, a graphical user interface around gdb using
KDE, the K Desktop Environment.
To install:
cmake -DCMAKE_INSTALL_PREFIX=/opt/kde4 .
make
sudo make install
(Make sure your KDE is installed in /opt/kde4; adjust the path
to suit your system. On some systems it is /usr.)
Problem reports as well as success stories are welcome!
The homepage is at
http://www.kdbg.org/
You'll find the most recent version of KDbg there as well as
other useful information concerning debugging.
Johannes Sixt <j6t@kdbg.org>

View file

@ -0,0 +1,36 @@
KDbg Release Notes for version 2.2.0
====================================
The 2.2.x series is still based on Qt 3 and KDE 3.
Changes since 2.1.1
-------------------
Features:
- Source code windows have now a tab attached, which makes switching
source files much easier.
- Source code windows now show line numbers at the left.
- There are now "Find Next" and "Find Previous" commands with shortcuts
F3 and Shift+F3.
- Improved support of template types in the type tables (which are used
to show structure members next to a structure variable). Notably, the
number of elements in STL and Qt collection classes are shown.
- Arguments for the debugged program can be passed on KDbg's command line.
Bug fixes
- An incorrect terminal command string setting could crash KDbg if it
contained format specifiers other than exactly one '%s'.
- The format specifier in the memory dump window was not correctly
preserved when the expression is changed.
- Setting a conditional breakpoint could crash KDbg.
- Using Attach on systems that use the simplified Attach to Process dialog
could crash KDbg.

View file

@ -0,0 +1,23 @@
KDbg Release Notes for version 2.2.1
====================================
The 2.2.x series is still based on Qt 3 and KDE 3.
Changes since 2.2.0
-------------------
Bug fixes
- Compilation with newer glibc failed.
- A crash could occur when the variable window was updated.
- A crash when command line switch -a was used together with a non-existing
executable name.
- Syntax highlighting was applied to all files, not just C/C++.
- The display was incorrect when a file was reloaded that had disassembly
lines visible.
There are also some minor documentation fixes.

View file

@ -0,0 +1,11 @@
KDbg Release Notes for version 2.2.2
====================================
The 2.2.x series is still based on Qt 3 and KDE 3.
Changes since 2.2.1
-------------------
There is only one bug fix:
- An error message was shown instead of assembler code when gdb 7.1 was used.

View file

@ -0,0 +1,22 @@
KDbg Release Notes for version 2.5.0
====================================
This release is based on KDE4 and Qt4.
Changes since 2.2.2
-------------------
- A number of icons were exchanged with Oxygen icons. These are not part
of KDbg's source code.
- Session state per debugged program is now stored in a section in $KDEHOME
rather than in a .kdbgrc file in the program's directory. This allows to
debug programs that are located in unwritable directories. But this also
means that earlier session information is disregarded.
- More accurate parsing of GDB responses of various commands fixed bugs in
certain areas, in particular, temporary breakpoints, register values,
truncated struct values, disassembly (again).
- "View Code" from the breakpoint list can open the source code in more cases.

View file

@ -0,0 +1,21 @@
KDbg Release Notes for version 2.5.1
====================================
Changes since 2.5.0
-------------------
Minor feature enhancements
- .hpp files undergo syntax highlighting.
- Keys j and k can be used to move the cursor position in the source code.
Bug fixes
- Cooperation with newer GDB (7.2 and 7.3) is improved:
. wchar_t strings as printed by GDB 7.2 are recognized;
. the thread list was missing with GDB 7.3;
. program exit was not detected (also GDB 7.3).
- Enum values in anonymous namespaces are now recognized.

View file

@ -0,0 +1,14 @@
KDbg Release Notes for version 2.5.2
====================================
Changes since 2.5.1
-------------------
Bug fixes
- Support for GDB 7.5.
- More of GDB's output is recognized in some corner cases
- The thread list parser introduced in 2.5.1 sometimes stripped two letters
from the function name.

View file

@ -0,0 +1,19 @@
KDbg Release Notes for version 2.5.3
====================================
Changes since 2.5.2
-------------------
Bug fixes
- Duplicated and <MULTIPLE> breakpoints do not increase the list of
breakpoints each time a session is started
- Communication with a localized GDB works; this is achieved by setting
LC_ALL=C, which is also propagated to the program being debugged. If
The program needs a different locale, set it in Execution->Arguments,
page Environment.
- Fixed a crash in the memory window
- Updates of the Russian and Croatian translations.

View file

@ -0,0 +1,18 @@
KDbg Release Notes for version 2.5.4
====================================
Changes since 2.5.3
-------------------
Bug fixes
- Source file names with international characters are handled better.
- When an executable is loaded, GDBs of different vintage print different
text, some of which were treated as error text incorrectly, leading to
failed debugging sessions. More of these texts are now ignored.
- Variables pointing to some global variable lacked the ability to be
expanded with recent GDBs.
- Parsing of string values residing in global variables was fixed.

View file

@ -0,0 +1,18 @@
KDbg Release Notes for version 2.5.5
====================================
Changes since 2.5.4
-------------------
Bug fixes
- A crash when the hotkey settings are changed was fixed.
- The animation button was regenerated to avoid a crash with modern Qt.
Thanks to Armin Felder for the initial fix.
- Pretty-printers and GDB Python extensions were disabled, because they
would interfere with the output parser.
- Recent GDBs do not terminate on receipt of SIGTERM, keeping KDbg
running for 20 seconds. This was fixed.

44
kdbg-2.5.5/TODO Normal file
View file

@ -0,0 +1,44 @@
7. Show a list of files for the executable.
9. Use gnuclient to show source code in emacs.
10. Provide formatting options in watch window via mouse, not /FMT.
13. Remember which subtrees have been expanded even when function is left and
reentered.
14. Speed up direct members by reusing values that are already available in
members.
19. Improve support of breakpoints in source files having directories in their
names.
22. Allow to change whether signals are handled or ignored.
24. Allow to view fewer or more bytes in the memory dump. Beautify the display.
25. Automatic single-stepping by instruction when a source line is disassembled.
26. Let the user hide some members of certain structures (on a per-type basis).
The parent indicates whether all members are visible. Provide a context menu
to display the hidden entries. Save the settings somewhere.
28. Better support for remote debugging and special versions of gdb, e.g.
"target pilot localhost:2000".
29. "Crash report" function: Stack trace with excerpts of the source code and
variable dumps for every frame.
30. Grey out watch window expressions if there are variables that are not
in scope.
31. Show the memory dump in a combined ASCII and hex view.
32. Allow to manipulate memory in the memory dump window
33. Clear the status bar when the program is (re-)started (because if this takes
some time, you don't know whether KDbg does something.)
35. Allow to copy variable values to the clipboard.
36.

67
kdbg-2.5.5/kdbg.spec Normal file
View file

@ -0,0 +1,67 @@
%define name kdbg
%define version 2.5.4
%define release 1.kde4
%define prefix /usr
%define src_dir %{name}-%{version}
%define builddir $RPM_BUILD_DIR/%{name}-%{version}
Summary: KDbg - KDE Debugging GUI around gdb
Name: %{name}
Version: %{version}
Release: %{release}
Prefix: %{prefix}
Group: X11/KDE/Development
License: GPL
Distribution: RedHat 7.0
Vendor: Johannes Sixt <j6t@kdbg.org>
Packager: Ullrich von Bassewitz <uz@musoftware.de>
Source: %{name}-%{version}.tar.gz
URL: http://www.kdbg.org/
Requires: kdelibs >= 2.0
BuildRoot: /tmp/build-%{name}-%{version}
%description
KDbg is a graphical user interface to gdb, the GNU debugger. It provides
an intuitive interface for setting breakpoints, inspecting variables, and
stepping through code.
%prep
rm -rf $RPM_BUILD_ROOT
rm -rf %{builddir}
%setup
touch `find . -type f`
%build
rm -f CMakeCache.txt
cmake . -DCMAKE_INSTALL_PREFIX=/usr
make -j4
%install
if [ -z "$KDEDIR" ]; then
export KDEDIR=%{prefix}
fi
rm -rf $RPM_BUILD_ROOT
make DESTDIR=$RPM_BUILD_ROOT install
cd $RPM_BUILD_ROOT
find . -type d | sed '1,2d;s,^\.,\%attr(-\,root\,root) \%dir ,' > \
$RPM_BUILD_DIR/file.list.%{name}
find . -type f | sed -e 's,^\.,\%attr(-\,root\,root) ,' \
-e '/\/config\//s|^|%config|' >> \
$RPM_BUILD_DIR/file.list.%{name}
find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> \
$RPM_BUILD_DIR/file.list.%{name}
echo "%docdir $KDEDIR/share/doc/HTML" >> $RPM_BUILD_DIR/file.list.%{name}
%clean
rm -rf $RPM_BUILD_ROOT
rm -rf %{builddir}
rm -f $RPM_BUILD_DIR/file.list.%{name}
%files -f ../file.list.%{name}

View file

@ -0,0 +1,94 @@
add_subdirectory(doc)
add_subdirectory(pics)
add_subdirectory(typetables)
include_directories(${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} )
include(CheckFunctionExists)
CHECK_INCLUDE_FILES(pty.h HAVE_PTY_H)
CHECK_INCLUDE_FILES(libutil.h HAVE_LIBUTIL_H)
CHECK_INCLUDE_FILES(util.h HAVE_UTIL_H)
CHECK_LIBRARY_EXISTS(util openpty "" HAVE_LIB_UTIL)
if (HAVE_LIB_UTIL)
set(CMAKE_REQUIRED_LIBRARIES util)
endif (HAVE_LIB_UTIL)
CHECK_FUNCTION_EXISTS(openpty HAVE_FUNC_OPENPTY)
message("-- Looking for a suitable 'ps' invocation")
FIND_PROGRAM(PROG_PS ps)
IF (PROG_PS)
set(PS_ARGS -eo pid,ppid,uid,vsz,etime,time,args)
execute_process(COMMAND ${PROG_PS} ${PS_ARGS}
RESULT_VARIABLE PS_FAILED
OUTPUT_QUIET ERROR_QUIET)
IF (NOT PS_FAILED)
execute_process(
COMMAND ${PROG_PS} ${PS_ARGS}
COMMAND sed -e "s/ */ /g" -e 1q
OUTPUT_VARIABLE PS_HEADER)
string(STRIP "${PS_HEADER}" PS_HEADER)
IF (PS_HEADER STREQUAL "PID PPID UID VSZ ELAPSED TIME COMMAND")
# enclose arguments in double-quotes
set(PS_COMMAND \"${PROG_PS}\")
set(PS_MSG ${PROG_PS})
foreach (I ${PS_ARGS})
set(PS_COMMAND ${PS_COMMAND},\"${I}\")
set(PS_MSG "${PS_MSG} ${I}")
endforeach (I)
message("-- Found 'ps' command: ${PS_MSG}")
ENDIF (PS_HEADER STREQUAL "PID PPID UID VSZ ELAPSED TIME COMMAND")
ENDIF (NOT PS_FAILED)
ENDIF (PROG_PS)
IF (NOT PS_COMMAND)
message("-- Looking for a suitable 'ps' invocation - not found")
ENDIF (NOT PS_COMMAND)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
set(kdbg_SRCS
pgmargs.cpp
procattach.cpp
debugger.cpp
dbgdriver.cpp
gdbdriver.cpp
xsldbgdriver.cpp
brkpt.cpp
exprwnd.cpp
regwnd.cpp
memwindow.cpp
threadlist.cpp
sourcewnd.cpp
winstack.cpp
ttywnd.cpp
typetable.cpp
prefdebugger.cpp
prefmisc.cpp
pgmsettings.cpp
watchwindow.cpp
dbgmainwnd.cpp
main.cpp
)
set(kdbg_UI
brkptbase.ui
brkptcondition.ui
pgmargsbase.ui
procattachbase.ui
)
kde4_add_ui_files(kdbg_SRCS ${kdbg_UI})
kde4_add_app_icon(kdbg_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/pics/hi*-app-kdbg.png")
kde4_add_app_icon(kdbg_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/pics/lo*-app-kdbg.png")
kde4_add_executable(kdbg ${kdbg_SRCS})
IF (HAVE_LIB_UTIL)
set(LIB_UTIL util)
ENDIF (HAVE_LIB_UTIL)
target_link_libraries(kdbg ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${LIB_UTIL})
install(TARGETS kdbg ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES kdbg.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
install(FILES kdbgrc DESTINATION ${CONFIG_INSTALL_DIR})
install(FILES kdbgui.rc DESTINATION ${DATA_INSTALL_DIR}/kdbg)

372
kdbg-2.5.5/kdbg/brkpt.cpp Normal file
View file

@ -0,0 +1,372 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#include <kglobal.h>
#include <klocale.h> /* i18n */
#include <kiconloader.h>
#include <kconfig.h>
#include <QDialog>
#include <QFileInfo>
#include <QPainter>
#include <QLabel>
#include <QBitmap>
#include <QPixmap>
#include <QMouseEvent>
#include "debugger.h"
#include "brkpt.h"
#include "dbgdriver.h"
#include <ctype.h>
#include <list>
#include "mydebug.h"
#include "ui_brkptcondition.h"
class BreakpointItem : public QTreeWidgetItem, public Breakpoint
{
public:
BreakpointItem(QTreeWidget* list, const Breakpoint& bp);
void updateFrom(const Breakpoint& bp);
void display(); /* sets icon and visible texts */
bool enabled() const { return Breakpoint::enabled; }
};
BreakpointTable::BreakpointTable(QWidget* parent) :
QWidget(parent),
m_debugger(0)
{
m_ui.setupUi(this);
connect(m_ui.bpEdit, SIGNAL(returnPressed()),
this, SLOT(on_btAddBP_clicked()));
initListAndIcons();
connect(m_ui.bpList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
this, SLOT(updateUI()));
// double click on item is same as View code
connect(m_ui.bpList,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
this, SLOT(on_btViewCode_clicked()));
// need mouse button events
m_ui.bpList->viewport()->installEventFilter(this);
}
BreakpointTable::~BreakpointTable()
{
}
void BreakpointTable::updateBreakList()
{
std::list<BreakpointItem*> deletedItems;
for (int i = 0 ; i < m_ui.bpList->topLevelItemCount(); i++)
{
deletedItems.push_back(static_cast<BreakpointItem*>(m_ui.bpList->topLevelItem(i)));
}
// get the new list
for (KDebugger::BrkptROIterator bp = m_debugger->breakpointsBegin(); bp != m_debugger->breakpointsEnd(); ++bp)
{
// look up this item
for (std::list<BreakpointItem*>::iterator o = deletedItems.begin(); o != deletedItems.end(); ++o)
{
if ((*o)->id == bp->id) {
(*o)->updateFrom(*bp);
deletedItems.erase(o); /* don't delete */
goto nextItem;
}
}
// not in the list; add it
new BreakpointItem(m_ui.bpList,*bp);
nextItem:;
}
// delete all untouched breakpoints
while (!deletedItems.empty()) {
delete deletedItems.front();
deletedItems.pop_front();
}
}
BreakpointItem::BreakpointItem(QTreeWidget* list, const Breakpoint& bp) :
QTreeWidgetItem(list),
Breakpoint(bp)
{
display();
}
void BreakpointItem::updateFrom(const Breakpoint& bp)
{
Breakpoint::operator=(bp); /* assign new values */
display();
}
void BreakpointTable::on_btAddBP_clicked()
{
// set a breakpoint at the specified text
QString bpText = m_ui.bpEdit->text();
bpText = bpText.trimmed();
if (m_debugger->isReady())
{
Breakpoint* bp = new Breakpoint;
bp->text = bpText;
m_debugger->setBreakpoint(bp, false);
}
}
void BreakpointTable::on_btAddWP_clicked()
{
// set a watchpoint for the specified expression
QString wpExpr = m_ui.bpEdit->text();
wpExpr = wpExpr.trimmed();
if (m_debugger->isReady()) {
Breakpoint* bp = new Breakpoint;
bp->type = Breakpoint::watchpoint;
bp->text = wpExpr;
m_debugger->setBreakpoint(bp, false);
}
}
void BreakpointTable::on_btRemove_clicked()
{
BreakpointItem* bp = static_cast<BreakpointItem*>(m_ui.bpList->currentItem());
if (bp != 0) {
m_debugger->deleteBreakpoint(bp->id);
// note that bp may be deleted by now
// (if bp was an orphaned breakpoint)
}
}
void BreakpointTable::on_btEnaDis_clicked()
{
BreakpointItem* bp = static_cast<BreakpointItem*>(m_ui.bpList->currentItem());
if (bp != 0) {
m_debugger->enableDisableBreakpoint(bp->id);
}
}
void BreakpointTable::on_btViewCode_clicked()
{
BreakpointItem* bp = static_cast<BreakpointItem*>(m_ui.bpList->currentItem());
if (bp == 0)
return;
if (!m_debugger->infoLine(bp->fileName, bp->lineNo, bp->address))
emit activateFileLine(bp->fileName, bp->lineNo, bp->address);
}
void BreakpointTable::updateUI()
{
bool enableChkpt = m_debugger->canChangeBreakpoints();
m_ui.btAddBP->setEnabled(enableChkpt);
m_ui.btAddWP->setEnabled(enableChkpt);
BreakpointItem* bp = static_cast<BreakpointItem*>(m_ui.bpList->currentItem());
m_ui.btViewCode->setEnabled(bp != 0);
if (bp == 0) {
enableChkpt = false;
} else {
if (bp->enabled()) {
m_ui.btEnaDis->setText(i18n("&Disable"));
} else {
m_ui.btEnaDis->setText(i18n("&Enable"));
}
}
m_ui.btRemove->setEnabled(enableChkpt);
m_ui.btEnaDis->setEnabled(enableChkpt);
m_ui.btConditional->setEnabled(enableChkpt);
}
bool BreakpointTable::eventFilter(QObject* ob, QEvent* ev)
{
if (ev->type() == QEvent::MouseButtonPress)
{
QMouseEvent* mev = static_cast<QMouseEvent*>(ev);
if (mev->button() == Qt::MidButton) {
// enable or disable the clicked-on item
BreakpointItem* bp =
static_cast<BreakpointItem*>(m_ui.bpList->itemAt(mev->pos()));
if (bp != 0)
{
m_debugger->enableDisableBreakpoint(bp->id);
}
return true;
}
}
return QWidget::eventFilter(ob, ev);
}
class ConditionalDlg : public QDialog
{
private:
Ui::BrkPtCondition m_ui;
public:
ConditionalDlg(QWidget* parent);
~ConditionalDlg();
void setCondition(const QString& text) { m_ui.condition->setText(text); }
QString condition() { return m_ui.condition->text(); }
void setIgnoreCount(uint count){ m_ui.ignoreCount->setValue(count); };
uint ignoreCount(){ return m_ui.ignoreCount->value(); };
};
void BreakpointTable::on_btConditional_clicked()
{
BreakpointItem* bp = static_cast<BreakpointItem*>(m_ui.bpList->currentItem());
if (bp == 0)
return;
/*
* Important: we must not keep a pointer to the Breakpoint around,
* since it may vanish while the modal dialog is open through other
* user interactions (like clicking at the breakpoint in the source
* window)!
*/
int id = bp->id;
ConditionalDlg dlg(this);
dlg.setCondition(bp->condition);
dlg.setIgnoreCount(bp->ignoreCount);
if (dlg.exec() != QDialog::Accepted)
return;
QString conditionInput = dlg.condition();
int ignoreCount = dlg.ignoreCount();
m_debugger->conditionalBreakpoint(id, conditionInput, ignoreCount);
}
void BreakpointTable::initListAndIcons()
{
m_ui.bpList->setColumnWidth(0, 220);
m_ui.bpList->setColumnWidth(1, 65);
m_ui.bpList->setColumnWidth(2, 30);
m_ui.bpList->setColumnWidth(3, 30);
m_ui.bpList->setColumnWidth(4, 200);
// add pixmaps
QPixmap brkena = UserIcon("brkena");
QPixmap brkdis = UserIcon("brkdis");
QPixmap watchena = UserIcon("watchena");
QPixmap watchdis = UserIcon("watchdis");
QPixmap brktmp = UserIcon("brktmp");
QPixmap brkcond = UserIcon("brkcond");
QPixmap brkorph = UserIcon("brkorph");
/*
* There are 32 different pixmaps: The basic enabled or disabled
* breakpoint, plus an optional overlaid brktmp icon plus an optional
* overlaid brkcond icon, plus an optional overlaid brkorph icon. Then
* the same sequence for watchpoints.
*/
m_icons.resize(32);
QPixmap canvas(16,16);
for (int i = 0; i < 32; i++) {
{
QPainter p(&canvas);
// clear canvas
p.fillRect(0,0, canvas.width(),canvas.height(), Qt::cyan);
// basic icon
if (i & 1) {
p.drawPixmap(1,1, (i & 8) ? watchena : brkena);
} else {
p.drawPixmap(1,1, (i & 8) ? watchdis : brkdis);
}
// temporary overlay
if (i & 2) {
p.drawPixmap(1,1, brktmp);
}
// conditional overlay
if (i & 4) {
p.drawPixmap(1,1, brkcond);
}
// orphan overlay
if (i & 16) {
p.drawPixmap(1,1, brkorph);
}
}
canvas.setMask(canvas.createHeuristicMask());
m_icons[i] = QIcon(canvas);
}
}
void BreakpointItem::display()
{
BreakpointTable* lb = static_cast<BreakpointTable*>(treeWidget()->parent());
/* breakpoint icon code; keep order the same as in BreakpointTable::initListAndIcons */
int code = enabled() ? 1 : 0;
if (temporary)
code += 2;
if (!condition.isEmpty() || ignoreCount > 0)
code += 4;
if (Breakpoint::type == watchpoint)
code += 8;
if (isOrphaned())
code += 16;
setIcon(0, lb->m_icons[code]);
// more breakpoint info
if (!location.isEmpty()) {
setText(0, location);
} else if (!Breakpoint::text.isEmpty()) {
setText(0, Breakpoint::text);
} else if (!fileName.isEmpty()) {
// use only the file name portion
QString file = QFileInfo(fileName).fileName();
// correct zero-based line-numbers
setText(0, file + ":" + QString::number(lineNo+1));
} else {
setText(0, "*" + address.asString());
}
int c = 0;
setText(++c, address.asString());
QString tmp;
if (hitCount == 0) {
setText(++c, QString());
} else {
tmp.setNum(hitCount);
setText(++c, tmp);
}
if (ignoreCount == 0) {
setText(++c, QString());
} else {
tmp.setNum(ignoreCount);
setText(++c, tmp);
}
if (condition.isEmpty()) {
setText(++c, QString());
} else {
setText(++c, condition);
}
}
ConditionalDlg::ConditionalDlg(QWidget* parent) :
QDialog(parent)
{
m_ui.setupUi(this);
QString title = KGlobal::caption();
title += i18n(": Conditional breakpoint");
setWindowTitle(title);
}
ConditionalDlg::~ConditionalDlg()
{
}
#include "brkpt.moc"

65
kdbg-2.5.5/kdbg/brkpt.h Normal file
View file

@ -0,0 +1,65 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef BRKPT_H
#define BRKPT_H
#include <QIcon>
#include <QEvent>
#include <vector>
#include "ui_brkptbase.h"
class KDebugger;
class BreakpointItem;
class BreakpointTable : public QWidget
{
Q_OBJECT
public:
BreakpointTable(QWidget* parent);
~BreakpointTable();
void setDebugger(KDebugger* deb) { m_debugger = deb; }
protected:
KDebugger* m_debugger;
Ui::BrkPtBase m_ui;
std::vector<QIcon> m_icons;
void insertBreakpoint(int num, bool temp, bool enabled, QString location,
QString fileName = 0, int lineNo = -1,
int hits = 0, uint ignoreCount = 0,
QString condition = QString());
void initListAndIcons();
virtual bool eventFilter(QObject* ob, QEvent* ev);
friend class BreakpointItem;
signals:
/**
* This signal is emitted when the user wants to go to the source code
* where the current breakpoint is in.
*
* @param file specifies the file; this is not necessarily a full path
* name, and if it is relative, you won't know relative to what, you
* can only guess.
* @param lineNo specifies the line number (0-based!).
* @param address specifies the exact address of the breakpoint.
*/
void activateFileLine(const QString& file, int lineNo, const DbgAddr& address);
public slots:
void on_btAddBP_clicked();
void on_btAddWP_clicked();
void on_btRemove_clicked();
void on_btEnaDis_clicked();
void on_btViewCode_clicked();
void on_btConditional_clicked();
void updateUI();
void updateBreakList();
};
#endif // BRKPT_H

View file

@ -0,0 +1,139 @@
<ui version="4.0" >
<class>BrkPtBase</class>
<widget class="QWidget" name="BrkPtBase" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>591</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<widget class="KLineEdit" name="bpEdit" >
<property name="showClearButton" stdset="0" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="bpList" >
<property name="rootIsDecorated" >
<bool>false</bool>
</property>
<column>
<property name="text" >
<string>Location</string>
</property>
</column>
<column>
<property name="text" >
<string>Address</string>
</property>
</column>
<column>
<property name="text" >
<string>Hits</string>
</property>
</column>
<column>
<property name="text" >
<string>Ignore</string>
</property>
</column>
<column>
<property name="text" >
<string>Condition</string>
</property>
</column>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QPushButton" name="btAddBP" >
<property name="text" >
<string>Add &amp;Breakpoint</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btAddWP" >
<property name="text" >
<string>Add &amp;Watchpoint</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btRemove" >
<property name="text" >
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btEnaDis" >
<property name="text" >
<string>&amp;Disable</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btViewCode" >
<property name="text" >
<string>&amp;View Code</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btConditional" >
<property name="text" >
<string>&amp;Conditional...</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>bpEdit</tabstop>
<tabstop>bpList</tabstop>
<tabstop>btAddBP</tabstop>
<tabstop>btAddWP</tabstop>
<tabstop>btRemove</tabstop>
<tabstop>btEnaDis</tabstop>
<tabstop>btViewCode</tabstop>
<tabstop>btConditional</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,122 @@
<ui version="4.0" >
<class>BrkPtCondition</class>
<widget class="QDialog" name="BrkPtCondition" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>98</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="font" >
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text" >
<string>&amp;Condition:</string>
</property>
<property name="buddy" >
<cstring>condition</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="KLineEdit" name="condition" />
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Ignore &amp;next hits:</string>
</property>
<property name="buddy" >
<cstring>ignoreCount</cstring>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QSpinBox" name="ignoreCount" >
<property name="specialValueText" >
<string>do not ignore</string>
</property>
<property name="correctionMode" >
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
</property>
<property name="suffix" >
<string/>
</property>
<property name="prefix" >
<string/>
</property>
<property name="maximum" >
<number>999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>BrkPtCondition</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>222</x>
<y>72</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>86</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>BrkPtCondition</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>290</x>
<y>78</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>86</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -0,0 +1,13 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef COMMANDIDS_H
#define COMMANDIDS_H
// statusbar ids
#define ID_STATUS_MSG 191
#define ID_STATUS_ACTIVE 193
#endif // COMMANDIDS_H

View file

@ -0,0 +1,10 @@
#ifndef CONFIG_H_Included
#define CONFIG_H_Included
#cmakedefine HAVE_FUNC_OPENPTY
#cmakedefine HAVE_LIBUTIL_H
#cmakedefine HAVE_PTY_H
#cmakedefine HAVE_UTIL_H
#cmakedefine PS_COMMAND @PS_COMMAND@
#endif // CONFIG_H_Included

View file

@ -0,0 +1,460 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#include "dbgdriver.h"
#include "exprwnd.h"
#include <QStringList>
#include <ctype.h>
#include <signal.h>
#include <stdlib.h> /* strtol, atoi */
#include <algorithm>
#include "mydebug.h"
#include <assert.h>
DebuggerDriver::DebuggerDriver() :
m_state(DSidle),
m_activeCmd(0)
{
// debugger process
connect(this, SIGNAL(readyReadStandardOutput()), SLOT(slotReceiveOutput()));
connect(this, SIGNAL(bytesWritten(qint64)), SLOT(slotCommandRead()));
connect(this, SIGNAL(finished(int, QProcess::ExitStatus)),
SLOT(slotExited()));
}
DebuggerDriver::~DebuggerDriver()
{
flushHiPriQueue();
flushLoPriQueue();
}
bool DebuggerDriver::startup(QString cmdStr)
{
// clear command queues
delete m_activeCmd;
m_activeCmd = 0;
flushHiPriQueue();
flushLoPriQueue();
m_state = DSidle;
// debugger executable
if (cmdStr.isEmpty())
cmdStr = defaultInvocation();
QStringList cmd = cmdStr.split(' ', QString::SkipEmptyParts);
if (cmd.isEmpty())
return false;
QString pgm = cmd.takeFirst();
#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert(QLatin1String("LC_ALL"), QLatin1String("C"));
env.remove(QLatin1String("LANG"));
setProcessEnvironment(env);
#endif
setProcessChannelMode(MergedChannels);
start(pgm, cmd);
if (!waitForStarted(-1))
return false;
// open log file
if (!m_logFile.isOpen() && !m_logFileName.isEmpty()) {
m_logFile.setFileName(m_logFileName);
m_logFile.open(QIODevice::WriteOnly);
}
return true;
}
void DebuggerDriver::slotExited()
{
static const char txt[] = "\n====== debugger exited ======\n";
if (m_logFile.isOpen()) {
m_logFile.write(txt,sizeof(txt)-1);
}
// reset state
m_state = DSidle;
// empty buffer
m_output.clear();
}
CmdQueueItem* DebuggerDriver::executeCmdString(DbgCommand cmd,
QString cmdString, bool clearLow)
{
// place a new command into the high-priority queue
CmdQueueItem* cmdItem = new CmdQueueItem(cmd, cmdString);
m_hipriCmdQueue.push(cmdItem);
if (clearLow) {
if (m_state == DSrunningLow) {
// take the liberty to interrupt the running command
m_state = DSinterrupted;
::kill(pid(), SIGINT);
ASSERT(m_activeCmd != 0);
TRACE(QString().sprintf("interrupted the command %d",
(m_activeCmd ? m_activeCmd->m_cmd : -1)));
delete m_activeCmd;
m_activeCmd = 0;
}
flushLoPriQueue();
}
// if gdb is idle, send it the command
if (m_state == DSidle) {
ASSERT(m_activeCmd == 0);
writeCommand();
}
return cmdItem;
}
bool CmdQueueItem::IsEqualCmd::operator()(CmdQueueItem* cmd) const
{
return cmd->m_cmd == m_cmd && cmd->m_cmdString == m_str;
}
CmdQueueItem* DebuggerDriver::queueCmdString(DbgCommand cmd,
QString cmdString, QueueMode mode)
{
// place a new command into the low-priority queue
std::list<CmdQueueItem*>::iterator i;
CmdQueueItem* cmdItem = 0;
switch (mode) {
case QMoverrideMoreEqual:
case QMoverride:
// check whether gdb is currently processing this command
if (m_activeCmd != 0 &&
m_activeCmd->m_cmd == cmd && m_activeCmd->m_cmdString == cmdString)
{
return m_activeCmd;
}
// check whether there is already the same command in the queue
i = find_if(m_lopriCmdQueue.begin(), m_lopriCmdQueue.end(), CmdQueueItem::IsEqualCmd(cmd, cmdString));
if (i != m_lopriCmdQueue.end()) {
// found one
cmdItem = *i;
if (mode == QMoverrideMoreEqual) {
// All commands are equal, but some are more equal than others...
// put this command in front of all others
m_lopriCmdQueue.erase(i);
m_lopriCmdQueue.push_front(cmdItem);
}
break;
} // else none found, so add it
// drop through
case QMnormal:
cmdItem = new CmdQueueItem(cmd, cmdString);
m_lopriCmdQueue.push_back(cmdItem);
}
// if gdb is idle, send it the command
if (m_state == DSidle) {
ASSERT(m_activeCmd == 0);
writeCommand();
}
return cmdItem;
}
// dequeue a pending command, make it the active one and send it to gdb
void DebuggerDriver::writeCommand()
{
// ASSERT(m_activeCmd == 0);
assert(m_activeCmd == 0);
// first check the high-priority queue - only if it is empty
// use a low-priority command.
CmdQueueItem* cmd;
DebuggerState newState = DScommandSent;
if (!m_hipriCmdQueue.empty()) {
cmd = m_hipriCmdQueue.front();
m_hipriCmdQueue.pop();
} else if (!m_lopriCmdQueue.empty()) {
cmd = m_lopriCmdQueue.front();
m_lopriCmdQueue.pop_front();
newState = DScommandSentLow;
} else {
// nothing to do
m_state = DSidle; /* is necessary if command was interrupted earlier */
return;
}
m_activeCmd = cmd;
TRACE("in writeCommand: " + cmd->m_cmdString);
QByteArray str = cmd->m_cmdString.toLocal8Bit();
const char* data = str.data();
qint64 len = str.length();
while (len > 0) {
qint64 n = write(data, len);
if (n <= 0)
break; // ignore error
len -= n;
data += n;
}
// write also to log file
if (m_logFile.isOpen()) {
m_logFile.write(str);
m_logFile.flush();
}
m_state = newState;
}
void DebuggerDriver::flushLoPriQueue()
{
while (!m_lopriCmdQueue.empty()) {
delete m_lopriCmdQueue.back();
m_lopriCmdQueue.pop_back();
}
}
void DebuggerDriver::flushHiPriQueue()
{
while (!m_hipriCmdQueue.empty()) {
delete m_hipriCmdQueue.front();
m_hipriCmdQueue.pop();
}
}
void DebuggerDriver::flushCommands(bool hipriOnly)
{
flushHiPriQueue();
if (!hipriOnly) {
flushLoPriQueue();
}
}
void DebuggerDriver::slotCommandRead()
{
TRACE(__PRETTY_FUNCTION__);
// there must be an active command which is not yet commited
ASSERT(m_state == DScommandSent || m_state == DScommandSentLow);
ASSERT(m_activeCmd != 0);
ASSERT(!m_activeCmd->m_committed);
// commit the command
m_activeCmd->m_committed = true;
// now the debugger is officially working on the command
m_state = m_state == DScommandSent ? DSrunning : DSrunningLow;
// set the flag that reflects whether the program is really running
switch (m_activeCmd->m_cmd) {
case DCrun: case DCcont: case DCnext: case DCstep: case DCfinish: case DCuntil:
emit inferiorRunning();
break;
default:
break;
}
// process delayed output
while (!m_delayedOutput.empty()) {
QByteArray delayed = m_delayedOutput.front();
m_delayedOutput.pop();
processOutput(delayed);
}
}
void DebuggerDriver::slotReceiveOutput()
{
QByteArray data = readAllStandardOutput();
/*
* The debugger should be running (processing a command) at this point.
* If it is not, it is still idle because we haven't received the
* bytesWritten signal yet, in which case there must be an active command
* which is not commited.
*/
if (m_state == DScommandSent || m_state == DScommandSentLow) {
ASSERT(m_activeCmd != 0);
ASSERT(!m_activeCmd->m_committed);
/*
* We received output before we got signal bytesWritten. Collect this
* output, it will be processed by commandRead when it gets the
* acknowledgment for the uncommitted command.
*/
m_delayedOutput.push(data);
return;
}
processOutput(data);
}
void DebuggerDriver::processOutput(const QByteArray& data)
{
// write to log file (do not log delayed output - it would appear twice)
if (m_logFile.isOpen()) {
m_logFile.write(data);
m_logFile.flush();
}
/*
* gdb sometimes produces stray output while it's idle. This happens if
* it receives a signal, most prominently a SIGCONT after a SIGTSTP:
* The user haltet kdbg with Ctrl-Z, then continues it with "fg", which
* also continues gdb, which repeats the prompt!
*/
if (m_activeCmd == 0 && m_state != DSinterrupted) {
// ignore the output
TRACE("ignoring stray output: " + QString(data));
return;
}
ASSERT(m_state == DSrunning || m_state == DSrunningLow || m_state == DSinterrupted);
ASSERT(m_activeCmd != 0 || m_state == DSinterrupted);
// collect output until next prompt string is found
// accumulate it
m_output += data;
// check for a prompt
int promptStart = findPrompt(m_output);
if (promptStart >= 0)
{
// found prompt!
// terminate output before the prompt
m_output.resize(promptStart);
/*
* We've got output for the active command. But if it was
* interrupted, ignore it.
*/
if (m_state != DSinterrupted) {
/*
* m_state shouldn't be DSidle while we are parsing the output
* so that all commands produced by parse() go into the queue
* instead of being written to gdb immediately.
*/
ASSERT(m_state != DSidle);
CmdQueueItem* cmd = m_activeCmd;
m_activeCmd = 0;
commandFinished(cmd);
delete cmd;
}
// empty buffer
m_output.clear();
// also clear delayed output if interrupted
if (m_state == DSinterrupted) {
m_delayedOutput = std::queue<QByteArray>();
}
/*
* We parsed some output successfully. Unless there's more delayed
* output, the debugger must be idle now, so send down the next
* command.
*/
if (m_delayedOutput.empty()) {
if (m_hipriCmdQueue.empty() && m_lopriCmdQueue.empty()) {
// no pending commands
m_state = DSidle;
emit enterIdleState();
} else {
writeCommand();
}
}
}
}
void DebuggerDriver::dequeueCmdByVar(VarTree* var)
{
if (var == 0)
return;
std::list<CmdQueueItem*>::iterator i = m_lopriCmdQueue.begin();
while (i != m_lopriCmdQueue.end()) {
if ((*i)->m_expr != 0 && var->isAncestorEq((*i)->m_expr)) {
// this is indeed a critical command; delete it
TRACE("removing critical lopri-cmd: " + (*i)->m_cmdString);
delete *i;
m_lopriCmdQueue.erase(i++);
} else
++i;
}
}
QString DebuggerDriver::editableValue(VarTree* value)
{
// by default, let the user edit what is visible
return value->value();
}
StackFrame::~StackFrame()
{
delete var;
}
DbgAddr::DbgAddr(const QString& aa) :
a(aa)
{
cleanAddr();
}
/*
* We strip off the leading 0x and any leading zeros.
*/
void DbgAddr::cleanAddr()
{
if (a.isEmpty())
return;
while (a[0] == '0' || a[0] == 'x') {
a.remove(0, 1);
}
}
void DbgAddr::operator=(const QString& aa)
{
a = aa;
fnoffs = QString();
cleanAddr();
}
/* Re-attach 0x in front of the address */
QString DbgAddr::asString() const
{
if (a.isEmpty())
return QString();
else
return "0x" + a;
}
bool operator==(const DbgAddr& a1, const DbgAddr& a2)
{
return QString::compare(a1.a, a2.a) == 0;
}
bool operator>(const DbgAddr& a1, const DbgAddr& a2)
{
if (a1.a.length() > a2.a.length())
return true;
if (a1.a.length() < a2.a.length())
return false;
return QString::compare(a1.a, a2.a) > 0;
}
Breakpoint::Breakpoint() :
id(0),
type(breakpoint),
temporary(false),
enabled(true),
ignoreCount(0),
hitCount(0),
lineNo(0)
{ }
#include "dbgdriver.moc"

621
kdbg-2.5.5/kdbg/dbgdriver.h Normal file
View file

@ -0,0 +1,621 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef DBGDRIVER_H
#define DBGDRIVER_H
#include <QFile>
#include <QByteArray>
#include <QProcess>
#include <queue>
#include <list>
class VarTree;
class ExprValue;
class ExprWnd;
class KDebugger;
class QStringList;
/**
* A type representing an address.
*/
struct DbgAddr
{
QString a;
QString fnoffs;
DbgAddr() { }
DbgAddr(const QString& aa);
DbgAddr(const DbgAddr& src) : a(src.a), fnoffs(src.fnoffs) { }
void operator=(const QString& aa);
void operator=(const DbgAddr& src) { a = src.a; fnoffs = src.fnoffs; }
QString asString() const;
bool isEmpty() const { return a.isEmpty(); }
protected:
void cleanAddr();
};
bool operator==(const DbgAddr& a1, const DbgAddr& a2);
bool operator>(const DbgAddr& a1, const DbgAddr& a2);
enum DbgCommand {
DCinitialize,
DCtty,
DCexecutable,
DCtargetremote,
DCcorefile,
DCattach,
DCinfolinemain,
DCinfolocals,
DCinforegisters,
DCexamine,
DCinfoline,
DCdisassemble,
DCsetargs,
DCsetenv,
DCunsetenv,
DCsetoption, /* debugger options */
DCcd,
DCbt,
DCrun,
DCcont,
DCstep,
DCstepi,
DCnext,
DCnexti,
DCfinish,
DCuntil, /* line number is zero-based! */
DCkill,
DCbreaktext,
DCbreakline, /* line number is zero-based! */
DCtbreakline, /* line number is zero-based! */
DCbreakaddr,
DCtbreakaddr,
DCwatchpoint,
DCdelete,
DCenable,
DCdisable,
DCprint,
DCprintDeref,
DCprintStruct,
DCprintQStringStruct,
DCframe,
DCfindType,
DCinfosharedlib,
DCthread,
DCinfothreads,
DCinfobreak,
DCcondition,
DCsetpc,
DCignore,
DCprintWChar,
DCsetvariable
};
enum RunDevNull {
RDNstdin = 0x1, /* redirect stdin to /dev/null */
RDNstdout = 0x2, /* redirect stdout to /dev/null */
RDNstderr = 0x4 /* redirect stderr to /dev/null */
};
/**
* How the memory dump is formated. The lowest 4 bits define the size of
* the entities. The higher bits define how these are formatted. Note that
* not all combinations make sense.
*/
enum MemoryDumpType {
// sizes
MDTbyte = 0x1,
MDThalfword = 0x2,
MDTword = 0x3,
MDTgiantword = 0x4,
MDTsizemask = 0xf,
// formats
MDThex = 0x10,
MDTsigned = 0x20,
MDTunsigned = 0x30,
MDToctal = 0x40,
MDTbinary = 0x50,
MDTaddress = 0x60,
MDTchar = 0x70,
MDTfloat = 0x80,
MDTstring = 0x90,
MDTinsn = 0xa0,
MDTformatmask = 0xf0
};
struct Breakpoint;
/**
* Debugger commands are placed in a queue. Only one command at a time is
* sent down to the debugger. All other commands in the queue are retained
* until the sent command has been processed by gdb. The debugger tells us
* that it's done with the command by sending the prompt. The output of the
* debugger is parsed at that time. Then, if more commands are in the
* queue, the next one is sent to the debugger.
*/
struct CmdQueueItem
{
DbgCommand m_cmd;
QString m_cmdString;
bool m_committed; /* just a debugging aid */
// remember which expression when printing an expression
VarTree* m_expr;
ExprWnd* m_exprWnd;
// remember file position
QString m_fileName;
int m_lineNo;
DbgAddr m_addr;
// the breakpoint info
Breakpoint* m_brkpt;
int m_existingBrkpt;
// whether command was emitted due to direct user request (only set when relevant)
bool m_byUser;
CmdQueueItem(DbgCommand cmd, const QString& str) :
m_cmd(cmd),
m_cmdString(str),
m_committed(false),
m_expr(0),
m_exprWnd(0),
m_lineNo(0),
m_brkpt(0),
m_existingBrkpt(0),
m_byUser(false)
{ }
struct IsEqualCmd
{
IsEqualCmd(DbgCommand cmd, const QString& str) : m_cmd(cmd), m_str(str) { }
bool operator()(CmdQueueItem*) const;
DbgCommand m_cmd;
const QString& m_str;
};
};
/**
* The information about a breakpoint that is parsed from the list of
* breakpoints.
*/
struct Breakpoint
{
int id; /* gdb's number */
enum Type {
breakpoint, watchpoint
} type;
bool temporary;
bool enabled;
QString location;
QString text; /* text if set using DCbreaktext */
DbgAddr address; /* exact address of breakpoint */
QString condition; /* condition as printed by gdb */
int ignoreCount; /* ignore next that may hits */
int hitCount; /* as reported by gdb */
// the following items repeat the location, but in a better usable way
QString fileName;
int lineNo; /* zero-based line number */
Breakpoint();
bool isOrphaned() const { return id < 0; }
};
/**
* Information about a stack frame.
*/
struct FrameInfo
{
QString fileName;
int lineNo; /* zero-based line number */
DbgAddr address; /* exact address of PC */
};
/**
* The information about a stack frame as parsed from the backtrace.
*/
struct StackFrame : FrameInfo
{
int frameNo;
ExprValue* var; /* more information if non-zero */
StackFrame() : var(0) { }
~StackFrame();
};
/**
* The information about a thread as parsed from the threads list.
*/
struct ThreadInfo : FrameInfo
{
int id; /* gdb's number */
QString threadName; /* the SYSTAG */
QString function; /* where thread is halted */
bool hasFocus; /* the thread whose stack we are watching */
};
/**
* Register information
*/
struct RegisterInfo
{
QString regName;
QString rawValue;
QString cookedValue; /* may be empty */
QString type; /* of vector register if not empty */
};
/**
* Disassembled code
*/
struct DisassembledCode
{
DbgAddr address;
QString code;
};
/**
* Memory contents
*/
struct MemoryDump
{
DbgAddr address;
QString dump;
};
/**
* This is an abstract base class for debugger process.
*
* This class represents the debugger program. It provides the low-level
* interface to the commandline debugger. As such it implements the
* commands and parses the output.
*/
class DebuggerDriver : public QProcess
{
Q_OBJECT
public:
DebuggerDriver();
virtual ~DebuggerDriver() = 0;
virtual QString driverName() const = 0;
/**
* Returns the default command string to invoke the debugger driver.
*/
virtual QString defaultInvocation() const = 0;
/**
* Returns a list of options that can be turned on and off.
*/
virtual QStringList boolOptionList() const = 0;
virtual bool startup(QString cmdStr);
void setLogFileName(const QString& fname) { m_logFileName = fname; }
bool isRunning() { return state() != NotRunning; }
protected:
QString m_runCmd;
enum DebuggerState {
DSidle, /* gdb waits for input */
DSinterrupted, /* a command was interrupted */
DSrunningLow, /* gdb is running a low-priority command */
DSrunning, /* gdb waits for program */
DScommandSent, /* command has been sent, we wait for wroteStdin signal */
DScommandSentLow /* low-prioritycommand has been sent */
};
DebuggerState m_state;
public:
bool isIdle() const { return m_state == DSidle; }
/**
* Tells whether a high prority command would be executed immediately.
*/
bool canExecuteImmediately() const { return m_hipriCmdQueue.empty(); }
protected:
QByteArray m_output; // normal gdb output
std::queue<QByteArray> m_delayedOutput; // output colleced before signal bytesWritten() arrived
public:
/**
* Enqueues a high-priority command. High-priority commands are
* executed before any low-priority commands. No user interaction is
* possible as long as there is a high-priority command in the queue.
*/
virtual CmdQueueItem* executeCmd(DbgCommand,
bool clearLow = false) = 0;
virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg,
bool clearLow = false) = 0;
virtual CmdQueueItem* executeCmd(DbgCommand, int intArg,
bool clearLow = false) = 0;
virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg, int intArg,
bool clearLow = false) = 0;
virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg1, QString strArg2,
bool clearLow = false) = 0;
virtual CmdQueueItem* executeCmd(DbgCommand, int intArg1, int intArg2,
bool clearLow = false) = 0;
enum QueueMode {
QMnormal, /* queues the command last */
QMoverride, /* removes an already queued command */
QMoverrideMoreEqual /* ditto, also puts the command first in the queue */
};
/**
* Enqueues a low-priority command. Low-priority commands are executed
* after any high-priority commands.
*/
virtual CmdQueueItem* queueCmd(DbgCommand,
QueueMode mode) = 0;
virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg,
QueueMode mode) = 0;
virtual CmdQueueItem* queueCmd(DbgCommand, int intArg,
QueueMode mode) = 0;
virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg, int intArg,
QueueMode mode) = 0;
virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg1, QString strArg2,
QueueMode mode) = 0;
/**
* Flushes the command queues.
* @param hipriOnly if true, only the high priority queue is flushed.
*/
virtual void flushCommands(bool hipriOnly = false);
/**
* Terminates the debugger process.
*/
virtual void terminate() = 0;
/**
* Terminates the debugger process, but also detaches any program that
* it has been attached to.
*/
virtual void detachAndTerminate() = 0;
/**
* Interrupts the debuggee.
*/
virtual void interruptInferior() = 0;
/**
* Specifies the command that prints the QString data.
*/
virtual void setPrintQStringDataCmd(const char* cmd) = 0;
/**
* Parses the output as an array of QChars.
*/
virtual ExprValue* parseQCharArray(const char* output, bool wantErrorValue, bool qt3like) = 0;
/**
* Parses a back-trace (the output of the DCbt command).
*/
virtual void parseBackTrace(const char* output, std::list<StackFrame>& stack) = 0;
/**
* Parses the output of the DCframe command;
* @param frameNo Returns the frame number.
* @param file Returns the source file name.
* @param lineNo The zero-based line number.
* @param address Returns the exact address.
* @return false if the frame could not be parsed successfully. The
* output values are undefined in this case.
*/
virtual bool parseFrameChange(const char* output, int& frameNo,
QString& file, int& lineNo, DbgAddr& address) = 0;
/**
* Parses a list of breakpoints.
* @param output The output of the debugger.
* @param brks The list of new #Breakpoint objects. The list
* must initially be empty.
* @return False if there was an error before the first breakpoint
* was found. Even if true is returned, #brks may be empty.
*/
virtual bool parseBreakList(const char* output, std::list<Breakpoint>& brks) = 0;
/**
* Parses a list of threads.
* @param output The output of the debugger.
* @return The new thread list. There is no indication if there was
* a parse error.
*/
virtual std::list<ThreadInfo> parseThreadList(const char* output) = 0;
/**
* Parses the output when the program stops to see whether this it
* stopped due to a breakpoint.
* @param output The output of the debugger.
* @param id Returns the breakpoint id.
* @param file Returns the file name in which the breakpoint is.
* @param lineNo Returns the zero-based line number of the breakpoint.
* @param address Returns the address of the breakpoint.
* @return False if there was no breakpoint.
*/
virtual bool parseBreakpoint(const char* output, int& id,
QString& file, int& lineNo, QString& address) = 0;
/**
* Parses the output of the DCinfolocals command.
* @param output The output of the debugger.
* @param newVars Receives the parsed variable values. The values are
* simply append()ed to the supplied list.
*/
virtual void parseLocals(const char* output, std::list<ExprValue*>& newVars) = 0;
/**
* Parses the output of a DCprint or DCprintStruct command.
* @param output The output of the debugger.
* @param wantErrorValue Specifies whether the error message should be
* provided as the value of a NKplain variable. If this is false,
* 0 is returned if the printed value is an error message.
* @return the parsed value. It is 0 if there was a parse error
* or if the output is an error message and #wantErrorValue
* is \c false. The returned object's text() is undefined.
*/
virtual ExprValue* parsePrintExpr(const char* output, bool wantErrorValue) = 0;
/**
* Parses the output of the DCcd command.
* @return false if the message is an error message.
*/
virtual bool parseChangeWD(const char* output, QString& message) = 0;
/**
* Parses the output of the DCexecutable command.
* @return false if an error occured.
*/
virtual bool parseChangeExecutable(const char* output, QString& message) = 0;
/**
* Parses the output of the DCcorefile command.
* @return false if the core file was not loaded successfully.
*/
virtual bool parseCoreFile(const char* output) = 0;
enum StopFlags {
SFrefreshSource = 1, /* refresh of source code is needed */
SFrefreshBreak = 2, /* refresh breakpoints */
SFrefreshThreads = 4, /* refresh thread list */
SFprogramActive = 128 /* program remains active */
};
/**
* Parses the output of commands that execute (a piece of) the program.
* @return The inclusive OR of zero or more of the StopFlags.
*/
virtual uint parseProgramStopped(const char* output, QString& message) = 0;
/**
* Parses the output of the DCsharedlibs command.
*/
virtual QStringList parseSharedLibs(const char* output) = 0;
/**
* Parses the output of the DCfindType command.
* @return true if a type was found.
*/
virtual bool parseFindType(const char* output, QString& type) = 0;
/**
* Parses the output of the DCinforegisters command.
*/
virtual std::list<RegisterInfo> parseRegisters(const char* output) = 0;
/**
* Parses the output of the DCinfoline command. Returns false if the
* two addresses could not be found.
*/
virtual bool parseInfoLine(const char* output,
QString& addrFrom, QString& addrTo) = 0;
/**
* Parses the ouput of the DCdisassemble command.
*/
virtual std::list<DisassembledCode> parseDisassemble(const char* output) = 0;
/**
* Parses a memory dump. Returns an empty string if no error was found;
* otherwise it contains an error message.
*/
virtual QString parseMemoryDump(const char* output, std::list<MemoryDump>& memdump) = 0;
/**
* Parses the output of the DCsetvariable command. Returns an empty
* string if no error was found; otherwise it contains an error
* message.
*/
virtual QString parseSetVariable(const char* output) = 0;
/**
* Returns a value that the user can edit.
*/
virtual QString editableValue(VarTree* value);
protected:
/** Removes all commands from the low-priority queue. */
void flushLoPriQueue();
/** Removes all commands from the high-priority queue. */
void flushHiPriQueue();
std::queue<CmdQueueItem*> m_hipriCmdQueue;
std::list<CmdQueueItem*> m_lopriCmdQueue;
/**
* The active command is kept separately from other pending commands.
*/
CmdQueueItem* m_activeCmd;
/**
* Helper function that queues the given command string in the
* low-priority queue.
*/
CmdQueueItem* queueCmdString(DbgCommand cmd, QString cmdString,
QueueMode mode);
/**
* Helper function that queues the given command string in the
* high-priority queue.
*/
CmdQueueItem* executeCmdString(DbgCommand cmd, QString cmdString,
bool clearLow);
void writeCommand();
virtual void commandFinished(CmdQueueItem* cmd) = 0;
protected:
void processOutput(const QByteArray& data);
/**
* Returns the start of the prompt in \a output or -1.
* \a len specifies the size of \a output, but in addition, the contents
* of \a output are NUL-terminated, i.e., \c output[len] is zero.
*/
virtual int findPrompt(const QByteArray& output) const = 0;
// log file
QString m_logFileName;
QFile m_logFile;
public slots:
void dequeueCmdByVar(VarTree* var);
protected slots:
virtual void slotReceiveOutput();
virtual void slotCommandRead();
virtual void slotExited();
signals:
/**
* This signal is emitted when the output of a command has been fully
* collected and is ready to be interpreted.
*/
void commandReceived(CmdQueueItem* cmd, const char* output);
/**
* This signal is emitted when the debugger recognizes that a specific
* location in a file ought to be displayed.
*
* Gdb's --fullname option supports this for the step, next, frame, and
* run commands (and possibly others).
*
* @param file specifies the file; this is not necessarily a full path
* name, and if it is relative, you won't know relative to what, you
* can only guess.
* @param lineNo specifies the line number (0-based!) (this may be
* negative, in which case the file should be activated, but the line
* should NOT be changed).
* @param address specifies the exact address of the PC or is empty.
*/
void activateFileLine(const QString& file, int lineNo, const DbgAddr& address);
/**
* This signal is emitted when a command that starts the inferior has
* been submitted to the debugger.
*/
void inferiorRunning();
/**
* This signal is emitted when all output from the debugger has been
* consumed and no more commands are in the queues.
*/
void enterIdleState();
};
#endif // DBGDRIVER_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,205 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef DBGMAINWND_H
#define DBGMAINWND_H
#include <QPointer>
#include <QTimer>
#include <kxmlguiwindow.h>
#include "regwnd.h"
class QDockWidget;
class QProcess;
class KAnimatedButton;
class KRecentFilesAction;
class KUrl;
class WinStack;
class QListWidget;
class ExprWnd;
class BreakpointTable;
class ThreadList;
class MemoryWindow;
class TTYWindow;
class WatchWindow;
class KDebugger;
class DebuggerDriver;
struct DbgAddr;
class DebuggerMainWnd : public KXmlGuiWindow
{
Q_OBJECT
public:
DebuggerMainWnd();
~DebuggerMainWnd();
bool debugProgram(const QString& exe, const QString& lang);
/**
* Specifies the file where to write the transcript.
*/
void setTranscript(const QString& name);
/**
* Specifies the process to attach to after the program is loaded.
*/
void setAttachPid(const QString& pid);
// the following are needed to handle program arguments
void setCoreFile(const QString& corefile);
void setRemoteDevice(const QString &remoteDevice);
void overrideProgramArguments(const QString& args);
protected:
// session properties
virtual void saveProperties(KConfigGroup& cg);
virtual void readProperties(const KConfigGroup& cg);
// settings
void saveSettings(KSharedConfigPtr);
void restoreSettings(KSharedConfigPtr);
void initAnimation();
void initStatusBar();
void initKAction();
// view windows
WinStack* m_filesWindow;
QListWidget* m_btWindow;
ExprWnd* m_localVariables;
WatchWindow* m_watches;
RegisterView* m_registers;
BreakpointTable* m_bpTable;
TTYWindow* m_ttyWindow;
ThreadList* m_threads;
MemoryWindow* m_memoryWindow;
QTimer m_backTimer;
// recent execs in File menu
QAction* m_closeAction;
QAction* m_reloadAction;
QAction* m_fileExecAction;
KRecentFilesAction* m_recentExecAction;
QAction* m_coreDumpAction;
QAction* m_settingsAction;
QAction* m_findAction;
QAction* m_btWindowAction;
QAction* m_localVariablesAction;
QAction* m_watchesAction;
QAction* m_registersAction;
QAction* m_bpTableAction;
QAction* m_ttyWindowAction;
QAction* m_threadsAction;
QAction* m_memoryWindowAction;
QAction* m_runAction;
QAction* m_stepIntoAction;
QAction* m_stepOverAction;
QAction* m_stepOutAction;
QAction* m_toCursorAction;
QAction* m_stepIntoIAction;
QAction* m_stepOverIAction;
QAction* m_execMovePCAction;
QAction* m_breakAction;
QAction* m_killAction;
QAction* m_restartAction;
QAction* m_attachAction;
QAction* m_argumentsAction;
QAction* m_bpSetAction;
QAction* m_bpSetTempAction;
QAction* m_bpEnableAction;
QAction* m_editValueAction;
QString m_lastDirectory; /* the dir of the most recently opened file */
protected:
virtual bool queryClose();
QAction* createAction(const QString& text, const char* icon,
int shortcut, const QObject* receiver,
const char* slot, const char* name);
QAction* createAction(const QString& text,
int shortcut, const QObject* receiver,
const char* slot, const char* name);
// the debugger proper
QString m_debuggerCmdStr;
KDebugger* m_debugger;
QString m_transcriptFile; /* where gdb dialog is logged */
/**
* Starts to debug the specified program using the specified language
* driver.
*/
bool startDriver(const QString& executable, QString lang);
DebuggerDriver* driverFromLang(QString lang);
/**
* Derives a driver name from the contents of the named file.
*/
QString driverNameFromFile(const QString& exe);
// output window
QString m_outputTermCmdStr;
QString m_outputTermKeepScript;
QProcess* m_outputTermProc;
int m_ttyLevel;
QString createOutputWindow();
bool m_popForeground; /* whether main wnd raises when prog stops */
int m_backTimeout; /* when wnd goes back */
int m_tabWidth; /* tab width in characters (can be 0) */
QString m_sourceFilter;
QString m_headerFilter;
void setTerminalCmd(const QString& cmd);
void setDebuggerCmdStr(const QString& cmd);
QDockWidget* createDockWidget(const char* name, const QString& title);
QDockWidget* dockParent(QWidget* w);
bool isDockVisible(QWidget* w);
void makeDefaultLayout();
QString makeSourceFilter();
// to avoid flicker when the status bar is updated,
// we store the last string that we put there
QPointer<KAnimatedButton> m_animation;
QString m_lastActiveStatusText;
bool m_animRunning;
// statusbar texts
QString m_statusActive;
signals:
void setTabWidth(int tabWidth);
public slots:
virtual void updateUI();
virtual void updateLineItems();
void slotAddWatch();
void slotAddWatch(const QString& text);
void slotNewFileLoaded();
void slotNewStatusMsg();
void slotDebuggerStarting();
void slotToggleBreak(const QString&, int, const DbgAddr&, bool);
void slotEnaDisBreak(const QString&, int, const DbgAddr&);
void slotProgramStopped();
void slotBackTimer();
void slotRecentExec(const KUrl& url);
void slotLocalsPopup(const QPoint& pt);
void slotLocalsToWatch();
void slotEditValue();
void slotFileOpen();
void slotFileExe();
void slotFileCore();
void slotFileGlobalSettings();
void slotFileProgSettings();
void slotViewStatusbar();
void slotExecUntil();
void slotExecAttach();
void slotExecArgs();
void intoBackground();
void slotConfigureKeys();
};
#endif // DBGMAINWND_H

2197
kdbg-2.5.5/kdbg/debugger.cpp Normal file

File diff suppressed because it is too large Load diff

565
kdbg-2.5.5/kdbg/debugger.h Normal file
View file

@ -0,0 +1,565 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef DEBUGGER_H
#define DEBUGGER_H
#include <QSet>
#include <QStringList>
#include <list>
#include <map>
#include "envvar.h"
#include "exprwnd.h" /* some compilers require this */
class ExprWnd;
class VarTree;
struct ExprValue;
class ProgramTypeTable;
class KTreeViewItem;
class KConfig;
class KConfigBase;
class KConfigGroup;
class QListWidget;
class RegisterInfo;
class ThreadInfo;
class DebuggerDriver;
class CmdQueueItem;
class Breakpoint;
struct DisassembledCode;
struct MemoryDump;
struct DbgAddr;
class KDebugger : public QObject
{
Q_OBJECT
public:
KDebugger(QWidget* parent, /* will be used as the parent for dialogs */
ExprWnd* localVars,
ExprWnd* watchVars,
QListWidget* backtrace);
~KDebugger();
/**
* This function starts to debug the specified executable using the
* specified driver. If a program is currently being debugged, it is
* terminated first. Ownership of driver is taken if and only if
* true is returned.
*
* @return false if an error occurs.
*/
bool debugProgram(const QString& executable,
DebuggerDriver* driver);
/**
* Uses the specified core to debug the active program.
* @param batch tells whether the core file was given on the
* command line.
*/
void useCoreFile(QString corefile, bool batch);
/**
* Overrides the program argument in the per-program config
* with a new value.
*/
void overrideProgramArguments(const QString& args);
/**
* Uses the specified pid to attach to the active program.
*/
void setAttachPid(const QString& pid);
/**
* Attaches to the specified process and debugs it.
*/
void attachProgram(const QString& pid);
/**
* Returns the file name of the per-program config file for the
* specified program.
*/
static QString getConfigForExe(const QString& exe);
/**
* The driver name entry in the per-program config file.
*/
static const char DriverNameEntry[];
public slots:
/**
* Runs the program or continues it if it is stopped at a breakpoint.
*/
void programRun();
/**
* Restarts the debuggee.
*/
void programRunAgain();
/**
* Performs a single-step, possibly stepping into a function call.
* If byInsn is true, a step by instruction is performed.
*/
void programStep();
/**
* Performs a single-step, stepping over a function call.
* If byInsn is true, a step by instruction is performed.
*/
void programNext();
/**
* Performs a single-step by instruction, possibly stepping into a
* function call.
*/
void programStepi();
/**
* Performs a single-step by instruction, stepping over a function
* call.
*/
void programNexti();
/**
* Runs the program until it returns from the current function.
*/
void programFinish();
/**
* Kills the program (removes it from memory).
*/
void programKill();
/**
* Interrupts the program if it is currently running.
*/
void programBreak();
/**
* Moves the program counter to the specified line.
* If an address is given, it is moved to the address.
*/
void setProgramCounter(const QString&, int, const DbgAddr&);
public:
/**
* Queries the user for program arguments.
*/
void programArgs(QWidget* parent);
/**
* Queries the user for program settings: Debugger command, terminal
* emulator.
*/
void programSettings(QWidget* parent);
/**
* Setup remote debugging device
*/
void setRemoteDevice(const QString& remoteDevice) { m_remoteDevice = remoteDevice; }
/**
* Run the debuggee until the specified line in the specified file is
* reached.
*
* @return false if the command was not executed, e.g. because the
* debuggee is running at the moment.
*/
bool runUntil(const QString& fileName, int lineNo);
/**
* Ask debugger for information about the specified line in the specified file.
*
* If \a addr is given, then it is used as a hint to position
* to position the cursor in the source window at that address
* if it belongs to the specified line.
* @param fileName The source file in which to set the breakpoint.
* @param lineNo The zero-based line number.
* @param addr An address that belongs to the name; can be empty.
* @return false if the command was not executed, e.g. because the
* debuggee is running at the moment.
*/
bool infoLine(QString fileName, int lineNo, const DbgAddr& addr);
/**
* Set a breakpoint.
*
* @param fileName The source file in which to set the breakpoint.
* @param lineNo The zero-based line number.
* @param address The exact address of the breakpoint.
* @param temporary Specifies whether this is a temporary breakpoint
* @return false if the command was not executed, e.g. because the
* debuggee is running at the moment.
*/
bool setBreakpoint(QString fileName, int lineNo,
const DbgAddr& address, bool temporary);
/**
* Set a breakpoint.
*
* @param bp Describes the breakpoint.
* @param queueOnly If false, the breakpoint is set using a high-priority command.
*/
void setBreakpoint(Breakpoint* bp, bool queueOnly);
/**
* Enable or disable a breakpoint at the specified location.
*
* @param fileName The source file in which the breakpoint is.
* @param lineNo The zero-based line number.
* @param address The exact address of the breakpoint.
* @return false if the command was not executed, e.g. because the
* debuggee is running at the moment.
*/
bool enableDisableBreakpoint(QString fileName, int lineNo,
const DbgAddr& address);
/**
* Enables or disables the specified breakpoint.
*
* @return false if the command was not executed, e.g. because the
* debuggee is running at the moment.
*/
bool enableDisableBreakpoint(int id)
{ return enableDisableBreakpoint(breakpointById(id)); }
/**
* Removes the specified breakpoint. Note that if bp is an orphaned
* breakpoint, then bp is an invalid pointer if (and only if) this
* function returns true.
*
* @return false if the command was not executed, e.g. because the
* debuggee is running at the moment.
*/
bool deleteBreakpoint(int id)
{ return deleteBreakpoint(breakpointById(id)); }
/**
* Changes the specified breakpoint's condition and ignore count.
*
* @return false if the command was not executed, e.g. because the
* debuggee is running at the moment.
*/
bool conditionalBreakpoint(int id,
const QString& condition,
int ignoreCount)
{ return conditionalBreakpoint(breakpointById(id), condition, ignoreCount); }
/**
* Tells whether one of the single stepping commands can be invoked
* (step, next, finish, until, also run).
*/
bool canSingleStep();
/**
* Tells whether a breakpoints can be set, deleted, enabled, or disabled.
*/
bool canChangeBreakpoints();
/**
* Tells whether a the program is loaded, but not active.
*/
bool canStart();
/**
* Add a watch expression.
*/
void addWatch(const QString& expr);
/**
* Retrieves the current status message.
*/
const QString& statusMessage() const { return m_statusMessage; }
/**
* Is the debugger ready to receive another high-priority command?
*/
bool isReady() const;
/**
* Is the debuggee running (not just active)?
*/
bool isProgramRunning() { return m_haveExecutable && m_programRunning; }
/**
* Do we have an executable set?
*/
bool haveExecutable() { return m_haveExecutable; }
/**
* Is the debuggee active, i.e. was it started by the debugger?
*/
bool isProgramActive() { return m_programActive; }
/**
* Is the debugger driver idle?
*/
bool isIdle() const;
/* The list of breakpoints. */
typedef std::list<Breakpoint>::const_iterator BrkptROIterator;
BrkptROIterator breakpointsBegin() const { return m_brkpts.begin(); }
BrkptROIterator breakpointsEnd() const { return m_brkpts.end(); }
const QString& executable() const { return m_executable; }
/**
* Terminal emulation level.
*/
enum TTYLevel {
ttyNone = 0, /* ignore output, input triggers EOF */
ttySimpleOutputOnly = 1, /* minmal output emulation, input triggers EOF */
ttyFull = 7 /* program needs full emulation */
};
/**
* Returns the level of terminal emulation requested by the inferior.
*/
TTYLevel ttyLevel() const { return m_ttyLevel; }
/** Sets the terminal that is to be used by the debugger. */
void setTerminal(const QString& term) { m_inferiorTerminal = term; }
/** Returns the debugger driver. */
DebuggerDriver* driver() { return m_d; }
/** Returns the pid that the debugger is currently attached to. */
const QString& attachedPid() const { return m_attachedPid; }
/**
* The memory at that the expression evaluates to is watched. Can be
* empty. Triggers a redisplay even if the expression did not change.
*/
void setMemoryExpression(const QString& memexpr);
/**
* Sets how the watched memory location is displayed.
* Call setMemoryExpression() to force a redisplay.
*/
void setMemoryFormat(unsigned format) { m_memoryFormat = format; }
// settings
void saveSettings(KConfig*);
void restoreSettings(KConfig*);
protected:
QString m_inferiorTerminal;
QString m_debuggerCmd; /* per-program setting */
TTYLevel m_ttyLevel; /* level of terminal emulation */
bool startDriver();
void stopDriver();
void writeCommand();
std::list<QString> m_watchEvalExpr; /* exprs to evaluate for watch window */
std::list<Breakpoint> m_brkpts;
QString m_memoryExpression; /* memory location to watch */
unsigned m_memoryFormat; /* how that output should look */
protected slots:
void parse(CmdQueueItem* cmd, const char* output);
protected:
void handleRunCommands(const char* output);
void updateAllExprs();
void updateProgEnvironment(const QString& args, const QString& wd,
const std::map<QString,EnvVar>& newVars,
const QSet<QString>& newOptions);
void parseLocals(const char* output, std::list<ExprValue*>& newVars);
void handleLocals(const char* output);
bool handlePrint(CmdQueueItem* cmd, const char* output);
bool handlePrintDeref(CmdQueueItem* cmd, const char* output);
void handleBacktrace(const char* output);
void handleFrameChange(const char* output);
void handleFindType(CmdQueueItem* cmd, const char* output);
void handlePrintStruct(CmdQueueItem* cmd, const char* output);
void handleSharedLibs(const char* output);
void handleRegisters(const char* output);
void handleMemoryDump(const char* output);
void handleInfoLine(CmdQueueItem* cmd, const char* output);
void handleDisassemble(CmdQueueItem* cmd, const char* output);
void handleThreadList(const char* output);
void handleSetPC(const char* output);
void handleSetVariable(CmdQueueItem* cmd, const char* output);
void evalExpressions();
void evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate);
void evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate);
void dereferencePointer(ExprWnd* wnd, VarTree* var, bool immediate);
void determineType(ExprWnd* wnd, VarTree* var);
void queueMemoryDump(bool immediate);
CmdQueueItem* loadCoreFile();
void openProgramConfig(const QString& name);
typedef std::list<Breakpoint>::iterator BrkptIterator;
BrkptIterator breakpointByFilePos(QString file, int lineNo,
const DbgAddr& address);
BrkptIterator breakpointById(int id);
CmdQueueItem* executeBreakpoint(const Breakpoint* bp, bool queueOnly);
void newBreakpoint(CmdQueueItem* cmd, const char* output);
void updateBreakList(const char* output);
bool stopMayChangeBreakList() const;
void saveBreakpoints(KConfig* config);
void restoreBreakpoints(KConfig* config);
bool enableDisableBreakpoint(BrkptIterator bp);
bool deleteBreakpoint(BrkptIterator bp);
bool conditionalBreakpoint(BrkptIterator bp,
const QString& condition,
int ignoreCount);
bool m_haveExecutable; /* has an executable been specified */
bool m_programActive; /* is the program active (possibly halting in a brkpt)? */
bool m_programRunning; /* is the program executing (not stopped)? */
bool m_sharedLibsListed; /* do we know the shared libraries loaded by the prog? */
QString m_executable;
QString m_corefile;
QString m_attachedPid; /* user input of attaching to pid */
QString m_programArgs;
QString m_remoteDevice;
QString m_programWD; /* working directory of gdb */
std::map<QString,QString> m_envVars; /* environment variables set by user */
QSet<QString> m_boolOptions; /* boolean options */
QStringList m_sharedLibs; /* shared libraries used by program */
ProgramTypeTable* m_typeTable; /* known types used by the program */
KConfig* m_programConfig; /* program-specific settings (brkpts etc) */
void saveProgramSettings();
void restoreProgramSettings();
QString readDebuggerCmd(const KConfigGroup& g);
// debugger process
DebuggerDriver* m_d;
bool m_explicitKill; /* whether we are killing gdb ourselves */
QString m_statusMessage;
protected slots:
void gdbExited();
void slotInferiorRunning();
void backgroundUpdate();
void gotoFrame(int);
void slotExpanding(QTreeWidgetItem*);
void slotDeleteWatch();
void slotValuePopup(const QString&);
void slotDisassemble(const QString&, int);
void slotValueEdited(VarTree*, const QString&);
public slots:
void setThread(int);
void shutdown();
signals:
/**
* This signal is emitted before the debugger is started. The slot is
* supposed to set up m_inferiorTerminal.
*/
void debuggerStarting();
/**
* This signal is emitted whenever a part of the debugger needs to
* highlight the specfied source code line (e.g. when the program
* stops).
*
* @param file specifies the file; this is not necessarily a full path
* name, and if it is relative, you won't know relative to what, you
* can only guess.
* @param lineNo specifies the line number (0-based!) (this may be
* negative, in which case the file should be activated, but the line
* should NOT be changed).
* @param address specifies the exact address of the PC or is empty.
*/
void activateFileLine(const QString& file, int lineNo, const DbgAddr& address);
/**
* This signal indicates that the program counter has changed.
*
* @param filename specifies the filename where the program stopped
* @param lineNo specifies the line number (zero-based); it can be -1
* if it is unknown
* @param address specifies the address that the instruction pointer
* points to.
* @param frameNo specifies the frame number: 0 is the innermost frame,
* positive numbers are frames somewhere up the stack (indicates points
* where a function was called); the latter cases should be indicated
* differently in the source window.
*/
void updatePC(const QString& filename, int lineNo,
const DbgAddr& address, int frameNo);
/**
* This signal is emitted when gdb detects that the executable has been
* updated, e.g. recompiled. (You usually need not handle this signal
* if you are the editor which changed the executable.)
*/
void executableUpdated();
/**
* Indicates that a new status message is available.
*/
void updateStatusMessage();
/**
* Indicates that the internal state of the debugger has changed, and
* that this will very likely have an impact on the UI.
*/
void updateUI();
/**
* Indicates that the list of breakpoints has possibly changed.
*/
void breakpointsChanged();
/**
* Indicates that the register values have possibly changed.
*/
void registersChanged(const std::list<RegisterInfo>&);
/**
* Indicates that the list of threads has possibly changed.
*/
void threadsChanged(const std::list<ThreadInfo>&);
/**
* Indicates that the value for a value popup is ready.
*/
void valuePopup(const QString&);
/**
* Provides the disassembled code of the location given by file and
* line number (zero-based).
*/
void disassembled(const QString& file, int line, const std::list<DisassembledCode>& code);
/**
* Indicates that the program has stopped for any reason: by a
* breakpoint, by a signal that the debugger driver caught, by a single
* step instruction.
*/
void programStopped();
/**
* Indicates that a new memory dump output is ready.
* @param msg is an error message or empty
* @param memdump is the memory dump
*/
void memoryDumpChanged(const QString&, const std::list<MemoryDump>&);
/**
* Gives other objects a chance to save program specific settings.
*/
void saveProgramSpecific(KConfigBase* config);
/**
* Gives other objects a chance to restore program specific settings.
*/
void restoreProgramSpecific(KConfigBase* config);
protected:
ExprWnd& m_localVariables;
ExprWnd& m_watchVariables;
QListWidget& m_btWindow;
// implementation helpers
protected:
QWidget* parentWidget() { return static_cast<QWidget*>(parent()); }
};
#endif // DEBUGGER_H

View file

@ -0,0 +1,3 @@
add_subdirectory(de)
add_subdirectory(en)
add_subdirectory(ru)

View file

@ -0,0 +1,17 @@
install(FILES
argspwdenv.html
breakptlist.html
globaloptions.html
howdoi.html
localvars.html
memory.html
pgmoutput.html
pgmsettings.html
registers.html
sourcecode.html
stack.html
threads.html
tips.html
watches.html
index.html
DESTINATION ${HTML_INSTALL_DIR}/de/kdbg)

View file

@ -0,0 +1,50 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Argumente, Arbeitsverzeichnis, Umgebungsvariablen</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h3>
<a NAME="Environment"></a>Programmargumente, Arbeitsverzeichnis, Umgebungsvariablen
setzen</h3>
Mit <i>Ausf&uuml;hren|Argumente</i> &ouml;ffnen Sie einen Dialog, in dem
Sie Programmargumente, das Arbeitsverzeichnis sowie Umgebungsvariablen
setzen k&ouml;nnen.
<h3>
Programmargumente</h3>
In der obersten Eingabezeile k&ouml;nnen Sie die Programmargumente eingeben,
die an das Programm &uuml;bergeben werden sollen. Diese werden beim n&auml;chsten
Programmstart verwendet.
<h3>
Arbeitsverzeichnis</h3>
Im Eingabefeld darunter k&ouml;nnen Sie das Arbeitsverzeichnis angeben.
Dieses wird sofort an gdb &uuml;bergeben, sobald Sie <i>OK</i> dr&uuml;cken.
Das Programm verwendet das neue Arbeitsverzeichnis allerdings erst beim
n&auml;chsten Start.
<p>Das Arbeitsverzeichnis gilt auch f&uuml;r gdb selbst! Das angegebene
Arbeitsverzeichnis wird sofort an gdb weitergegeben, d.h. gdb wird die
neue Einstellung verwenden, sobald Sie <i>OK</i> dr&uuml;cken. Das kann
einen Einfluss darauf haben, ob gdb Quellcodedateien findet.
<h3>
Umgebungsvariablen</h3>
Im Bereich f&uuml;r Umgebungsvariablen k&ouml;nnen Sie einen Ausdruck in
der Form
<tt>VARIABLE=Wert</tt> eingeben und dann <i>&Auml;ndern</i> klicken,
um der Umgebungsvariablen <tt>VARIABLE</tt> einen <tt>Wert</tt> zuzuweisen.
Um eine Variable zu entfernen, w&auml;hlen Sie diese zuerst aus der Liste
darunter aus und klicken dan <i>L&ouml;schen</i>. Um einen Wert zu &auml;ndern,
geben Sie einfach den neuen Wert ein und klicken <i>&Auml;ndern</i>. Wenn
Sie den Namen der Variable &auml;ndern und <i>&Auml;ndern</i> clicken,
erzeugen Sie eine neue Variable! Die neuen Umgebungsvariablen werden erst
beim n&auml;chsten Programmstart verwendet.
<p>Wenn Sie glibc2 unter Linux verwenden, ist es sehr wichtig, dass Sie
der Umgebungsvariablen <tt>LD_BIND_NOW</tt> den Wert <tt>1</tt> zuweisen.
Wenn diese Variable nicht gesetzt ist, k&ouml;nnen solche Funktionen nicht
betreten werden, die von der Bibliothek <tt>libc</tt> und anderen Shared
Libraries importiert werden.
</body>
</html>

View file

@ -0,0 +1,82 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Haltepunkte</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Die Liste der Haltepunkte</h1>
Die Liste der Haltepunkte zeigt alle gesetzten Haltepunkte und Watchpoints
und erm&ouml;glicht, diese zu manipulieren. Die Liste der Haltepunkte k&ouml;nnen
Sie mit dem Men&uuml;punkt <i>Ansicht|Haltepunkte</i> anzeigen.
<h2>
Die &Uuml;bersicht</h2>
F&uuml;r jeden Haltepunkt wird folgendes angezeigt:
<ul>
<li>
der Ort,</li>
<li>
die Anzahl der Stopps,</li>
<li>
die Anzahl der n&auml;chsten zu ignorierenden Stopps (falls gesetzt)</li>
<li>
die Haltebedingung (falls gesetzt).</li>
</ul>
Das Piktogramm links zeigt an, ob der Haltepunkt aktiviert (tiefroter Punkt)
oder deaktiviert (hellroter Punkt) ist, ob es sich um einen tempor&auml;ren
Haltepunkt handelt (eine winzige Uhr ist sichtbar) und ob der Haltepunkt
bedingt ist (ein Fragezeichen ist sichtbar).
<p>Watchpoints werden durch ein Brillensymbol gekennzeichnet.
<h2>
Haltepunkte manipulieren</h2>
<a NAME="StopProg"></a>Beachten Sie bitte, dass Haltepunkte und Watchpoints
nicht manipuliert werden k&ouml;nnen solange das zu debuggende Programm
l&auml;uft. Wenn das Programm bereits gestartet wurde, muss es zuerst angehalten
werden - entweder indem es auf einen bereits gesetzten Haltepunkt trifft
oder "gewaltsam" indem Sie <i>Ausf&uuml;hrung|Unterbrechen</i> w&auml;hlen.
Dadurch wird das Programm nicht beendet, sondern nur unterbrochen. Sie
k&ouml;nnen die Haltepunkte jetzt ver&auml;ndern. W&auml;hlen Sie danach
<i>Ausf&uuml;hrung|Ausf&uuml;hren</i>,
um das Programm fortzusetzen.
<p>Am einfachsten kann ein Haltepunkt im <a href="sourcecode.html">Quellcode-Fenster</a>
gesetzt werden. Wenn Sie den genauen Dateinamen und die Zeilennummer einer
Funktion nicht kennen, k&ouml;nnen Sie den Funktionsnamen im Feld &uuml;ber
der Liste eingeben und <i>Haltepunkt</i> w&auml;hlen.
<p>Sie k&ouml;nnen eine Haltepunkt in der Liste ausw&auml;hlen seine Zustand
mittels <i>Deaktivieren</i> oder <i>Aktivieren</i> &auml;ndern. Oder Sie
klicken auf den Haltepunkt mit der mittleren Maustaste - genau so, wie
Sie im Quellcode-Fenster Haltepunkte aktivieren und deaktivieren.
<p>Sie k&ouml;nnen eine Bedingung setzen (sodass das Programm nur stehen
bleibt, wenn die Bedingung erf&uuml;llt ist) oder die Anzahl der zu ignorierenden
Stopps setzen (sodass das Programm die n&auml;chsten n Male nicht stehen
bleibt, die es &uuml;ber diesen Haltepunkt l&auml;uft). Dazu w&auml;hlen
sie den Schalter <i>Bedingt</i> und geben die Anzahl der zu ignorierenden
Treffer und/oder die Bedingung ein.
<h2>
Watchpoints manipulieren</h2>
Watchpoints sind den Haltepunkten &auml;hnlich, nur dass das Programm angehalten
wird, sobald sich der Inhalt einer Speicherstelle &auml;ndert. Ebenso wie
Haltepunkte k&ouml;nnen Watchpoints nicht manipuliert werden, solange das
Programm l&auml;uft. Weitere Hinweise dazu <a href="#StopProg">siehe oben</a>.
<p>Einen Watchpoint k&ouml;nnen Sie setzen, indem Sie einen Ausdruck im
Feld &uuml;ber der Liste eingeben und <i>Watchpoint</i> klicken. Das Programm
wird dann angehalten, sobald sich der Wert des Ausdrucks &auml;ndert. Beachten
Sie, dass Sie Watchpoints, die eine lokale Variable ben&ouml;tigen, nur
setzen k&ouml;nnen, wenn das Programm von einem Haltepunkt (oder mittels
Ausf&uuml;hrung|Unterbrechen) angehalten wurde.
<p>Zum Entfernen eines Watchpoints w&auml;hlen Sie diesen in der Liste
aus und klicken <i>Entfernen</i>. Falls der Ausdruck eine lokale Variable
enth&auml;lt, wird der Watchpoint automatisch entfernt, sobald das Programm
die aktive Funktion verl&auml;sst.
<p>Wie mit Haltepunkten k&ouml;nnen Sie eine Bedingung oder eine Anzahl
zu ignorierender Stopps setzen, indem Sie den Watchpoint ausw&auml;hlen
und <i>Bedingt</i> klicken.
</body>
</html>

View file

@ -0,0 +1,72 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Globale Einstellungen</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Globale Einstellungen</h1>
Mit dem Men&uuml;punkt <i>Datei|Globale Einstellungen</i> k&ouml;nnen Sie
folgende Optionen einstellen:
<ul>
<li>
den Befehl, mit dem gdb aufgerufen wird;</li>
<li>
den Befehl, der das Fenster f&uuml;r die Programmausgabe &ouml;ffnet,</li>
<li>
ob KDbg in den Vordergrund kommen soll, sobald das Programm stoppt, und
eine Verz&ouml;gerung, wann er sich wieder zur&uuml;ckzieht,</li>
<li>
die Tabulatorweite.</li>
</ul>
<h4>
Aufruf von gdb</h4>
<blockquote>Wenn Sie eine alternative Version von gdb verwenden wollen,
geben sie diese unter <i>Aufruf von GDB</i> an. Die Standardeinstellung
ist <tt>gdb --fullname --nx</tt>. Achtung: Sie m&uuml;ssen jedenfalls diese
beiden Argumente &uuml;bergeben; wenn Sie sie weglassen, kann KDbg nicht
funktionieren. Wenn Sie das Eingabefeld leer lassen, wird die Standardeinstellung
verwendet.</blockquote>
<h4>
Aufruf eines Terminal-Emulators</h4>
<blockquote>Falls Sie ein anderes Terminal-Programm verwenden wollen, das
die Ausgabe des Programms anzeigt, geben Sie dieses unter <i>Terminal f&uuml;r
die Programmausgabe</i> an. Die Standardeinstellung ist <tt>xterm -name
kdbgio -title %T -e sh -c %C</tt>. In diesem Eintrag wird <tt>%T</tt> durch
eine &Uuml;berschrift und <tt>%C</tt> durch ein Bourne-Shell-Skript ersetzt,
das in eine Endlosschleife landet, damit sich das Fenster nicht schlie&szlig;t.
(Keine Sorge, das Skript frisst keine CPU-Zeit, sondern ruft einfach nur
<tt>sleep
3600</tt> in einer Schleife auf :) Eine alternative f&uuml;r diesen Eintrag
w&auml;re zm Beispiel <tt>konsole --name kdbgio --caption %T -e
sh -c %C</tt>.</blockquote>
<h4>
In den Vordergrund</h4>
<blockquote>Sie k&ouml;nnen angeben, ob das KDbg-Fenster in den Vordergrund
gebracht werden soll, sobald das kontrollierte Programm anh&auml;lt (bei
einem Breakpoint oder wegen eines Signals). Das Fenster wird allerdings
nicht aktiviert (zumindest nicht unter KWM, dem Window Manger von KDE).
Manche Benutzer werden dieses Verhalten als st&ouml;rend empfinden, weshalb
diese Option standardm&auml;ssig ausgeschaltet ist.</blockquote>
<blockquote>Wenn diese Option eingeschaltet ist, zieht sich das KDbg-Fenster
auch wieder in den Hintergrund zur&uuml;ck, sobald das Programm fortgesetzt
wird. Allerdings geschieht das erst nach einer Verz&ouml;gerung, die ebenfalls
angegeben werden kann. Dadurch wird verhindert, dass das Fenster st&auml;ndig
nach hinten und vorne blinkt, sobald Sie einen Einzelschritt-Befehl absetzen.</blockquote>
</body>
</html>

View file

@ -0,0 +1,83 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Wie kann ich...?</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Wie kann ich...?</h1>
<h4>
... eine Haltepunkt setzen?</h4>
Daf&uuml;r gibt's mehrere M&ouml;glichkeiten:
<ul>
<li>
Sie k&ouml;nnen im <a href="sourcecode.html">Quellcode-Fenster</a> in den
"aktiven Bereich" am linken Ende der Zeile klicken.</li>
<li>
Sie k&ouml;nnen im Quellcode-Fenster eine Zeile ausw&auml;hlen und dann
im Men&uuml; <i>Haltepunkt</i> eine Auswahl treffen.</li>
<li>
Sie k&ouml;nnen einen Haltepunkt in der <a href="breakptlist.html">Liste
der Haltepunkte</a> setzen.</li>
</ul>
Wenn Sie keinen Haltepunkt setzen k&ouml;nnen, k&ouml;nnte es sein, dass
das Programm gerade l&auml;uft. Sie k&ouml;nnen keine Haltepunkte setzen,
solange das Programm l&auml;uft. Halten Sie es zuerst mit <i>Ausf&uuml;hrung|Unterbrechen</i>
an. Falls Sie dann noch immer keine Haltepunkte setzen k&ouml;nnen, versichern
Sie sich, dass Sie das Programm mit Debug-Information &uuml;bersetzt <i>und
gebunden</i> haben.
<h4>
... den Wert einer globalen Variablen oder eines beliebigen Ausdrucks anzeigen?</h4>
Benutzen Sie das <a href="watches.html">Ausdr&uuml;cke-Fenster</a>.
<h4>
... Watchpoints setzen?</h4>
Watchpoints k&ouml;nnen &uuml;ber die <a href="breakptlist.html">Liste
der Haltepunkte</a> bearbeitet werden.
<h4>
... einen Core-Dump benutzen?</h4>
Laden Sie zuerst das Programm mittels <i>Datei|Programm</i>, dann geben
Sie den Core-Dump mittels <i>Datei|Core dump</i> an.
<h4>
... ein Programm debuggen, das sich in eine Endlosschleife verlaufen hat?</h4>
Starten Sie das Programm und lassen Sie es laufen, bis es in die Endlosschleife
gelangt. Dann schalten Sie um zu KDbg und w&auml;hlen <i>Ausf&uuml;hrung|Unterbrechen</i>.
Hiermit haben Sie das Programm <i>in flagranti</i> erwischt!
<h4>
... erreichen, dass das Programm einigemale &uuml;ber einen Haltepunkt
dr&uuml;berl&auml;uft, ohne anzuhalten?</h4>
In der <a href="breakptlist.html">Liste der Haltepunkte</a> w&auml;hlen
Sie den Haltepunkt; dann klicken Sie <i>Bedingt</i> und geben die Anzahl
in <i>Ignoriere n&auml;chste Treffer</i> an.
<h4>
... eine Umgebungsvariable f&uuml;r das Programm setzen?</h4>
W&auml;hlen Sie <i>Ausf&uuml;hrung|Argumente</i> und geben die Umgebungsvariable
im <a href="argspwdenv.html#Environment">Argumente-Dialog</a> an.
<h4>
... ein Arbeitsverzeichnis f&uuml;r das Programm w&auml;hlen?</h4>
W&auml;hlen Sie <i>Ausf&uuml;hrung|Argumente</i> und geben das Arbeitsverzeichnis
im <a href="argspwdenv.html#Environment">Argumente-Dialog</a> an.
<h4>
... das Terminal-Fenster los werden?</h4>
W&auml;hlen Sie <i>Datei|Einstellungen</i> und schalten auf das Register
<a href="pgmsettings.html#output">Ausgabe</a>
um. W&auml;hlen Sie <i>Nur Ausgabe, einfache Terminalemulation</i> und
klicken Sie <i>OK</i>. Nun m&uuml;ssen Sie das Programm neu laden (am einfachsten
w&auml;hlen Sie es aus der Liste unter <i>Datei|Zuletzt ge&ouml;ffnete
Programme</i>). Die Programmausgaben werden nun in das eingebaute <a href="pgmoutput.html">Ausgabefenster</a>
geschrieben und stdin ist auf <tt>/dev/null</tt> umgeleitet.
<p>Sie m&uuml;ssen diese Einstellungen f&uuml;r jedes neue Programm wiederholen,
das Sie debuggen.
<p><b><i>Wichtig:</i></b> Sie sollten dies nicht tun, falls Ihr Programm
Eingaben vom Terminal (normalerweise stdin) erwartet oder falls mehr als
nur einfache Terminalemultionen ben&ouml;tigt werden (mehr als nur Wagenr&uuml;cklauf
und Zeilenvorschub). Das eingebaute Ausgabefenster unterst&uuml;tzt keine
Eingaben oder Terminalemulationen.
</body>
</html>

View file

@ -0,0 +1,175 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<h1>
KDbg - Benutzerhandbuch</h1>
<h2>
Inhalt</h2>
<ul>
<li>
<a href="#Introduction">Einleitung</a></li>
<li>
<a href="#UsingKDbg">Mit KDbg arbeiten</a></li>
<li>
<a href="#InfoWindows">Die Informationsfenster von KDbg</a></li>
<li>
<a href="#TipsTricks">Tipps und so weiter</a></li>
<li>
F&uuml;r Fortgeschrittene: <a href="../../en/kdbg/types.html">Typentabellen</a>
(nur Englisch)</li>
<li>
<a href="#Author">Autor</a></li>
</ul>
<hr>
<h2>
<a NAME="Introduction"></a>Einleitung</h2>
KDbg ist eine grafische Benutzeroberfl&auml;che f&uuml;r <tt>gdb</tt>,
den GNU-Debugger.
<p>Das bedeutet, dass KDbg selbst nicht der Debugger ist. Vielmehr kommuniziert
KDbg mit <tt>gdb</tt>, indem Befehlszeilen and diesen geschickt werden
und die Ausgabe, wie z.B. Variablenwerte, entgegengenommen werden. Die
Men&uuml;befehle und Mausklicks werden in <tt>gdb</tt>-Befehle umgesetzt,
und die Ausgabe von <tt>gdb</tt> wird in (mehr oder weniger) sichtbare
Information umgesetzt, wie zum Beispiel die Struktur von Variablen.
<p>Eine Folge davon ist, dass KDbg vollst&auml;ndig von den F&auml;higkeiten
des verwendeten Befehlszeilendebuggers, <tt>gdb</tt>, abh&auml;ngig ist.
KDbg kann nicht mehr als <tt>gdb</tt> leisten. Wenn Sie zum Beispiel einen
<tt>gdb</tt>
haben, der Programme mit Threads nicht unterst&uuml;tzt, dann kann auch
KDbg das nicht (obwohl ein Threads-Fenster vorhanden ist).
<h2>
<a NAME="UsingKDbg"></a>Mit KDbg arbeiten</h2>
Bevor Sie mit der Arbeit beginnen, sollten Sie die <a href="globaloptions.html">globalen
Einstellungen</a> pr&uuml;fen, indem Sie <i>Datei|Globale Einstellungen</i>
aufrufen.
<h4>
Ein zu debuggendes Program angeben</h4>
Um ein Programm zu debuggen, w&auml;hlen Sie <i>Datei|Programm</i>. Wenn
Sie das Programm schon einmal debuggt haben, k&ouml;nnen Sie es auch aus
der Liste unter <i>Datei|Zuletzt g&ouml;ffnete Programme</i> w&auml;hlen.
Das Programm wird jetzt geladen.
<p>Wenn Sie einen Core-Dump verwenden wollen, m&uuml;ssen Sie zuerst das
Programm, das den Core-Dump erzeugt hat wie gerade erw&auml;hnt laden,
dann w&auml;hlen Sie <i>Datei|Core dump</i> aus dem Men&uuml;. KDbg zeigt
die Stelle an, die den Core-Dump verursacht hat.
<p>Sie k&ouml;nnen nun Haltepunkte setzen, indem Sie die Eintr&auml;ge
im Men&uuml; <i>Haltepunkt</i> oder im Rechte-Maus-Men&uuml; oder in der
<a href="breakptlist.html">Liste
der Haltepunkte</a> verwenden.
<p>Sie k&ouml;nnen auch <a href="pgmsettings.html">programmspezifische
Einstellungen</a> vornehmen, indem Sie <i>Datei|Einstellungen</i> w&auml;hlen.
<h4>
Das Programm ausf&uuml;hren</h4>
Nun f&uuml;hren Sie das Programm aus, indem Sie <i>Ausf&uuml;hrung|Ausf&uuml;hren</i>
w&auml;hlen. Das Programm arbeitet nun wie gew&ouml;hnlich, bis es beendet
wird, auf einen Haltepunkt oder Watchpoint trifft, oder ein Signal empf&auml;ngt.
<p>Sie k&ouml;nnen das Programm mit Argumenten ausf&uuml;hren, ein Arbeitsverzeichnis
festlegen und auch Umgebungsvariablen definieren. Dazu w&auml;hlen Sie
<i>Ausf&uuml;hrung|Argumente</i>
und machen Ihre Angaben im <a href="argspwdenv.html">Programmargumente-Dialog</a>.
<p>Weiters k&ouml;nnen Sie sich in ein Programm einh&auml;ngen (<i>attachen</i>),
das bereits ausgef&uuml;hrt wird. Dazu laden Sie das Programm zuerst wie
oben beschrieben, dann w&auml;hlen Sie <i>Ausf&uuml;hrung|Attachen</i>.
Geben Sie die Prozessnummer an und klicken Sie <i>OK</i>. Das Programm
wird jetzt angehalten (aber nicht beendet), und der derzeitige Stand des
Programms wird im <a href="sourcecode.html">Quellcode-Fenster</a> angezeigt.
<h4>
Das Programm wurde angehalten - was nun?</h4>
Wenn das Programm an einem Haltepunkt, Watchpoint oder wegen eines Signals
angehalten wird, zeigt das <a href="sourcecode.html">Quellcode-Fenster</a>
die Zeile, in der das Programm gerade arbeitete. Es passiert h&auml;ufig,
dass das Programm wegen eine Signals (oftmals <tt>SIGSEGV</tt>, Speicherzugriffsfehler)
in einer Funktion angehalten wird, die sich nicht in jenem Programmteil
befindet, den Sie geschrieben haben. In diesem Fall betrachten Sie das
<a href="stack.html">Stack-Fenster</a>
genauer: Suchen Sie nach einer Funktion, die Sie geschrieben haben (beginnen
Sie am oberen Ende) und klicken Sie darauf. Das bringt Sie an eine Stelle,
an der Sie mit der Suche nach dem tats&auml;chlichen Programmfehler beginnen
k&ouml;nnen.
<p>Im Men&uuml; <i>Ausf&uuml;hrung</i> finden Sie Befehle, die Sie zum
Ausf&uuml;hren und schrittweisen Abarbeiten des Programms verwenden. Weiters
k&ouml;nnen Sie das laufende Programm unterbrechen. Die wichtigen Befehle
k&ouml;nnen auch mit Funktionstasten gegeben werden. Zum effizienten Arbeiten
empfehle ich, dass Sie sich diese Tasten eingew&ouml;hnen.
Sie k&ouml;nnen <i>Einstellungen|Kurzbefehle festlegen</i> verwenden, falls
Sie die Funktionen anderen Tasten zuweisen wollen.
<p>Im Men&uuml; <i>Haltepunkt</i> finden Sie Befehle zum Setzen, Entfernen,
Aktivieren und Inaktivieren von permanenten und tempor&auml;ren Haltepunkten.
Nat&uuml;rlich k&ouml;nnen Sie auch eine <a href="breakptlist.html">Liste
der Haltepunkte</a> anzeigen. Sie k&ouml;nnen einen Haltepunkt auch setzen,
indem Sie mit der Maus in den Freiraum links der entsprechenden Quellcode-Zeile
klicken (mit der linken Maustaste); weiters k&ouml;nnen sie einen vorhandenen
Haltepunkt mit der mittleren Maustaste aktivieren und deaktivieren.
<p>Die Animation in der Werkzeugleiste zeigt an, ob das Programm gerade l&auml;uft.
Sie bleibt stehen, sobald das Programm an einem Haltepunkt oder aus einem
anderen Grund angehalten wird oder sobald es beendet wird.
Ein Klick auf die Animation hat die Funktion von <i>Ausf&uuml;hrung|Unterbrechen</i>.
<h2>
<a NAME="InfoWindows"></a>Die Informationsfenster von KDbg</h2>
KDbg zeigt Information in einer Reihe verschiedener Fenster an. Im Men&uuml;
<i>Ansicht</i>
finden Sie die Befehle, die diese Fenster anzeigen und schlie&szlig;en. Es handelt
sich dabei um <i>dockende</i> Fenster, sodass Sie deren Anordnung beliebig
ver&auml;ndern k&ouml;nnen.
<ul>
<li>
<a href="sourcecode.html">Das Quellcode-Fenster</a></li>
<li>
<a href="localvars.html">Lokale Variablen</a></li>
<li>
<a href="stack.html">Der Programm-Stack</a></li>
<li>
<a href="watches.html">Ausdr&uuml;cke (<i>Watches</i>)</a></li>
<li>
<a href="breakptlist.html">Die Liste der Haltepunkte</a></li>
<li>
<a href="pgmoutput.html">Das Programmausgabefenster</a></li>
<li>
<a href="registers.html">Die Registerinhalt</a></li>
<li>
<a href="memory.html">Der Speicherinhalt</a></li>
<li>
<a href="threads.html">Die Programm-Threads</a></li>
</ul>
<h2>
<a NAME="TipsTricks"></a>Tipps und so weiter</h2>
<ul>
<li>
<a href="tips.html">Tipps</a></li>
<li>
<a href="howdoi.html">Wie kann ich...?</a></li>
</ul>
<h2>
<a NAME="Author"></a>Autor</h2>
KDbg wurde von <a href="mailto:j6t@kdbg.org">Johannes Sixt</a>
mit vielen weiteren Helfern geschrieben.
<br>Die KDbg-Homepage befindet sich unter <a href="http://www.kdbg.org/">http://www.kdbg.org/</a>.
</body>
</html>

View file

@ -0,0 +1,25 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.18-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Lokale Variablen</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Lokale Variablen</h1>
Mittels <i>Ansicht|Lokale Variablen</i> wird das Fenster f&uuml;r die lokalen
Variablen angezeigt. Darin wird der Inhalt der lokalen Variablen des aktiven
Stack-Frames angezeigt.
<p>Das im <a href="stack.html">Stack-Fenster</a> ausgew&auml;hlte Frame
bestimmt die lokalen Variablen, die hier angezeigt werden.
<p>Sobald das Programm angehalten wird (z.B. durch einen Haltepunkt), wird
die Anzeige aktualisiert. Variablenwerte, die sich seit dem letzten Anhalten
ge&auml;ndert haben, werden rot hervorgehoben.
<p>Sie k&ouml;nnen die ausgew&auml;hlte Variable oder Struktur-Member in
das <a href="watches.html">Ausdr&uuml;ckefenster</a> kopieren, indem Sie
mittels der rechten Maustaste das kleine Kontextmen&uuml; aufrufen.
</body>
</html>

View file

@ -0,0 +1,29 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Speicherinhalt</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Der Speicherinhalt</h1>
Das Fenster zur Anzeige des Speicherinhalts k&ouml;nnen Sie mittels <i>Ansicht|Speicher</i>
aufrufen. Es zeigt den Inhalt des Speichers des Programms an beliebigen
Adressen an.
<p>Um Speicherinhalt anzuzeigen, geben Sie eine Adresse an. Die Adresse
braucht nicht in Hexadezimalform eingegeben werden und es kann sich auch
um einen beliebigen Ausdruck handeln.
<p>Sie k&ouml;nnen ein Format w&auml;hlen, wie der Speicherinhalt dargestellt
werden soll, indem Sie die entsprechenden Optionen im Rechte-Maus-Men&uuml;
w&auml;hlen.
<p>Die zuletzt verwendeten Adressen werden zwischengespeichert und k&ouml;nnen
&uuml;ber die Popup-Liste ausgew&auml;hlt werden. Bitte beachten Sie, dass
zusammen mit der Adresse auch das Darstellungsformat gespeichert wird.
<p>Wenn Sie keinen Speicherinhalt ansehen wollen, empfehlen wir, dass Sie
die Adresse l&ouml;schen, damit kein Speicherinhalt angezeigt wird - dadurch
arbeitet KDbg etwas schneller.
</body>
</html>

View file

@ -0,0 +1,52 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Programmausgabe</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Das Programmausgabefenster</h1>
Das Programmausgabefenster wird mit <i>Ansicht|Ausgabe</i> ge&ouml;ffnet.
Das Ausgabefenster zeichnet den Text auf, den das Programm auf <tt>stdout</tt>
und <tt>stderr</tt> ausgibt.
<p>Das Ausgabefenster l&auml;sst keine Eingabe zu und unterst&uuml;tzt
nur eine &auml;u&szlig;erst minimale Terminalemulation: Lediglich <tt>\n</tt>
(Zeilenvorschub, line-feed), <tt>\t</tt> (horizontaler Tabulator) und
<tt>\r</tt> (Wagenr&uuml;cklauf, carriage-return) werden behandelt.
Das reicht im Allgemeinen f&uuml;r Programme mit grafischer Benutzeroberfl&auml;che
aus, die nur Debug-Ausgaben schreiben.
<p>Wenn ein Programm zum ersten Mal in KDbg geladen wird, wird dieses Ausgabefenster
<i>nicht</i> benutzt. Der Grund daf&uuml;r ist, dass KDbg nicht wissen
kann, ob das Programm eine ausgefeilte Terminalemulation ben&ouml;tigt
oder ob es Eingaben &uuml;ber das Terminal erwartet. Deshalb wird standardm&auml;ssig
ein Terminalemulator verwendet. Um die Ausgaben in das Ausgabefenster umzuleiten,
gehen sie wie folgt vor:
<ol>
<li>
Rufen Sie mittels <i>Datei|Einstellungen</i> die <a href="pgmsettings.html">programmspezifischen
Einstellungen</a> auf.</li>
<li>
Schalten Sie auf das Register <i>Ausgabe</i> um.</li>
<li>
W&auml;hlen Sie <i>Nur Ausgabe, einfache Terminalemulation</i> und klicken
Sie <i>OK</i>.</li>
<li>
Laden Sie das Programm erneut, indem Sie es aus der Liste unter <i>Datei|Zuletzt
ge&ouml;ffnete Programme</i> w&auml;hlen.</li>
</ol>
Sie k&ouml;nnen den Inhalt des Fensters jederzeit l&ouml;schen, indem Sie
<i>L&ouml;schen</i> aus dem Popup-Men&uuml; w&auml;hlen, das Sie mit der
rechten Maustaste aufrufen k&ouml;nnen.
<p>Falls die letzte Zeile des Ausgabefensters sichtbar ist, verschiebt
sich der Fensterinhalt automatisch, sodass die letzte Zeile immer sichtbar
bleibt, wenn neuer Text ankommt. Wenn Sie hingegen den Fensterinhalt verschieben,
sodass die letzte Zeile nicht sichtbar ist, bleibt der sichtbare Teil unver&auml;ndert.
</body>
</html>

View file

@ -0,0 +1,77 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<title>KDbg - Benutzerhandbuch - Programmspezifische Einstellungen</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Programmspezifische Einstellungen</h1>
In diesem Dialog k&ouml;nnen programmspezifischen Einstellungen getroffen
werden. Der Dialog wird mittels <i>Datei|Einstellungen</i> aufgerufen.
Die Einstellungen werden nur auf das geladene Programm angewendet und bleiben
&uuml;ber Sitzungen hinweg erhalten.
<blockquote><b><i>Wichtiger Hinweis:</i></b> Die getroffenen Einstellungen
werden erst wirksam, wenn das Programm das <i>n&auml;chste Mal geladen</i>
wird. Das bedeutet, dass Sie nach dem Dr&uuml;cken von OK in diesem Dialog
das Programm erneut laden m&uuml;ssen (mittels <i>Datei|Programm</i>)!!</blockquote>
<ul>
<li>
<a href="#driver">Debugger</a></li>
<li>
<a href="#output">Ausgabe</a></li>
</ul>
<h2>
<a NAME="driver"></a>Debugger</h2>
Hier kann der Debugger gew&auml;hlt werden, der f&uuml;r dieses Programm
verwendet werden soll.
<h4>
Aufruf von GDB</h4>
<blockquote>Geben Sie den Befehl an, mit dem <tt>gdb</tt> aufgerufen werden
soll. Wenn Sie das Feld leer lassen, wird die <a href="globaloptions.html">globale
Einstellung</a> &uuml;bernommen. Wenn Sie cross-compilieren oder remote
debuggen, werden Sie hier einen <tt>gdb</tt>-Befehl angeben, der f&uuml;r
die Zielplattform geeignet ist. Die Standardeinstellung ist <tt>gdb&nbsp;--fullname&nbsp;--nx</tt>.
Sie m&uuml;ssen auf jeden Fall auch diese Optionen angeben, andernfalls
funktioniert KDbg nicht.</blockquote>
<h2>
<a NAME="output"></a>Ausgabe</h2>
Hier geben Sie an, unter welcher Terminalemulation das Programm arbeitet.
<h4>
Keine Ein- und Ausgabe</h4>
<blockquote>W&auml;hlen Sie diese Option, falls Ihr Programm keine Eingabe
vom Terminal erwartet und Sie keine Ausgabe sehen wollen, die auf <tt>stdout</tt>
oder <tt>stderr</tt> geschrieben wird. Alle drei Standardkan&auml;le (<tt>stdin</tt>,
<tt>stdout</tt>
und <tt>stderr</tt>) werden praktisch nach <tt>/dev/null</tt> umgeleitet.</blockquote>
<h4>
Nur Ausgabe, einfache Terminalemulation</h4>
<blockquote>W&auml;hlen Sie diese Option, falls Ihr Programm keine Eingabe
vom Terminal erwartet (<tt>stdin</tt> wird nach <tt>/dev/null</tt> umgeleitet)
und die Ausgabe, die auf <tt>stdout</tt> und <tt>stderr</tt> geschrieben
wird, keine besondere Terminalemulation erfordert. Die Ausgabe wird im
<a href="pgmoutput.html">Ausgabefenster</a>
angezeigt.</blockquote>
<h4>
Volle Terminalemulation</h4>
<blockquote>W&auml;hlen Sie diese Option, falls Ihr Programm Eingaben &uuml;ber
<tt>stdin</tt>
liest oder falls die Ausgabe auf <tt>stdout</tt> oder <tt>stderr</tt> Terminalemulation
erfordert. Ein Terminalemulator kann in den <a href="globaloptions.html">globalen
Einstellungen</a> angegeben werden.</blockquote>
</body>
</html>

View file

@ -0,0 +1,37 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Registerinhalt</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Der Registerinhalt</h1>
Das Fenster zur Anzeige des Registerinhalts wird mittels <i>Ansicht|Register</i>
angezeigt. Jedesmal, wenn das Programm angehalten wird, zeigt Kdbg hier
den Inhalt der CPU-Register an.
<p>Das Fenster ist in 3 Spalten aufgeteilt:
<ol>
<li>
Die Spalte <i>Register</i> zeigt die Namen der Register.</li>
<li>
Die Spalte <i>Wert</i> zeigt den Inhalt der Register in einer mehr oder
weniger rohen Form an. Diese rohe Form wird &uuml;blicherweise in Hexadezimaldarstellung
angezeigt, selbst der Inhalt der Flie&szlig;kommaregister.</li>
<li>
Die Spalte <i>Dekodierter Wert</i> zeigt den Inhalt der Register in dekotierter
Form an. Bei den arithmetischen Registern ist das meist eine vorzeichenbehaftete
Dezimalzahl, bei Flie&szlig;kommaregistern wird die Flie&szlig;kommazahl
angezeigt, die Flag-Register werden manchmal die gesetzten Flags in Worten
dargestellt (h&auml;ngt von der verwendeten Version von <tt>gdb</tt> ab).</li>
</ol>
Durch Klicken mit der rechten Maustaste k&ouml;nnen Sie ein Kontextmen&uuml;
aufrufen, &uuml;ber das Sie die Darstellung der Werte in der zweiten Spalte
w&auml;hlen k&ouml;nnen.
</body>
</html>

View file

@ -0,0 +1,30 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Quellcode</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Das Quellcode-Fenster</h1>
Das Quellcode-Fenster ist das Hauptfenster und ist immer sichtbar.
<p>Das Quellcode-Fenster zeigt den Quellcode von Programmen an. Am linken
Rand jeder Zeile befindet sich ein "aktiver Bereich". Dort wird ein mit
einem Pfeil angezeigt, an welcher Stelle das Programm gerade ausgef&uuml;hrt
wird. Weiters wird hier angezeigt, an welchen Stellen Haltepunkte gesetzt
sind.
<p>Neue Haltepunkte k&ouml;nnen gesetzt werden, indem Sie mit der linken
Maustaste in den aktiven Bereich klicken. Mit der mittleren Maustaste k&ouml;nnen
Sie vorhandene Haltepunkte aktivieren und deaktivieren.
<p>Das kleine Pluszeichen '+' zwischen dem "aktiven Bereich" und der Quellcodezeile
zeigt den Assembler-Code der Quellcodezeile an, wenn Sie darauf klicken.
Dabei wird das Zeichen zu einem Minus '-', das den Assemblercode wieder
verbirgt, wenn Sie darauf klicken.
<p>Meistens werden Quellcode-Dateien automatisch ge&ouml;ffnet. Sie k&ouml;nnen
Dateien manuell &ouml;ffnen, indem Sie <i>Datei|Quellcode &ouml;ffnen</i>
w&auml;hlen oder <i>Quellcode &ouml;ffnen</i> aus dem Rechte-Maus-Men&uuml;.
</body>
</html>

View file

@ -0,0 +1,25 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Stack</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Das Stack-Fenster</h1>
Das Stack-Fenster wird mittels <i>Ansicht|Stack</i> angezeigt. Hierin wird
der Call-Stack (Backtrace, Stack-Frames) angezeigt, d.h. die Funktionen,
die das Programm im Augenblick betreten und noch nicht verlassen hat.
<p>Das innerste Frame (in dem sich das Programm gerade befindet) befindet
sich an erster Stelle.
<p>Sie k&ouml;nnen in ein anderes Stack-Frame umschalten, indem Sie einfach
auf die entsprechende Zeile klicken. Das <a href="sourcecode.html">Quellcode-Fenster</a>
zeigt die Stelle an, in der der Aufruf in das n&auml;chst-innere Frame
stattfand; die Anzeige der <a href="localvars.html">lokalen Variablen</a>
und die <a href="watches.html">Ausdr&uuml;cke</a> werden umgeschaltet,
sodass die lokalen Variablen des gew&auml;hlten Frames angezeigt werden.
</body>
</html>

View file

@ -0,0 +1,44 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Threads</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Die Programm-Threads</h1>
Das Fenster mit der Liste der Programm-Threas wird mittels <i>Ansicht|Threads</i>
aufgerufen. Dieses Fenster listet die aktiven Threads des Programms auf.
<p><b><i>Wichtig:</i></b> Das Debuggen von Programm-Threads muss von der
verwendeten <tt>gdb</tt>-Version unterst&uuml;tzt werden - es handelt sich
hierbei nicht um ein Feature von KDbg. F&uuml;r Linux-Systeme (i386) funktioniert
<tt>gdb5</tt>
am besten.
<p>Der Inhalt des Fensters wird jedesmal erneuert, wenn das Programm vom
Debugger angehalten wird. (Das heisst, dass <i>nicht</i> der aktuelle Zustand
des Programms angezeigt wird, w&auml;hrend es l&auml;uft.)
<p>Die erste Spalte zeigt die Thread-ID an, die zweite Spalte zeigt die
Stelle, an der der Thread gerade abgearbeitet wird.
<p>Die Markierung am Zeilenanfang benennt den <i>aktiven</i> Thread:
<ul>
<li>
Das&nbsp; <a href="stack.html">Stack-Fenster</a> zeigt den Call-Stack des
aktiven Threads.</li>
<li>
Das <a href="localvars.html">Fenster mit den lokalen Variablen</a> zeigt
die lokalen Variablen des aktiven Threads.</li>
<li>
Das <a href="watches.html">Ausdr&uuml;cke-Fenster</a> verwendet zur Evaluierung
der Ausdr&uuml;cke die lokalen Variablen des aktiven Threads.</li>
</ul>
Indem Sie auf einen Thread klicken, wechseln Sie den aktiven Thread und
die genannten Fenster werden entsprechend auf den aktuellen Stand gebracht.
Ausserdem schaltet das <a href="sourcecode.html">Quellcode-Fenster</a>
zu der Programmstelle um, an der der aktive Thread angehalten wurde.
</body>
</html>

View file

@ -0,0 +1,45 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Tipps</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h2>
Tipps und Tricks</h2>
<ul>
<li>
Setzen Sie immer die Umgebungsvariable <tt>LD_BIND_NOW=1</tt> auf glibc2-Systems.
Wie Umgebungsvariablen gesetzt werden, wird <a href="argspwdenv.html#Environment">hier
erkl&auml;rt</a>.</li>
<li>
Sie k&ouml;nnen Haltepunkte als Lesezeichen verwenden: Setzen Sie einfach
einen Haltepunkt und deaktivieren Sie diesen. Sp&auml;ter k&ouml;nnen Sie
rasch an die entsprechende Stelle zur&uuml;ckkehren, indem Sie in der Liste
der Haltepunkte doppel-klicken (oder&nbsp; <i>Code anzeigen</i> klicken).
Da sich KDbg alle Haltepunkte &uuml;ber Sitzungen hinaus merkt, werden
sie sofort wieder gesetzt, sobald sie das entsprechende Programm das n&auml;chste
Mal debuggen.</li>
<li>
Auf folgende Weise k&ouml;nnen Sie Programmvariablen &auml;ndern: Im Watch-Bereich
(rechts unten) geben Sie eine Zuweisung ein, z.B. <tt>var.member=17</tt>
und Klicken <i>Neu</i>. Die entsprechende Variable wird sofort ge&auml;ndert.
Sie sollten die Variable nun sofort l&ouml;schen (indem Sie sie ausw&auml;hlen
und <i>Entf</i> klicken). Das ist notwendig, weil der Ausdruck (d.h die
Zuweisung) sonst bei jedem Programmstopp ausgewertet wird.</li>
<li>
Sie k&ouml;nnen Werte im Watch-Bereich in den verschiedenen Formaten anzeigen
lassen, die gdb versteht. Z.B. zeigt <tt>/x&nbsp;var.member</tt> die Variable
<tt>var.member</tt>
in hexadezimaler Notation an.</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.18-SMP i686) [Netscape]">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Benutzerhandbuch - Ausdr&uuml;cke</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Inhalt</a>
<h1>
Ausdr&uuml;cke (Watches)</h1>
Das Watches-Fenster wird mittels <i>Ansicht|Ausdr&uuml;cke</i> angezeigt.
Dieses zeigt beliebige Ausdr&uuml;cke an (diese bezeichnet man auch als
<i>Watches</i>).
<p>Ein neuer Ausdruck wird hinzugef&uuml;gt, indem dieser im Eingabefeld
eingegeben wird und dann auf <i>Neu</i> geklickt wird. Um einen Ausdruck
zu entfernen, klicken Sie diesen an (an der Wurzel des entsprechenden Baums)
und klicken dann auf <i>Entf</i>.
<p>Sie k&ouml;nnen auch eine Variable oder einen Struktur-Member aus dem
<a href="localvars.html">Lokale-Variablen-Fenster</a> her&uuml;berkopieren,
indem Sie das dortige Kontextmen&uuml; zuhilfe nehmen.
<p>Die eingegeben Ausdr&uuml;cke werden zwischen Sitzungen gespeichert.
Wir empfehlen, Ausdr&uuml;cke zu entfernen, die nicht mehr ben&ouml;tigt,
weil das die Arbeitsgeschwindigkeit von KDbg steigert.
</body>
</html>

View file

@ -0,0 +1,20 @@
install(FILES
argspwdenv.html
breakptlist.html
globaloptions.html
howdoi.html
invocation.html
localvars.html
memory.html
pgmoutput.html
pgmsettings.html
registers.html
sourcecode.html
stack.html
threads.html
tips.html
types.html
watches.html
xslt.html
index.html
DESTINATION ${HTML_INSTALL_DIR}/en/kdbg)

View file

@ -0,0 +1,42 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Arguments, Environment</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
Specifying program arguments, working directory, environment variables</h1>
<p>Choose <i>Execution|Arguments</i> to open a dialog where you can set program
arguments, the working directory for your program, and environment variables.</p>
<h2><a name="PgmArgs"></a>Tab Arguments</h2>
<p>In the edit box enter the arguments that shall be passed on to your
program. <i>Insert file name</i> lets you browse for a file;
the file name will be <em>inserted</em> in the edit box (at the cursor position).</p>
<p>Next time the program is started, the new arguments will be used.</p>
<h2><a name="WorkingDir"></a>Tab Working Directory</h2>
<p>In the edit box you can specify the working directory for your program.
<i>Browse</i> lets you browse for a directory.
Your program will use the new directory only when it is run the next time.</p>
<p>The working directory also applies to gdb itself! The directory that
you specify will be passed to gdb immediately, i.e. gdb will work with
the new setting as soon as you press <i>OK</i>. This can influence whether
source code files are found.</p>
<h2><a name="Environment"></a>Tab Environment</h2>
<p>In the Environment tab you can set environment variables that the program
sees in addition to those that it inherits.
In the edit box type in an expression of the form <tt>VARIABLE=value</tt>
to set the environment variable <tt>VARIABLE</tt> to the value <tt>value</tt>,
and click <i>Modify</i>. To remove a variable, select it from the list
below and click <i>Delete</i>. To change the value, edit the value in the
edit field and click <i>Modify</i>. If you change the name of the variable
and click <i>Modify</i>, you add a new variable! The new environment variables
will be used by your program the next time it is run.</p>
<h2>Tab xsldbg Settings</h2>
<p>This tab is only available when a <a href="xslt.html">XSLT script is
debugged</a>. Here you can specify various flags that influence the
XSL translation and XSLDBG.</p>
</body>
</html>

View file

@ -0,0 +1,93 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Breakpoint list</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Breakpoint List</h1>
<p>The breakpoint list displays all breakpoints and watchpoints that are set
and allows you to manipulate them. It can be displayed using <i>View|Breakpoints</i>.</p>
<h2>
The list of breakpoints</h2>
<p>For each breakpoint the following is shown:</p>
<ul>
<li>
the breakpoint location,</li>
<li>
the hit count,</li>
<li>
the ignore count if set,</li>
<li>
the condition if set.</li>
</ul>
<p>The icon in front of the entry indicates whether the breakpoint is enabled
(a red dot) or disabled (a bright red dot), whether the breakpoint is temporary
(a tiny clock is overlaid), whether the breakpoint is conditional (a
tiny question mark is overlaid), or whether the breakpoint is <em>orphaned</em>
(a 'x' is overlaid).</p>
<p>Watchpoints are indicated by an eye glas icon in front of the line.</p>
<h2>
<A name="orphanedbp"></A>Orphaned breakpoints</h2>
<p><em>Orphaned breakpoints</em> are breakpoints that gdb cannot implant
immediately. Orphaned breakpoints occur if you try to set a breakpoint in a file
that is not part of the executable. In particular, this is the case if the file
belongs to a shared library or dynamically loaded module: When the executable
is loaded, gdb does not yet know about dynamic modules and, hence, cannot set
breakpoints there. However, KDbg does not forget about requests to set
breakpoints in dynamic modules: It tries to set orphaned breakpoints each time
that the program stops. When the breakpoint can be set successfully, it turns
into a normal breakpoint.</p>
<p>But there is an important consequence: Orphaned breakpoints are not effective,
and the program will <em>not</em> stop there. The remedy is to set a breakpoint
in the executable at the earliest possible point after which it is known that
the dynamic module is loaded. For shared libraries this is usually in <tt>main()</tt>
and for dynamically loaded modules it is after the call to <tt>dlopen()</tt>
(or equivalent). When the program stops at this breakpoint the orphaned
breakpoints from the dynamic module are set and become effective.</p>
<h2>
Manipulating breakpoints</h2>
<p><a name="StopProg"></a>It is important to note that breakpoints and watchpoints
cannot be manipulated while the program is running. If the program has
already been started, it must stop first - either by hitting a breakpoint
that is already set or forcefully by choosing <i>Execution|Break</i>. Note
that this will not terminate the program, it just interrupts it. You can
now manipulate the breakpoints; then choose <i>Execution|Continue</i> to
let the program continue.</p>
<p>To set a breakpoint on a specific source line, it is easiest to do this
in the source code window. If you don't know the exact file and line number
of a function, you can set the breakpoint by typing the function name in
the edit box above the list and click <i>Add Breakpoint</i>.</p>
<p>You can disable and enable breakpoints by selecting them in the list
and clicking <i>Disable</i> or <i>Enable</i>. Or you simply click on the
breakpoint in the list using the middle mouse button - just like you enable
and disable breakpoints in the source window.</p>
<p>You can set a condition on a breakpoint (so that the program is only
stopped if the condition is true) or set an ignore count (so that the program
is not stopped the next n times that the breakpoint is hit). To do that,
press the <i>Conditional</i> button and enter the condition and/or ignore
count.</p>
<h2>
Manipulating watchpoints</h2>
<p>Watchpoints are a like breakpoints, except that they interrupt the program
when the value of a memory location changes. As with breakpoints, watchpoints
cannot be manipulated while the program is running. See <a href="#StopProg">above</a>
for more information.</p>
<p>To set a watchpoint, type an expression in the edit box above the list,
then click <i>Add Watchpoint</i>. The program will stop when the value
of the expression changes. Note that watchpoints that involve local variables
can only be set when the program is stopped in a breakpoint (or has been
interrupted by <i>Execution|Break</i>).</p>
<p>To remove the watchpoint, select it from the list and click <i>Remove</i>.
If the expression involves a local variable, the watchpoint will be removed
automatically when the program leaves the current frame.</p>
<p>You can set a condition and an ignore count on the watchpoint just like
on breakpoints by selecting it and clicking <i>Conditional</i>.</p>
</body>
</html>

View file

@ -0,0 +1,78 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Global Options</title>
</head>
<body text="#000000" bgcolor="#ffffff">
<p><a href="index.html">Contents</a></p>
<h1>
Global Options Dialog</h1>
<p>To specify some global options, choose <i>Settings|Global Options</i>. You
can set the following:</p>
<ul>
<li>
the command by which gdb is invoked,</li>
<li>
the command that opens a terminal for the program's output,</li>
<li>
whether the KDbg shall pop into the foreground when the program stops and
a timeout when it shall go back again,</li>
<li>
the tab width,</li>
<li>
filters for source file names.</li>
</ul>
<h4>
How to invoke gdb</h4>
<blockquote>If you want to use a different version of gdb, you can specify
it under
<i>How to invoke GDB</i>. The default command is <tt>gdb --fullname
--nx</tt>. Be sure to also specify these options if you change the gdb
executable. If you leave them away, KDbg will not work. If you messed up
the entry, you can clear it to revert to the default setting.</blockquote>
<h4>
How to invoke a terminal emulator</h4>
<blockquote>If you want to use a different terminal program to show the
output of the program, specify it under <i>Terminal for program output</i>.
The default setting is <tt>xterm -name kdbgio -title %T -e sh -c %C</tt>.
In this entry,
<tt>%T</tt> will be replaced by a title string, <tt>%C</tt>
will be replaced by a Bourne shell script that loops infinitely so that
the terminal window doesn't close. (No, it doesn't use CPU, it calls <tt>sleep
3600</tt> in a loop :) An alternative for this setting could be <tt>konsole
--name kdbgio --caption %T -e sh -c %C</tt>.</blockquote>
<h4>
Pop into foreground</h4>
<blockquote>You can specify whether the KDbg window shall move itself into
the foreground as soon as the program being debugged stops (at a breakpoint
or due to a signal). The KDbg window is not activated, however (at least
under KWM, the KDE window manager). Some users may feel that this behavior
is intrusive, so this option is off by default.</blockquote>
<blockquote>If this option is on, KDbg will also retreat itself into the
background when the program is continued by any command, but it does so
only after a timeout that can be specified. This avoids that the debugger
window flashes back and forth each time you click any of the <i>Step</i>
commands.</blockquote>
<h4>
File filters</h4>
<blockquote>You can specify wildcards for source files and header files,
which are used in the file dialog of the <i>File|Open Source</i>
command.</blockquote>
</body>
</html>

View file

@ -0,0 +1,76 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - How Do I...?</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
How Do I...?</h1>
<h4>
... set breakpoints?</h4>
<p>There's more than one way to set a breakpoint:</p>
<ul>
<li>
You can set it in the source window by clicking on the "active area" at
the far left of the line.</li>
<li>
You can set it by selecting the line in the source window and choosing
an option from the <i>Breakpoint</i> menu.</li>
<li>
You can set it in the <a href="breakptlist.html">breakpoint list</a>.</li>
</ul>
<p>If you can't set breakpoints, maybe the program is currently running. You
can't set breakpoints while the program is running. Stop it first using
<i>Execution|Break</i>.
If you still can't set breakpoints, make sure that you have compiled <em>and
linked</em> your program with debugging information enabled.</p>
<h4>
... display the value of a global variable or an arbitrary expression?</h4>
<p>Use the <A href="watches.html">Watch window</A>.</p>
<h4>
... set watchpoints?</h4>
<p>Watchpoints are manipulated in the <a href="breakptlist.html">breakpoint
list</a>.</p>
<h4>
... use a core dump?</h4>
<p>First load the executable using <i>File|Executable</i>, then specify the
core dump using <i>File|Core dump</i>.</p>
<h4>
... debug a program that's caught in an endless loop?</h4>
<p>Start the program and let it run until it is in the endless loop. Then
switch to KDbg and choose <i>Execution|Break</i>. You've just caught the
nasty program <em>in flagranti</em>!</p>
<h4>
... achieve that the program passes over a breakpoint a number of times
before it stops?</h4>
<p>In the <a href="breakptlist.html">breakpoint list</a> select the breakpoint;
then click <i>Conditional</i> and specify the number of times to skip the
breakpoint in the <i>Ignore count</i> field.</p>
<h4>
... set environment variables for the executable?</h4>
<p>Select <i>Execution|Arguments</i> and specify the environment variables
in the <a href="argspwdenv.html#Environment">program arguments dialog</a>.</p>
<h4>
... set a working directory for the executable?</h4>
<p>Select <i>Execution|Arguments</i> and specify the working directory in
the <a href="argspwdenv.html#WorkingDir">program arguments dialog</a>.</p>
<h4>
... get rid of this terminal window?</h4>
<p>Select <i>Settings|This Program</i> and switch to the <a href="pgmsettings.html#output">Output</a> tab.
Select <i>Only output, simple terminal emulation</i> and click <i>OK</i>.
Now restart the program (choose it from the list under <i>File|Recent Executables</i>).
The program output goes now to the built-in <a href="pgmoutput.html">output
window</a> and stdin is redirected to <tt>/dev/null</tt>.</p>
<p>You must do this for every new program that you debug.</p>
<p><b><i>Important:</i></b> You should not do this if your program expects
input from the terminal (usually stdin) or if its output requires nifty
terminal emulation (more than carriage-return and line-feed). The built-in
output window does not support input and terminal emulation.</p>
</body>
</html>

View file

@ -0,0 +1,185 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<h1>
KDbg - User's Manual</h1>
<h2>
Contents</h2>
<ul>
<li>
<a href="#Introduction">Introduction</a></li>
<li>
<a href="#UsingKDbg">Using KDbg</a></li>
<li>
<a href="#InfoWindows">KDbg's information windows</a></li>
<li>
<a href="#Tips">Tips and such</a></li>
<li>
Advanced topic: <a href="types.html">Type tables</a></li>
<li>
<a href="invocation.html">How to invoke KDbg from the command line</a></li>
<li>
<a href="#Author">Author</a></li>
</ul>
<hr>
<h2>
<a name="Introduction"></a>Introduction</h2>
<p>KDbg is a front-end for <tt>gdb</tt>, the GNU debugger.</p>
<p>This means that KDbg itself is not the debugger. Rather, it communicates
with <tt>gdb</tt>, a command line debugger, by sending commands to it and
receiving the output, such as variable values. The menu commands and mouse
clicks are translated into <tt>gdb</tt> commands, and the output of <tt>gdb</tt>
is translated into (more or less) visible information, such as structured
variable contents.</p>
<p>The upshot of all this is that KDbg completely relies on the capabilities
of the underlying command line debugger, <tt>gdb</tt>. KDbg can do no more
than <tt>gdb</tt> can. For example, if you have a <tt>gdb</tt> that does
not supports debugging of threaded programs, KDbg cannot, either (even
though it offers a threads window).</p>
<h2>
<a name="UsingKDbg"></a>Using KDbg</h2>
<p>Before you start using KDbg, you may want to review the options in the
<a href="globaloptions.html">Global Options</a> dialog that you invoke
with <i>Settings|Global Options</i>.</p>
<h4>
Specifying a debugging target</h4>
<p>To debug a program, choose <i>File|Executable</i> from the menu. If you
have debugged the program earlier, you can choose it from <i>File|Recent
Executables</i>. The program is loaded.</p>
<p>If you want to debug a core dump, you must first load the executable
that produced the core dump, then choose
<i>File|Core Dump</i> from the
menu. Now KDbg goes to the point in the program that caused the core dump.</p>
<p>You can now set breakpoints, using the <i>Breakpoint</i> menu, the right
mouse button menu, or the <a href="breakptlist.html">breakpoint window</a>.</p>
<p>You can also choose program specific settings that apply only to the
currently loaded executable using <i>Settings|This Program</i>, in the
<a href="pgmsettings.html">Program Settings</a> dialog.</p>
<p>Furthermore, it is possible to <a href="xslt.html">debug XSLT scripts</a>.</p>
<h4>
Running the program</h4>
<p>Now run the program by selecting <i>Execution|Run</i>. The program now
executes as usual until it either exits, hits a breakpoint or watchpoint,
or receives a signal.</p>
<p>You can run the program with arguments, set a working directory, or
set environment variables. To do this, choose <i>Execution|Arguments</i>
and specify your options in the <a href="argspwdenv.html">Program Arguments</a>
dialog (before you start the program).</p>
<p>You can also attach to a program that is currently running. To do this,
first load the executable file like above. Then choose <i>Execution|Attach</i>.
From the list processes specify the one you want to attach to
and click <i>OK</i>. The running program is
halted (not terminated), and the current point of execution is displayed
in the source window.</p>
<p><font size="-1">On some systems the list of processes may not be available.
In this case a simple edit box is available where the process number can be
specified.</font></p>
<h4>
The program stopped - now what?</h4>
<p>When the program stops at a breakpoint, watchpoint, or due to a signal,
the <a href="sourcecode.html">source code window</a> displays the line
where the program stopped. It is very common that the program stops due
to a signal (usually a <tt>SIGSEGV</tt>, segmentation violation) in a function
that is not part of the program, that you have written. In this case you
investigate the <a href="stack.html">stack window</a> and look for a function
that you have written (start at the top of the list) and click on it. This
will bring you to a location that you can start your search for the real
bug.</p>
<p>In the menu <i>Execution</i> you find the commands that you need to
run
the program, step through code, and to interrupt the program (<i>Break</i>)
while it is running. The important commands (<i>Run</i> and all kinds of
<i>Step</i>) are bound to function keys. For efficient debugging it is
strongly recommend that you get used to using them. You can use
<i>Settings|Configure Shortcuts</i> if you want to bind the functions
to different keys.</p>
<p>In the menu <i>Breakpoint</i> you find commands to set, clear, disable,
and enable permanent and temporary breakpoints. You can display a list
of breakpoints in the <a href="breakptlist.html">breakpoints window</a>.
You can also set a breakpoint by clicking at the left end of the source
line (using the left mouse button), and you can enable and disable a breakpoint
by clicking it using the middle mouse button.</p>
<p>The animation in the toolbar indicates whether the program
is running. It stops when the program stopped in a breakpoint or for
some other reason or when the program exited. This animated button is a shortcut
for <i>Execution|Break</i>.</p>
<h2>
<a name="InfoWindows"></a>KDbg's information windows</h2>
<p>KDbg displays information and accepts commands in number of different windows.
In the menu <i>View</i> you find commands to show and hide these windows.
They are docking windows, which means that you can drag them around and
arrange them in any manner you like.</p>
<ul>
<li>
<a href="sourcecode.html">The source code window</a></li>
<li>
<a href="localvars.html">The local variables window</a></li>
<li>
<a href="stack.html">The stack window</a></li>
<li>
<a href="watches.html">The watched expressions window</a></li>
<li>
<a href="breakptlist.html">The breakpoint list</a></li>
<li>
<a href="pgmoutput.html">The output window</a></li>
<li>
<a href="registers.html">The register dump window</a></li>
<li>
<a href="memory.html">The memory dump window</a></li>
<li>
<a href="threads.html">The threads window</a></li>
</ul>
<h2>
<a name="Tips"></a>Tips and such</h2>
<p>The following topics give some useful hints on using KDbg.</p>
<ul>
<li>
<a href="tips.html">Tips and Tricks</a></li>
<li>
<a href="howdoi.html">How do I...?</a></li>
</ul>
<h2>
<a name="Author"></a>Author</h2>
<p>KDbg is written by <a href="mailto:j6t@kdbg.org">Johannes Sixt</a>
with contributions from these people (in no particular order):</p>
<ul>
<li>Keith Isdale</li>
<li>Ben Burton</li>
<li>Daniel Thor Kristjansson</li>
<li>Matthew Allen</li>
<li>Ron Lerech</li>
<li>Neil Butterworth</li>
<li>Thomas Sparr</li>
<li>Max Judin</li>
<li>Johnny Chan</li>
<li>Ilmar S. Habibulin</li>
</ul>
<p>KDbg homepage is at <a href="http://www.kdbg.org/">http://www.kdbg.org/</a>.</p>
</body>
</html>

View file

@ -0,0 +1,35 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Invocation</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>Invoking KDbg from the command line</h1>
<p><pre>
Usage: kdbg [Qt-options] [KDE-options] [options] [program] [core]
Generic options:
--help Show help about options
--help-qt Show Qt specific options
--help-kde Show KDE specific options
--help-all Show all options
--author Show author information
-v, --version Show version information
--license Show license information
-- End of options
Options:
-t &lt;file&gt; transcript of conversation with the debugger
-r &lt;device&gt; remote debugging via &lt;device&gt;
-l &lt;language&gt; specify language: C, XSLT []
-a &lt;args&gt; specify arguments of debugged executable
-p &lt;pid&gt; specify PID of process to debug
Arguments:
program path of executable to debug
core a core file to use
</pre></p></body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Local Variables</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Local Variables Window</h1>
<p>The local variables window is opened using <i>View|Locals</i>. The local
variables window displays the contents of the local variables at the currently
selected stack frame.</p>
<p>The set of local variables that are displayed is determined by the stack
frame that is selected in the <A href="stack.html">stack window</A>.</p>
<p>Variable values that changed between stops of the program are displayed
in red color.</p>
<p>The values of most variables can be changed. For this purpose, press F2
while the input focus is in the window or choose <i>Edit value</i> from the
context menu. Then edit the value and hit Enter. Note that you cannot modify
the strings that <tt>char*</tt> values point to in this way, just the pointer
value.</p>
<p>Using the context menu you can move
the active variable or structure member to the <a href="watches.html">watched
expressions window</a>.</p>
</body>
</html>

View file

@ -0,0 +1,26 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Memory Dump</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Memory Dump Window</h1>
<p>The memory dump window is displayed using <i>View|Memory</i>. It displays
the contents of the program's memory at arbitrary adresses.</p>
<p>To display memory contents, enter an address in the edit field. The
address need not be given in hexadecimal form - it can be an expression.</p>
<p>You can specifiy a format how the memory contents shall be displayed
by chooseing the appropriate options from the popup menu that you invoke
by clicking the right mouse button.</p>
<p>A number of address expressions are remembered. You can recall such
an expression from the drop-down list. Please note that the address expression
is remembered together with the format.</p>
<p>If you don't need to investigate memory contents, it is recommended
that you clear the expression so that no memory dump is displayed - this
speeds up the debugging process.</p>
</body>
</html>

View file

@ -0,0 +1,46 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Program Output</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Program Output Window</h1>
<p>The program output window is displayed using <i>View|Output</i>. The output
window captures text that is written to stdout and stderr by the program
being debugged.</p>
<p>The output window does not allow to type input for the program and it
features only minimal terminal emulation: <tt>\n</tt> (line-feed),
<tt>\t</tt> (horizontal tab), and <tt>\r</tt> (carriage-return)
are treated. These capabilities are usually sufficient to debug GUI programs
which only write debugging output to stdout and stderr.</p>
<p>When a program is debugged with KDbg for the first time, the program
output window is <em>not</em> used. The reason for this is that KDbg cannot
know whether the program requires sophisticated terminal emulation or if
it expects input through a terminal. So, a terminal emulator program is
used by default. In order to redirect the output to the output window,
you must do the following:</p>
<ol>
<li>
Open the <a href="pgmsettings.html">Settings dialog</a> by selecting <i>Settings|This Program</i>.</li>
<li>
Switch to the <i>Output</i> tab.</li>
<li>
Choose <i>Only output, simple terminal emulation</i> and click <i>OK</i>.</li>
<li>
Reload the program by selecting it from the list in <i>File|Recent Executables</i>.</li>
</ol>
<p>You can clear the contents of the output window by selecting <i>Clear</i>
from the popup menu that appears when you click the right mouse button.</p>
<p>If the last line of the output is visible, the window always scrolls
automatically so that the last line remains visible when new output arrives.
If, however, you manually scroll up so that the last line is not visible,
the visible portion of text will not change.</p>
</body>
</html>

View file

@ -0,0 +1,75 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Program Settings</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Program Settings Dialog</h1>
<p>In this dialog, program specific settings can be selected. It is invoked
by <i>Settings|This Program</i>. The settings apply only to the currently loaded
executable and will be saved across sessions.</p>
<blockquote><b><i>Important note:</i></b> The chosen settings will only
apply the next time the executable is loaded into KDbg. This means that
after pressing
<i>OK</i> in this dialog, you must reload the executable
using <i>File|Recent Executables</i>!!</blockquote>
<ul>
<li>
<a href="#driver">Debugger</a></li>
<li>
<a href="#output">Output</a></li>
</ul>
<h2>
<a name="driver"></a>Debugger</h2>
<p>In this section, the debugger to be used for the program can be chosen.</p>
<h4>
How to invoke GDB</h4>
<blockquote>Enter the command to invoke gdb. Leave this field empty to
use the default gdb command as specified in the <a href="globaloptions.html">global
options</a>. When you are cross-compiling and remote-debugging, you will
probably want to use a different gdb suitable for the target platform.
The default command is <tt>gdb --fullname --nx</tt>. Be sure to specify
at least <tt>--fullname</tt> if you change the gdb command.
If you remove this command switch, KDbg will not work.
</blockquote>
<h2>
<a name="output"></a>Output</h2>
<p>In this section, the terminal emulation under which the program will run
can be selected.</p>
<h4>
No input and output</h4>
<blockquote>Check this option if your program does not receive input from
the terminal and you do not want to see the output that the program writes
to <tt>stdout</tt> and <tt>stderr</tt> (if any). All three standard channels
(<tt>stdin</tt>, <tt>stdout</tt>, and <tt>stderr</tt>) are effectively
redirected to <tt>/dev/null</tt>.</blockquote>
<h4>
Only output, simple terminal emulation</h4>
<blockquote>Check this option if your program does not receive input from
the terminal (<tt>stdin</tt> will be redirected to <tt>/dev/null</tt>),
and the output that it writes to <tt>stdout</tt> and <tt>stderr</tt> does
not require sophisticated terminal emulation. The output will be shown
in the <a href="pgmoutput.html">Output window</a>.</blockquote>
<h4>
Full terminal emulation</h4>
<blockquote>Check this option if your program reads input from <tt>stdin</tt>
or if the output to <tt>stdout</tt> or <tt>stderr</tt> requires terminal
emulation. A terminal emulator will be invoked as specified in the <a href="globaloptions.html">global
options</a>.</blockquote>
</body>
</html>

View file

@ -0,0 +1,35 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Register Dump</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Register Dump Window</h1>
<p>Whenever the program stops, KDbg displays the contents of the CPU registers
in the register dump window. To display this window, choose <i>View|Registers</i>.</p>
<p>The registers are grouped by the kind of register. The window contains 3 columns:</p>
<ol>
<li>
The column <i>Register</i> displays the register name.</li>
<li>
The column <i>Value</i> displays the contents of the registers in a more
or less raw form. The raw form is usually displayed as hexadecimal numbers,
even the contents of floating point registers.</li>
<li>
The column <i>Decoded value</i> displays the contents of the registers
in a decoded form. For arithmetic registers this is generally a signed
decimal value, floating point registers are displayed as floating point
numbers, the flag registers are sometimes decoded into named flags.</li>
</ol>
<p>By clicking the right mouse button a context menu is popped up which lets
you select how the value in the third column is displayed.
You can change the type to use for all registers of a group at once if you
choose the format for the group header.</p>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Source Code</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Source Code Window</h1>
<p>The source code window is the main window and is always visible.</p>
<p>The source code window displays program source code. At the left of
each source line is an "active area". It displays a pointer to indicate
which source line the program currently executes, and it indicates on which
source lines breakpoints have been set.</p>
<p>New breakpoints can be set by clicking into the active area with the
left mouse button. An existing breakpoint can be enabled and disabled by
clicking with the middle mouse button.</p>
<p>The tiny plus '+' between the "active area" and the source line can
be clicked on. If you do so, the source line's assembler code will be displayed.
The plus turns into a minus '-', which, if clicked, will hide the disassembled
code.</p>
<p>Mostly, source code windows are opened automatically. To open a new
source file manually, click the right mouse button and choose <i>Open Source</i>
or choose <i>File|Open Source</i>.</p>
</body>
</html>

View file

@ -0,0 +1,23 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Stack</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Stack Window</h1>
<p>The stack window is displayed using <i>View|Stack</i>. The stack window
lists the stack frames, i.e. the functions that the program has entered,
but not yet left.</p>
<p>The innermost frame (where the program currently executes) is shown
at the top.</p>
<p>To switch to a different stack frame, simply click on that stack frame.
The <a href="sourcecode.html">source window</a> displays the source line
where the function invocation took place and the <a href="localvars.html">local
variables window</a> and the <a href="watches.html">watch window</a> change
to reflect the local variables of the selected stack frame.</p>
</body>
</html>

View file

@ -0,0 +1,42 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Threads</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Threads Window</h1>
<p>The threads window is displayed using <i>View|Threads</i>. The threads
window lists the active threads of the program.</p>
<p><b><i>Note:</i></b> Debugging threaded programs must be supported by
the version of gdb that is used - it is not a feature of KDbg. For Linux
systems this works best with gdb5 and later. However, at the time of this writing gdb
still poorly supports threads on NPTL- (New Posix Threads Library) enabled
systems (glibc 2.3.x and kernel 2.6.x).</p>
<p>The contents of the threads window are updated every time the program
is stopped by the debugger. (That is, the window does <em>not</em> reflect
the state while the program is running.)</p>
<p>The first column shows the thread ID, the second column identifies the
location where the thread currently executes.</p>
<p>The marker in front of the line tells which thread currently is <em>active</em>:</p>
<ul>
<li>
The <a href="stack.html">stack window</a> displays the active threads's
backtrace.</li>
<li>
The <a href="localvars.html">local variables</a> window displays the active
thread's local variables.</li>
<li>
The <a href="watches.html">watch window</a> uses the active thread's local
variables to evaluate the expressions.</li>
</ul>
<p>By clicking a listed thread, the active thread is switched, and the corresponding
windows are updated. In particular, the <a href="sourcecode.html">source
window</a> displays the location where the active thread is currently halted.</p>
</body>
</html>

View file

@ -0,0 +1,47 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Tips and Tricks</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
Tips and Tricks</h1>
<ul>
<li>
You can use breakpoints as bookmarks: Just set a breakpoint and disable
it. Later, you can quickly come back to that breakpoint by double-clicking
it in the breakpoint list (or select it and click <i>View Code</i>). Since
breakpoints are persistent (i.e. KDbg remembers them across invocations
of a program), you get them back next time you invoke KDbg for that particular
program.</li>
<li>
You can display a value in the watch section in different ways by prepending
gdb's format specifiers in front of the variable to display. E.g. <tt>/x
var.member</tt> displays the <tt>var.member</tt> in hexadecimal notation.</li>
<li>
You can set breakpoints in a source files that belong to a shared library.
Such breakpoints will be marked as <em>orphaned</em> if the program is not active.
<A href="breakptlist.html#orphanedbp">Orphaned breakpoints</A> are not effective.
In order to make them effective, the program must stop at a time when the shared
library is loaded. For this it is usually sufficient to set a breakpoint in
<tt>main()</tt>. At the time when this breakpoint is hit, the orphaned breakpoints
in the shared library become effective.</li>
<li>
Debugging multi-threaded programs on NPTL-enabled Linux systems (kernel 2.6.x
or later and glibc 2.3.x or later) may sometimes fails; gdb stops the program
at unexpected instances. In this case the following may help (using bash):
<pre>
LD_ASSUME_KERNEL=2.4.19 kdbg myprogram
</pre>I.e. you run KDbg from the command line such that the old
Linuxthreads implementation is used.</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,183 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Type Tables</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
KDbg's Type Table</h1>
<p>KDbg can display a short description of structured types, so
that it is not necessary to expand the variable in the <a href="localvars.html">local
variables window</a> or <a href="watches.html">watched expressions window</a>.
The information which member variable is displayed is stored in <em>type
tables</em>. There is generally one type table per shared library.</p>
<p>KDbg's default type tables are located under <tt>$prefix/share/apps/kdbg/types</tt>.
User defined type tables can be placed in <tt>${KDEHOME}/share/apps/kdbg/types</tt>, where
<tt>${KDEHOME}</tt> is <tt>~/.kde</tt> if it is not a defined environment variable.
The file names end with <tt>.kdbgtt</tt>. Example: The type table for <tt>libqt.so</tt>
is named <tt>qt.kdbgtt</tt>.
User defined type tables override the type tables provided by the system.</p>
<p>A type table file obeys the regular KDE configuration file syntax. The
file has the following groups:</p>
<ul>
<li>
A group <tt>[Type Table]</tt> which lists the types and information how
the debugger can identify whether the program is linked against the library.</li>
<li>
A group for each type which has information about how the value of such
a type is displayed by KDbg.</li>
</ul>
<p>In order to determine which type tables apply to the program being debugged
KDbg lists the shared libraries it is linked to. Then it matches the names
against the <tt>ShlibRE</tt> entries of all type tables. Those that match
are used. If a type appears in several type tables, it is unspecified which
one will be used.</p>
<p>KDbg's type recognition only works for libraries that are linked dynamically
to the program being debugged.</p>
<h2>
The <tt>[Type Table]</tt> group</h2>
<p>This group contains the following entries:</p>
<ul>
<li>
<tt>Types1</tt>, <tt>Types2</tt>, etc. These entries name the types,
separated by commas.
Each of the entries can list any number of types. The entries must be numbered
consecutively (KDbg stops reading at the first gap), although an entry may be
empty (i.e. contain no type at all).
Sometimes the order in which the names are listed is important
(see <tt>Alias</tt> types below).</li>
<li>
<tt>ShlibRE</tt>. KDbg uses this entry to determine if the type table applies
to the program being debugged. For this purpose KDbg determines the shared
libraries to which the program is linked. If any of the libraries matches
this entry, the type table applies. The entry is a <a href="http://doc.trolltech.com/4.0/qregexp.html#introduction">Qt regular
expression</a>.
Note that back-slashes must be doubled because the back-slash is an escape
character in the configuration file syntax.</li>
<li>
<tt>LibDisplayName</tt>. This entry is used in lists where the available
type tables are listed to identify this type table.
<br><font size=-1>This is not used currently.</font></li>
<li>
<tt>EnableBuiltin</tt> lists extensions that must be enabled if this
library is used. Currently, two builtins are supported:
<ul>
<li>
<tt>QString::Data</tt> is used to display unicode strings of Qt's <tt>QString</tt>
class. See below.</li>
<li><tt>QCharIsShort</tt> is used only in connection with <tt>QString::Data</tt>
to specify that a unicode character is stored in an object of type <tt>short</tt>.
See <tt>qt3.kdbgtt</tt> for examples.</li></ul></li>
</ul>
<p>In the case of regular types the names of types should follow the output of the
<tt>whatis</tt> gdb command less any <tt>const</tt>, <i>spaces</i>, or trailing
<tt>&</tt>.
If the type contains a a comma in its name, it must be escaped with a backslash.
But note that the comma should not be escaped in the type's group (which is described
in the next section).
</p>
<p>In the case of template types the name can be arbitrary because the type's group
will mention the template name and a type parameter list.</p>
<h2>
The type's group</h2>
<p>There is one group for each type that is named exactly as the type.
Each group contains the following entries:</p>
<ul>
<li>An optional <tt>Template</tt> entry that specifies the exact template type
name as it is reported by gdb's <tt>whatis</tt> command. However, it is
possible to replace template parameter types at the top-most level by an
asterisk&nbsp;<tt>*</tt>, which acts as a wildcard: It matches <b>one</b>
template type argument that is reported by <tt>whatis</tt> (except that an
asterisk in the last position matches all remaining template type arguments).
</li>
<li>
<tt>Display</tt> determines how the value of the type is displayed by KDbg.
The string must contain 1 to 5 percent characters '<tt>%</tt>'. These are
replaced by the results of the expressions printed by the <tt>Expr</tt><i>x</i>
entries.</li>
<li>
One or more of <tt>Expr1</tt>, <tt>Expr2</tt>, etc. Each of them must contain
one or more <tt>%s</tt> sequence, which will be replaced by the expression
whose value is investigated. The so constructed expression is submitted
to gdb, and the result substituted back for the corresponding percent character
in the <tt>Display</tt> string.</li>
<li>
An optional <tt>FunctionGuard</tt><i>x</i> that is associated with the corresponding <tt>Expr</tt><i>x</i>.
If the evaluation of the resulting gdb expression returns an error, the corresponding expression from <tt>Expr</tt><i>x</i> is not evaluated. (This is used to guard function calls.)
<li>
<tt>Alias</tt> names an alias type. If this entry is present, the type
is treated like the specified type. That alias type must appear before
this type in the <tt>Types</tt><i>x</i> entries in the <tt>Type Table</tt>.</li>
</ul>
<p><font size=-1>Currently the number of expressions per type is limited to
5. This can easily be changed if it's too restrictive, but I recommend
not to go to that limit at all - it will slow down the debugging process.</font></p>
<p>KDbg recognizes a special extension that is used to display Qt 2.x's and Qt 3.x's
unicode strings: If an <tt>Expr</tt><i>x</i> is prepended with <tt>/QString::Data</tt>,
it is assumed that the result of the expression is a pointer to a <tt>QString::Data</tt>.
The value displayed is the unicode string that this instance of <tt>QString::Data</tt>
represents (which can be <tt>QString::null</tt> if it is Qt's well-defined
null string or <tt>(null)</tt> if the <tt>unicode</tt> member is the null
pointer). See <tt>qt2.kdbgtt</tt> for examples.</p>
<p>Tip: It is not necessary to define derived types if they ought to be
treated the same as the base class - KDbg can deduce derived types and
uses the type specification of the (leftmost) base class. You can use the
<tt>Alias</tt>
entry to quickly specify that a type should be treated like a non-leftmost
base class for a multiple-inheritance class.</p>
<h2>
An example</h2>
<p>The example shows how <tt>QString</tt> and <tt>QRect</tt> are defined
in <tt>qt3.kdbgtt</tt>. Furthermore, the template type <tt>QValueVector</tt>
is defined. This example applies to Qt 3.x, which is located in shared library
whose name ends in <tt>libqt-mt.so.3</tt>.</p>
<pre>[Type Table]
Types1=QString,QRect
Types2=QValueVector
LibDisplayName=libqt 3.x
ShlibRE=libqt-mt\\.so\\.3$
EnableBuiltin=QString::Data,QCharIsShort
[QString]
Display={ % }
Expr1=/QString::Data (%s).d
[QValueVector]
Template=QValueVector<*>
Display={ size=% shared=% capacity=% }
Expr1=($tmp=(%s).sh)->finish-$tmp->start
Expr2=(%s).sh->count
Expr3=($tmp=(%s).sh)->end-$tmp->start
[QRect]
Display={ tl=(%,%) br=(%,%) }
Expr1=(%s).x1
Expr2=(%s).y1
Expr3=(%s).x2
Expr4=(%s).y2</pre>
<p>This example shows these features:</p>
<ul>
<li>The name of the template type, <tt>QValueVector</tt> is irrelevant.
The exact type name is specified under the <tt>Template=</tt> entry.
It specifies a single wildcard so that it applies to all specializations.
</li>
<li>In order to evaluate the expression that was supplied in the <tt>%s</tt>
only once, the result is stored in a temporary gdb variable and reused later in
the same expression.</li>
<li>Note that it is safer to wrap the <tt>%s</tt> in parentheses.</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Watched Expressions</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>
The Watched Expressions Window</h1>
<p>The watched expressions window is opened using <i>View|Watched Expressions</i>.
It displays arbitrary expressions.</p>
<p>To add an expression, type it into the edit field and press Enter or
click <i>Add</i>. To remove an expression, click on it (choose the root
of the expression) and click <i>Del</i>.</p>
<p>You can also move a variable or structure member from the <a href="localvars.html">local
variables window</a> to this window using the context menu in the local
variables window.</p>
<p>The values of most expressions can be changed. For this purpose, press F2
while the input focus is in the window. Then edit the value and hit Enter.
Note that you cannot modify the strings that <tt>char*</tt> values point
to in this way, just the pointer value.</p>
<p>Watched expressions are stored across debugging sessions. It is recommended
that you remove expressions that your don't need any longer because that
speeds up the debugging process.</p>
</body>
</html>

View file

@ -0,0 +1,24 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - User's Manual - Debugging XSLT scripts</title>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><a href="index.html">Contents</a></p>
<h1>Debugging XSLT scripts</h1>
<p>KDbg allows to debug XSLT (XML stylesheet translation) scripts using
<a href="http://xsldbg.sourceforge.net/">xsldbg</a>, which must be available
on your system.</p>
<h2>Specifying the script and an XML file to transform</h2>
<p>XSLT mode is automatically entered if a &quot;program&quot; is loaded
that has a file name that ends in <tt>.xsl</tt>. In addition, the
<A href="invocation.html">command line option</A> <tt>-l XSL</tt> can be
specified to explicitly choose this mode.</p>
<p>To debug an XSLT script it is necessary to specify an XML data file
that the script can transform. This is done in the
<a href="argspwdenv.html">Program Arguments</a> dialog, where the XML
file is specified in the <em>Program Arguments</em> edit box.</p>
</body>
</html>

1
kdbg-2.5.5/kdbg/doc/ru/.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
*.html encoding=koi8-r

View file

@ -0,0 +1,17 @@
install(FILES
argspwdenv.html
breakptlist.html
globaloptions.html
howdoi.html
localvars.html
memory.html
pgmoutput.html
pgmsettings.html
registers.html
sourcecode.html
stack.html
threads.html
tips.html
watches.html
index.html
DESTINATION ${HTML_INSTALL_DIR}/ru/kdbg)

View file

@ -0,0 +1,43 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Аргументы, Окружение</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Указание аргументов программы, рабочего каталога, переменные окружения</h1>
Выберите пункт меню <i>Исполнение|Аргументы</i> для вызова диалогового окна, в
котором вы сможете установить аргументы отлаживаемой программы, ее рабочий
каталог и переменные окружения.
<h2>
<a NAME="PgmArgs"></a>Аргументы программ</h2>
В самой верхней строке ввода укажите аргументы командной строки, которые должны
быть переданы программе. Эти аргументы будут использованы при следующием
запуске программы.
<h2>
<a NAME="WorkingDir"></a>Рабочий каталог</h2>
Ниже расположена строка ввода, в которой вы можете указать рабочий каталог
программы. Программа будет работать в указанном каталоге при следующем запуске.
<p>Рабочий каталог также действует и для gdb! Указанный вами каталог будет
немедленно передан gdb и вступит в силу как только вы нажмете <i>OK</i>. Это
может повлиять на поиск файлов исходных текстов.
<h2>
<a NAME="Environment"></a>Переменные окружения</h2>
В секции переменных окружения введите выражение в виде <tt>VARIABLE=value</tt>
для установки переменной окружения <tt>VARIABLE</tt> в значение <tt>value</tt>
и кликните на кнопку <i>Изменить</i>. Для удаления переменной, выберите ее в
списке и кликните на кнопку <i>Удалить</i>. Для изменения значения переменной,
выберите ее из списка, отредактируйте ее значение в поле редактирования и
кликните по кнопке <i>Изменить</i>. Если вы измените имя переменной и кликните
по кнопке <i>Изменить</i>, то вы добавите новую переменную! Новые переменные
окружения будут использованы вашей программой при следующем запуске.
<p>Если в Linux вы используете библиотеку glibc2, то вам необходимо установить
переменную окружения <tt>LD_BIND_NOW</tt>. Очень важно, чтобы вы установили
значение этой переменной в <tt>1</tt> для всех сессий отладки. Если она не
будет установлена, то gdb не сможет осуществлять пошаговую отладку (в и из)
системных функций, импортируемых из разделяемых библиотек <tt>libc</tt> и
остальных.
</body>
</html>

View file

@ -0,0 +1,68 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Список точек останова</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Список точек останова</h1>
Список точек останова отображает все установленные точки останова и просмотра и
позволяет манипулировать ими. Он может быть вызван посредством пункта меню
<i>Вид|Точки останова</i>.
<h2>Перечень точек останова</h2>
Для каждой точки останова отображается следующее:
<ul>
<li>местонахождение точки останова,</li>
<li>счетчик остановок на этой точке,</li>
<li>счетчик пропусков точки останова, если указан,</li>
<li>условие останова, если указно.</li>
</ul>
Иконка напротив записи указаывает состояние точки останова: включена - красная
точка, выключена - светло-красная точка, временная точка останова - маленькие
часы или условная точка останова - маленький знак вопроса.
<p>Точки просмотра обозначаются иконкой лупы напротив соответствующей записи.
<h2>Управление точками останова</h2>
<a NAME="StopProg"></a>Необходимо отметить, что точками останова и просмотра
невозможно управлять во время работы программы. Если программа уже запущена,
необходимо, чтобы она остановилась либо попав в точку останова, либо
принудительно посредством вызова пункта меню <i>Исполнение|Прервать</i>.
Это не завершит исполнение программы, а всего лишь остановит ее. Теперь вы
можете управлять точками останва, после чего выберите пункт
<i>Исполнение|Продолжить</i> для продолжения исполнения программы.
<p>Для установки точки останова на определенную строку исходного текста самым
простым способом является установка ее в окне исходных текстов. Если вы не
знаете имени файла и номера строки, где находится интересующая вас функция, вы
просто можете ввести ее имя в строке ввода над списком и кликнуть на кнопку
<i>Добавить Точку Останова</i>.
<p>Вы можете включать и выключать точки останова, выбрав их в списке, а затем
кликнув на кнопки <i>Включить</i> или <i>Выключить</i>. Или просто кликните
средней кнопкой мыши по нужному элементу списка - вы будете включать и
выключать их так же, как и в окне исходных текстов.
<p>Вы можете установить условие срабатывания точки останова или установить
счетчик пропусков этой точки, показывающий количество проходов, при которых не
будет произведен останов. Для этого кликните на кнопку <i>Условия</i> и введите
условие и/или счетчик пропусков.
<h2>Управление точками просмотра</h2>
Точки просмотра похожи на точки останова, за исключением того, что прерывание
происходит только при изменении значения содержимого памяти. Также как и точки
останова, точками просмотра нельзя управлять во время исполнения программы.
Подробнее см. <a href="#StopProg">выше</a>.
<p>Для установки точки просмотра, введите выражение в строку ввода над списком
и кликните на кнопку <i>Добавить Точку Просмотра</i>. Программа остановится при
изменении значения выражения. Необходимо отметить, что точки просмотра,
использующие локальные переменные, могут быть установлены только когда
программа прервана в точке останова (или принудительно посредством вызова
пункта меню <i>Исполнение|Прервать</i>).
<p>Для удаления точки просмотра, выберите ее из списка и кликните на кнопку
<i>Удалить</i>. Если выражение использует локальные переменные, то точка
просмотра будет удалена автоматически при выходе программы из данной области
стека (функции).
<p>Вы также можете установить для точек просмотра условия и счетчик пропусков,
выбрав его из списка и кликнув на кнопку <i>Условия</i>.
</body>
</html>

View file

@ -0,0 +1,72 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство пользователя - Глобальные Переменные</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Солдержание</a>
<h1>
Далоговое окно Глобальных Переменных</h1>
Для установки некоторых глобальных переменных можно использовать
<i>Файл|Глобальные Переменные</i>. Вы можете установить:
<ul>
<li>
команду, с помощью которой вызывается gdb,</li>
<li>
команду, которая открывает терминал для вывода программы,</li>
<li>
должен ли KDbg переходить в обыкновенный режим после остановки программы и
через какой промежуток времени он опять перейдет в фоновый режим,</li>
<li>
размер табуляции.</li>
</ul>
<h4>
Как вызывать gdb</h4>
<blockquote>Если вы используете различные версии gdb, нужно указать
их в <i>Как вызывать gdb</i>. По умолчанию используется
форма <tt>gdb --fullname
--nx</tt>. Проверьте, указаны ли данные опции,
если вы изменили исполняемый модуль gdb. Если вы пропустите их, KDbg не
будет работать. Если вы испортили запись, ее можно очистить, переведя
в значения по умолчанию.</blockquote>
<h4>
Как вызвать эмулятор терминала</h4>
<blockquote>Если вы хотите испотльзовать различные терминальные программы
для показа вывода программы, укажите их в
<i>Терминалы для вывода программ</i>. Значение по умолчанию &#150;
<tt>xterm -name kdbgio -title %T -e sh -c %C</tt>.
В данной записи,
<tt>%T</tt> заменяется титульной строкой, <tt>%C</tt>
заменяется скриптом командного интерпретатора Борна, который будет циклически
вызываться, пока не произойдет закрытия терминального окна.
(Скрипт использует в цикле <tt>sleep
3600</tt>). Альтернави\ой данных установок может служить
<tt>konsole --name kdbgio --caption %T -e sh -c %C</tt>.</blockquote>
<h4>
Переход в обычный режим</h4>
<blockquote>Вы можете указать KDbg окну перевестись в обычный режим,
когда отлаживаемая программа завершится (в точке останова или по сигналу).
Иначе окно KDbg не активируется (по крайней мере в KWM &150; оконном менеджере
KDE). Некоторым пользователям такое поведение может показатся навязчивым,
поэтому по умолчанию данная опция отключена.
</blockquote>
<blockquote>Если опция включена, KDbg переключится в фоновый режим, если
программа будет продолжена, но только по прошествии заданного временного
промежутка. Это сделано для того, чтобы окно отладчика не переключалось
все время, когда используется пошаговое исполнение программы.
</blockquote>
</body>
</html>

View file

@ -0,0 +1,78 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство пользователя - Как я могу...?</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>
Как я могу...?</h1>
<h4>
... установить точки останова?</h4>
Существует несколько способов:
<ul>
<li>Нажатием левой клавиши мыши в окне исходного текста в "активной области",
находящейся слева от строки исходного текста.</li>
<li>Выбрать строку в окне исходного текста и выбрать опцию
меню <i>Точки останова</i>.</li>
<li>Вы можете воспользоватся <a href="breakptlist.html">списком точек останова</a>.</li>
</ul>
Если вы не можете установить точки останова, возможно программа работает
в данный момент. Когда программа работает, установка точек останова невозможна.
Остановите программу с помощью <i>Выполнение|Прервать</i>. Если
вы по-прежнему не можете установить точку останова, проверьте, скомпилирована
<i>и собрана</i> ли ваша программа с поддержкой информации для отладки.
<h4>... установить значение глобальной переменной или какого-либо выражения?</h4>
Используйте окно Просмотра.
<h4>
... установить точку просмотра?</h4>
Точки просмотра устанавливаются в <a href="breakptlist.html">списке
точек останова</a>.
<h4>
... использовать дамп памяти?</h4>
Сначала необходимо загрузить исполняемый модуль, используя меню
<i>Файл|Исполняемый модуль</i>, затем указать соответствующий дамп памяти,
используя <i>Файл|Дамп Памяти</i>.
<h4>
... отлаживать программу, содержащую бесконечный цикл?</h4>
Запустите программу и подождите, пока она войдет в бесконечный цикл.
Переключитесь в KDbg и выберите <i>Выполнение|Прервать</i>.
Далее можно использовать отладочные средства.
<h4>
... сделать так, чтобы программа определенное количество раз игнорировала
точку останова во время прохода до того, как начнет прерываться?</h4>
В <a href="breakptlist.html">списке точек останова</a> выберите точку
останова; нажмите <i>Условная</i> и укажите количество раз для пропуска
точки останова в поле <i>Число пропусков</i>.
<h4>
... установить переменную среды для исполнемого модуля?</h4>
Выберите <i>Выполнение|Аргументы</i> и укажите переменные среды в
<a href="argspwdenv.html#Environment">диалоге аргументов программы</a>.
<h4>
... установить рабочий каталог для исполняемого модуля?</h4>
Выберите <i>Выполнение|Аргументы</i> и укажите рабочий каталог в
<a href="argspwdenv.html#WorkingDir">диалоге ургументов программы</a>.
<h4>
... избавиться от терминального окна?</h4>
Выберите <i>Файл|Настройки</i> и перейдите на меню
<a href="pgmsettings.html#output">Вывод</a>.
Выберите <i>Только вывод, простая эмуляция терминала</i> и нажмите
<i>OK</i>.
Теперь перезапустите программу (выберите ее из списка
<i>Файл|Последний исполняемый модуль</i>). Вывод программы теперь перенаправлен
в созданное <a href="pgmoutput.html">окно вывода</a>, а в качестве
стандартного потока ввода используется <tt>/dev/null</tt>.
<p>Вы должны произвести данную операцию для каждой новой отлаживаемой
программы.
<p><b><i>Важно:</i></b>Вы не должны делать этого, если программа
читает данные со стандартного потока ввода (обычно терминала) или
ее вывод требует более интеллектуальной эмуляции терминала (то есть
не только возврата каретки и прогона строки). Окно вывода не
поддерживает ввод и эмуляцию терминала.
</body>
</html>

View file

@ -0,0 +1,177 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<h1>KDbg - Руководство пользователя</h1>
<h2>Содержание</h2>
<ul>
<li>
<a href="#Introduction">Введение</a></li>
<li>
<a href="#UsingKDbg">Использование KDbg</a></li>
<li>
<a href="#InfoWindows">Информационные окна KDbg</a></li>
<li>
<a href="#Tips">Советы и пр.</a></li>
<li>Для опытных пользователей: <a href="types.html">Таблицы типов</a></li>
<li>
<a href="#KnownProblems">Известные проблемы</a></li>
<li>
<a href="#Author">Автор</a></li>
</ul>
<hr>
<h2>
<a NAME="Introduction"></a>Введение</h2>
KDbg является графическим интерфейсом к <tt>gdb</tt>, отладчиком проекта GNU.
<p>Это означает, что KDbg сам по себе не является отладчиком. Скорее, он
общается с <tt>gdb</tt>, отладчиком, использующим командную строку, посылая ему
команды и получая их результат, например, значения переменных. Пункты меню и
указания мышью преобразуются в последовательность команд <tt>gdb</tt>, а
результат преобразуется к более-менее визуальному представлению, такому как
структурное содержимое переменных.
<p>Обобщение выше сказанного - KDbg целиком зависит от возможностей
используемого отладчика <tt>gdb</tt>. KDbg не может делать больше, чем делает
<tt>gdb</tt>. Например, если имеющаяся у вас версия <tt>gdb</tt> не
поддерживает отладку многопоточных программ, то и KDbg не поможет вам в этом
(несмотря на то, что он выводит окно потоков).
<h2>
<a NAME="UsingKDbg"></a>Использование KDbg</h2>
Перед началом использования KDbg вы наверное захотите просмотреть опции в
диалоге <a href="globaloptions.html">Глобальные Опции</a>, который можно
вызвать из пункта меню <i>Файл|Глобальные Опции</i>.
<h4>Указание отлаживаемой программы</h4>
Для отладки программы выберите пункт меню <i>Файл|Исполняемые модули</i>. Если
вы ранее отлаживали эту программу, вы можете выбрать ее из пункта
<i>Файл|Последние Исполняемые Модули</i>. Программа загрузится.
<p>Если вы хотите произвести отладку по дампу памяти, то сначала вы должны
загрузить программу, породившую этот дамп, а потом загрузить сам дамп, выбрав
пункт меню <i>Файл|Дамп Памяти</i>. Теперь KDbg перейдет в ту точку программы,
которая вызвала создание дампа памяти.
<p>Теперь вы можете устанавливать точки останова, ипользуя меню
<i>Breakpoint</i>, меню, вызваемое правой кнопкой мышы, или
<a href="breakptlist.html">окно точек останова</a>.
<p>Также вы можете установить настройки только для отлаживаемой в данный момент
программы в диалоге <a href="pgmsettings.html">Настройки Программы</a>,
вызываемом пунктом меню <i>Файл|Настройки</i>.
<h4>Исполнение программы</h4>
Теперь запустите программу, выбрав пункт меню <i>Исполнение|Запуск</i>. Теперь
программа будет исполняться обычным образом до тех пор, пока она либо не
окончится, либо не попадет в точку останова или точку просмотра, либо не
получит сигнал.
<p>Вы можете запустить программу с аргументами, установить рабочий каталог, а
также переменные окружения для данной программы. Для этого выберите пункт меню
<i>Исполнение|Аргументы</i> и укажите ваши параметры в диалоге
<a href="argspwdenv.html">Аргументы Программы</a> (перед запуском программы).
<p>Вы также можете подключиться к уже работающей программе. Для этого загрузите
исполняемый модуль, как описано выше. Затем выберите пункт меню
<i>Исполнение|Подсоединиться</i>. Укажите идентификатор процесса и кликните на
<i>OK</i>. Работающая программа будет остановлена (но не прервана), а в окне
исходных текстов будет указана текущая точка останова.
<h4>Программа остановлена - что теперь?</h4>
Когда программа останавливается в точке останова, просмотра или при получении
сигнала, в <a href="sourcecode.html">окне исходных текстов</a> указывается
текущая строка остановки программы. Часто встречается ситуация, когда программа
останавливается, получая сигнал (обычно <tt>SIGSEGV</tt>), находясь в функции,
которую вы вызываете из своей программы, но сами не разрабатывали. В этом
случае просмотрите <a href="stack.html">окно стека</a> и найдите функцию,
которую писали вы (начиная с вершины списка) и кликните на нее. Это укажет вам
место, с которого вы сможете начать поиск ошибки в вашей программе.
<p>В меню <i>Исполнение</i> вы найдете команды, которые вам понадобятся для
запуска программы, пошаговой отладке, прерывания исполнения программы
(<i>Прерывание</i>). Важные команды, такие как <i>Запуск</i> и все виды
<i>Шагов</i>, привязаны к функциональным клавишам, которыми рекомендуется
пользоваться для повышения эффективности отладки.
<br><font size=-1>Эти функции не настраиваются, но может вы захотите внести
свой вклад и разработать эту функциональность?</font>
<p>В меню <i>Точки останова</i> вы найдете команды для установки, снятия,
включени и выключения временных и постоянных точек останова. Вы можете вывести
список точек останова в <a href="breakptlist.html">окно точек останова</a>.
Вы также может установить точку останова, кликнув левой кнопкой мыши в левое
поле строки исходного текста. Для включения и выключения точки останова
кликните средней кнопкой мыши на точку останова.
<p>Шестеренка на панели инструментов показывает, что gdb работает, в этом
случае она вертится. Когда она вертится быстро, KDbg не будет принимать
команды исполнения, а если она вращается медленно, то KDbg считывает значения
переменных.
<h2>
<a NAME="InfoWindows"></a>Информационные окна KDbg</h2>
KDbg выводит информацию и принимает команды в различных окнах. В меню
<i>Вид</i> вы обнаружите команды для вызова и закрытия этих окон. Все эти окна
вы можете размещать так, как вам удобно.
<ul>
<li>
<a href="sourcecode.html">Окно исходных текстов</a></li>
<li>
<a href="localvars.html">Окно локальных переменных</a></li>
<li>
<a href="stack.html">Окно стека</a></li>
<li>
<a href="watches.html">Окно отслеживаемых выражений</a></li>
<li>
<a href="breakptlist.html">Список точек останова</a></li>
<li>
<a href="pgmoutput.html">Окно вывода</a></li>
<li>
<a href="registers.html">Окно содержимого регистров</a></li>
<li>
<a href="memory.html">Окно образа памяти</a></li>
<li>
<a href="threads.html">Окно потоков</a></li>
</ul>
<h2>
<a NAME="Tips"></a>Советы и пр.</h2>
Следующие разделы содержат полезные сведения об использовании KDbg.
<ul>
<li>
<a href="tips.html">Полезные Советы</a></li>
<li>
<a href="howdoi.html">Как я могу...?</a></li>
</ul>
<h2>
<a NAME="KnownProblems"></a>Известные проблемы</h2>
gdb 4.16 имеет проблемы с обработкой классов С++ с виртуальным базовым классом.
(Такие классы обычно встречаются в программах, использующих CORBA.) Он
прерывается по ошибке сегментации, а KDbg сообщает о том, что gdb неожиданно
завершился. К сожалению, с этим ничего нельзя сделать. Вам придется
перезапустить gdb, выбрав пункт меню <i>Файл|Исполняемый модуль</i>, который
перезапустит сессию отладки.
<p>Распознавание типов в KDbg работает только для библиотек, динамически
линкуемых с отлаживаемой программой.
<h2>
<a NAME="Author"></a>Автор</h2>
KDbg разработан <a href="mailto:j6t@kdbg.org">Johannes Sixt</a>
с помощью многих остальных.
<br>Домашняя страница KDbg расположена по адресу
<a href="http://www.kdbg.org/">http://www.kdbg.org/</a>.
</body>
</html>

View file

@ -0,0 +1,19 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Локальные Переменные</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Окно Локальных Переменных</h1>
Окно локальных переменных вызывается выбором пункта меню <i>Вид|Локальные</i>.
Данное окно отображает содержимое локальных переменных, определенных
указанной текущей областью стека (stack frame).
<p>Отображаемый набор локальных переменных определяется областью стека (stack
frame), выбранной в окне стека.
<p>Значения переменных, изменивщихся между остановами программы, отображаются
красным цветом.
</body>
</html>

View file

@ -0,0 +1,26 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство пользователя - Образ памяти</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Окно образа памяти</h1>
Чтобы отобразить окно образа памяти нужно выбрать <i>Вид|Память</i>.
Оно выводит содержимое памяти программы по любым адресам.
<p>Для просмотра содержимого памяти, введите нужный адрес в поле редактирования.
Адрес не обязательно должен задаваться в шестнадцатеричной форме и может
задаваться выражением.
<p>Вы можете определить формат отображения содержимого памяти с помощью
выбора соответствующих опций из выпадающего меню, которое вызывается
нажатием правой клавиши мыши.
<p>Адресные выражения запоминаются и впоследствии могут быть
вызваны из выпадающего списка. Обратите внимание, что адресные выражения
запоминаются вместе с их форматом.
<p>Если вы не собираетесь исследовать содержимое памяти, рекомендуется
очистить выражение таким образом, чтобы содержимое памяти не выводилось
&#150; это увеличит скорость процесса отладки.
</body>
</html>

View file

@ -0,0 +1,43 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Вывод Программы</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Окно Вывода Программы</h1>
Окно вывода программы можно вызвать, выбрав пункт меню <i>Вид|Вывод</i>. В это
окно выводятся стандартные потоки вывода и диагностики отлаживаемой программы.
<p>Оно не позволяет вводить какие-либо данные в программу и реализует лишь
минимальную эмуляцию терминала: <tt>\n</tt> (перевод строки) преобразуется в
комбинацию начало строки-перевод строки, а <tt>\r</tt> (начало строки)
игнорируется. Этих возможностей обычно предостаточно для отладки GUI программ,
которые выводят отладочные сообщение в стандартные потоки вывода или
диагностики.
<p>Когда программа отлаживается первый раз, окно вывода программы не
<i>не</i>используется. Ведь KDbg не знает, достаточно ли программе столь
ограниченных возможностей или же она ожидает ввода с терминала. Поэтому по
умолчанию используется штатный эмулятор терминала. Для перенаправления вывода
программы в окно вывода необходимо проделать следующие шаги:
<ol>
<li>
Вызвать диалоговое окно <a href="pgmsettings.html">Настройки</a> посредством
пункта меню <i>Файл|Настройки</i>.</li>
<li>Выбрать закладку <i>Вывод</i>.</li>
<li>Выбрать <i>Только вывод, простой эмулятор терминал</i> и кликнуть на
кнопку <i>OK</i>.</li>
<li>Перезагрузить программу из списка <i>Файл|Последние Исполняемые Модули</i>.</li>
</ol>
Для очистки содержимого окна выберите пункт <i>Очистить</i> в всплывающем меню,
вызываемом нажатием правой кнопки мыши в этом окне.
<p>Если последняя строка окна заполнена текстом, то окно прокручивается
автоматически таким образом, что последняя строка всегда остается видимой при
поступлении новых сообщений. Если вы прокрутите окно, то отображаемая позиция
не изменится.
</body>
</html>

View file

@ -0,0 +1,73 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Настройки Программ</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Диалог Настройки Программ</h1>
В этом диалоге можно указать настройки конкретной программы. Для его вызова
выберите пункт меню <i>Файл|Настройки</i>. Данные настройки будут применены
только к текущей отлаживаемой программе и будут сохранены между сессиями ее
отладки.
<blockquote><b><i>Важное замечание:</i></b> Настройки будут применены только
при следующей загрузке исполняемого модуля в KDbg. Это означает, что после
нажатия на <i>OK</i> вы должны перезагрузить исполняемый модуль с помощью
пункта меню <i>Файл|Исполняемые модули</i>!!</blockquote>
<ul>
<li>
<a href="#driver">Отладчик</a></li>
<li>
<a href="#output">Вывод</a></li>
</ul>
<h2>
<a NAME="driver"></a>Отладчик</h2>
В этом разделе вы можете указать отладчик, которым будете отлаживать программу.
<h4>Как вызвать GDB</h4>
<blockquote>Введите команду для вызова gdb. Оставьте это поле пустым для вызова
gdb по умолчанию, указанного в
<a href="globaloptions.html">глобальных опциях</a>. Если вы занимаетесь
кросс-компиляцией и удаленной отладкой, то вы наверное захотите использовать
другой gdb, более подходящий для конкретной платформы. По умолчанию вызывается
<tt>gdb --fullname --nx</tt>. Не забудьте указать данные опции при изменении
используемого отладчика. Если вы их не укажите, KDbg не будет работать.
</blockquote>
<h2>
<a NAME="output"></a>Вывод</h2>
В этом разделе вы можете указать степень эмуляции терминала, в которой будет
работать программа.
<h4>Нет ввода и вывод</h4>
<blockquote>Отметьте эту опцию, если ваша программа не получает входных данных
с терминал и вы не хотите видеть то, что она выводит в стандартные потоки
вывода и диагностики. Все стандартные потоки (<tt>stdin</tt>, <tt>stdout</tt> и
<tt>stderr</tt>) перенаправляются в <tt>/dev/null</tt>.</blockquote>
<h4>Только вывод, простая эмуляция терминала</h4>
<blockquote>Отметьте эту опцию, если ваша программа не получает входных данных
с терминала (<tt>stdin</tt> будет перенаправлен в <tt>/dev/null</tt>), а вывод
(<tt>stdout</tt> и <tt>stderr</tt>) не требует сложной эмуляции терминала.
Вывод будет отображаться в <i>окне выовда</i>.
<br><i>Важно:</i> Встроенный эмулятор терминала интерпретирует только символ
новой строки <tt>\n</tt> (ASCII 10) в перевод строки. Он <i>не</i> обрабатывает
символ перевода каретки <tt>\r</tt> (ASCII 13). Этого вполне достаточно для
отображения простых отладочных сообщений, которые обычно используются
разработчиками программ, использующих графический интерфейс.</blockquote>
<h4>Полная эмуляция терминала</h4>
<blockquote>Отметьте эту опцию, если ваша программа получает данные из
<tt>stdin</tt>, или вывод в <tt>stdout</tt> or <tt>stderr</tt> требует полной
эмуляции терминала. В этом случае будет использован эмулятор терминала,
указанный в <a href="globaloptions.html">глобальных опциях</a>.</blockquote>
</body>
</html>

View file

@ -0,0 +1,31 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Содержимое регистров</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Окно Содержимого Регистров</h1>
Всякий раз, когда происходит останов программы,
KDbg выводит содержимое регистров ЦПУ в соответсвующем окне. Для того, чтобы
отобразить данное окно, выберите <i>Вид|Регистры</i>.
<p>Окно содержит 3 колонки:
<ol>
<li>Колонка <i>Регистр</i> выводит имя регистра.</li>
<li>Колонка <i>Значение</i> выводит содержимое регистров в более или менее
необработанном формате. Необработанный формат обычно выводит шестнадцатеричное
значение, даже для содержимого регистров с плавающей точкой.</li>
<li>Колонка <i>Декодированное значение</i> выводит содержимое регистров
в декодированной форме. Для арифметических регистров это
обычно знаковое десятичное значение, для регистров с плавающей точкой
&#150; число с плавающей точкой, регистры флагов декодируются в имена
флагов.</li>
</ol>
С помощью правой клавиши мыши можно вызвать меню, которое позволяет
установить формат значений во второй колонке.
</body>
</html>

View file

@ -0,0 +1,31 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство пользователя - Исходный Текст</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Окно Исходного Текста</h1>
Данное окно является главным и всегда отображается.
<p>Окно исходного текста содержит исходный текст программы. Слева от
каждой строки текста находится "активная область". Она содержит
указатель на строку исходного текста, которая выполняется в текущий момент
времени, а также указывает те строки исходного текста, которые содержат
точки останова.
<p>Новые точки останова устанавливаются нажатием левой клавиши мыши в
"активной области". Существующая точка останова может быть активирована
или дезактивирована с помощью средней клавиши мыши.
<p>Может быть нажат знак плюса '+' между "активной областью" и строкой
исходного текста. Это приведет к выводу ассемблерного кода для данной
строки. Чтобы скрыть ассемблерный код, необходимо
нажать клавишу '-'.
<p>Обычно окна исходного текста открываются автоматически. Чтобы
открыть файл с исходным текстом вручную, нужно нажать правую
кнопку мыши и выбрать <i>Открыть исходный текст</i> или
выбрать <i>Файл|Открыть исходный текст</i>.
<p>Для переключения между несколькими файлами с исходными текстами,
выберите нужный файл в меню <i>Окно</i>.
</body>
</html>

View file

@ -0,0 +1,23 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Стек</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Окно Стека</h1>
Окно стека вызывается выбором пункта меню <i>Вид|Стек</i>. Окно стека содержит
списки областей стека (stack frames), например, функции, которые были вызваны,
но еще не завершились.
<p>Самая внутренняя (вложенная) область (место текущего исполнения программы)
находится в самом верху списка.
<p>Для переключения на другую область стека, просто выберите эту область
мышкой. <a href="sourcecode.html">Окно исходных текстов</a> отображает строки
исходных текстов, которые исполняются программой в текущий момент, а
<a href="localvars.html">окно локальных переменных</a> и
<a href="watches.html">окно отслеживаемых выражений</a> изменяются, отображая
локальные переменные выбранной области стека.
</body>
</html>

View file

@ -0,0 +1,38 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Потоки</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Окно Потоков</h1>
Окно потоков можно вывести, выбрав пункт меню <i>Вид|Потоки</i>. В окне потоков
отображается список активных потоков программы.
<p><b><i>Замечание:</i></b> Отладка многопоточных программ должна
поддерживаться используемой версией gdb - это не является функцией KDbg. Для
Linux-систем лучше использовать gdb5.
<p>Содержимое окна потоков обновляется при каждой остановке программы
отладчиком. (Т.е. в окне <i>не</i> отображается состояние потоков во время
работы программы.)
<p>Первая колонка отображает идентификатор потока, вторая указывает на текущее
место исполнения данного потока.
<p>Маркер напротив одной из строк указывает на текущий <i>активный</i> поток:
<ul>
<li>
<a href="stack.html">Окно стека</a> отображает стек вызовов активного потока.
</li>
<li><a href="localvars.html">Окно локальных переменных</a> отображает локальные
переменные активного потока.</li>
<li><a href="watches.html">Окно просмотра</a> использует локальные переменные
потока для проверки выражений.</li>
</ul>
Если кликнуть на другой поток в списке, то он станет активным и соответственно
будет изменено содержимое других окон. В частности,
<a href="sourcecode.html">окно исходных кодов</a> отобразит место, где текущий
поток был остановлен.
</body>
</html>

View file

@ -0,0 +1,43 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Полезные Советы</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Полезные Советы</h1>
<ul>
<li>Всегда устанавливайте переменную окружения <tt>LD_BIND_NOW=1</tt> в
системах, использующих библиотеку glibc2.
Установка переменных окружения описана
<a href="argspwdenv.html#Environment">здесь</a>.</li>
<li>Вы можете использовать точки останова, как закладки: просто установите
точку останова и выключите ее. Позже вы сможете возвратиться к этой точке,
кликнув на нее два раза в списке точек останова (или просто выбрав ее и кликнув
на кнопку <i>Просмотреть Исходный Код</i>). Т.к. точки останова являются
постоянными (т.е. KDbg запоминает их расположение и восстанавливает в следующей
сессии), то при вызове вашей программы на отладку в следующий раз все точки
останова будут на месте.
</li>
<li>Вы можете изменять значения переменных программы: в окне просмотра
переменных (внизу справа) введите присвоение <tt>var.member=17</tt> и кликните
по кнопке <i>Добавить</i>. Это приведет к немедленному изменению значения
переменной. Теперь вам необходимо удалить это выражение из списка (выбрав
его и кликнув на кнопку <i>Удалить</i>). Это необходимо потому, что просмотр
выражений осуществляется при каждом останове программы и этой переменной будет
присваиваться тоже значение снова и снова!</li>
<li>Вы можете выводить значение переменных в окно просмотра в разных форматах,
используя модификаторы gdb перед указанием выводимой переменной. Например,
<tt>/x var.member</tt> выведет значение <tt>var.member</tt> в шеснадцатеричном
виде.</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,126 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Таблицы Типов</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Таблица Типов KDbg</h1>
KDbg может отображать содержимое отдельно взятых членов структурированных типов
данных, таким образом отсутствует необходимость в раскрытии переменных в
<a href="localvars.html">окне локальных переменных</a> или в
<a href="watches.html">окне отслеживаемых выражений</a>. Информация о том,
переменная какого члена отображается, хранится в <i>таблицах типов</i>. Обычно
существует одна таблица на разделяемую библиотеку.
<p>Таблицы типов KDbg расположены в каталоге
<tt>$KDEDIR/share/apps/kdbg/types</tt>. Имена файло таблиц оканчиваются на
<tt>.kdbgtt</tt>. Например, таблица типов для <tt>libqt.so</tt> называется
<tt>qt.kdbgtt</tt>.
<p>Файлы таблиц типов соответствуют стандартному синтаксису файлов конфигурации
KDE. Файл содержит следующие группы:
<ul>
<li>
Группу <tt>[Type Table]</tt>, в которой перечислены типы и информация о том,
как отладчик может определить, слинкована ли программа с этой библиотекой.</li>
<li>Группу на каждый прописанный тип, в которой содержится информация о том,
как KDbg должен отображать данный тип.</li>
</ul>
Для определения таблиц типов, применимых к отлаживаемой программе, KDbg
запрашивает список разделяемых библиотек, с которыми слинкована программа.
Затем он осуществляет поиск имен этих библиотек в таблицах типов в элементах
<tt>ShlibRE</tt>. Используются те таблицы, в которых были найдены
соответствующие имена библиотек. Если тип появляется в нескольких таблицах, то
неопределено, какое же из описаний будет выбрано.
<h2>Группа <tt>[Type Table]</tt></h2>
Эта группа содержит следующие элементы:
<ul>
<li>
<tt>Types1</tt>, <tt>Types2</tt>, и тд. Эти элементы являются именами типов.
Каждый из них представляет собой разделенный запятыми список имен типов. В
каждом элементе может быть перечислено любое количество типов. (Имена типов
можно разбить на несколько строк, чтобы они строки не получались слишком
длинными.) В этих строках недопустимы символы пробела. Элементы должны
нумероваться последовательно (KDbg прекращает чтение на первом же пропуске),
однако элементы могут быть пусты (т.е. вообще не содержать типов). Иногда
порядок перечисления имен имеет значение (см. пример с <tt>Alias</tt> ниже).
</li>
<li>
<tt>ShlibRE</tt>. KDbg использует этот элемент для определения, использовать
ли данную таблицу к текущей отлаживаемой программе. Для этого KDbg определяет
разделяемые библиотеки, используемые программой. Если хотя бы одна из них
совпадает со значением этого элемента, таблица используется. Используемые
регулярные выражения совпадают с регулярными выражениями Qt (метасимволы
<tt>.*?[]^$\</tt> распознаются обычным образом, однако отсутсвует возможность
группировать символы.)</li>
<li>
<tt>LibDisplayName</tt>. Этот элемент используется в списках, в которых
доступные таблицы типов перечислены для указания данной таблицы типов.</li>
<br><font size=-1>На данный момент это не используется.</font></ul>
<h2>Группа типа</h2>
На каждый заявленый тип должна быть заведена группа, названная именем типа.
<font size=-1>На данный момент шаблоны С++ не поддерживаются.</font>
Каждая группа содержит следующие элементы:
<ul>
<li>
<tt>Display</tt> указывает, как KDbg должен отображать значение этого типа.
Строка может содержать от 1 до 5 символов '<tt>%</tt>'. Они заменяются на
результаты выражений, описанных в элементах <tt>Expr</tt><i>x</i>.</li>
<li>Один или более <tt>Expr1</tt>, <tt>Expr2</tt>, и тд. Каждый из них должен
содержать <b>только одну</b> последовательность <tt>%s</tt>, которая будет
заменена выражением, чье значение необходимо получить. Такие выражения
передаются gdb, а результат заносится на место соответствующего символа
процента в элементе <tt>Display</tt>.</li>
<li>
<tt>Alias</tt> указывает на тип-псевдоним. Если присутствует данная запись, то
с данным типом обходятся также, как с тем, на который он указывает. Этот
тип-псевдоним дожен быть описан перд ссылающимся на него типом в элементах
<tt>Types</tt><i>x</i> группы <tt>[Type Table]</tt>.</li>
</ul>
<font size=-1>На данный момент количество выражений для каждого типа ограничено
пятью. Это может быть с легкостью изменено, но я не рекомендую вообще
приближаться к данному рубежу - это только затормозить процесс отладки.</font>
<p>KDbg распознает специальное расширение, которое используется для вывода
строк Qt 2.0 в unicode: Если перед <tt>Expr</tt><i>x</i> стоит
<tt>/QString::Data</tt>, подразумевается, что результат операции является
указателем на <tt>QString::Data</tt>. Выводимое значение является строкой в
unicode, представленное <tt>QString::Data</tt> (которое может быть
<tt>QString::null</tt>, если это пустая строка Qt, или <tt>(null)</tt>, если
<tt>unicode</tt> член структуры является нулевым указателем). Для примера см.
<tt>qt2.kdbgtt</tt>.
<p>Совет: Совсем необязательно описывать наследуемые типы, если они должны
обрабатываться также как и базовый класс - KDbg может определить наследование
и использовать описание типа первого (слева) базового класса. Вы можете
использовать элемент <tt>Alias</tt> для быстрого указания класса при
множественном наследовании, отличного от первого слева.
<h2>Пример</h2>
Этот пример показывает, как <tt>QString</tt> и <tt>QObject</tt> описаны в
<tt>qt.kdbgtt</tt>. Дополнительно определен <tt>QTableView</tt>, ссылающийся
на <tt>QObject</tt>. Этот пример применим к Qt 1.x, который расположен в
разделяемых библиотеках, имена которых оканчиваются как <tt>libqt.so.1</tt>.
<pre>[Type Table]
Types1=QString
Types2=QObject,QTableView
LibDisplayName=libqt 1.x
ShlibRE=libqt\.so\.1$
[QString]
Display={ % }
Expr1=(%s).shd->data
[QObject]
Display={ name=% #chld=% }
Expr1=(%s).objname
Expr2=(%s).childObjects->numNodes
[QTableView]
Alias=QObject</pre>
Замечание: гораздо безопаснее заключать <tt>%s</tt> в скобки.
</body>
</html>

View file

@ -0,0 +1,20 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<meta name="Author" content="Johannes Sixt">
<title>KDbg - Руководство Пользователя - Отслеживаемые Выражения</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
<a href="index.html">Содержание</a>
<h1>Окно Отслеживаемых Выражений</h1>
Окно отслеживаемых выражений вызывается выбором пункта меню
<i>Вид|Отслеживаемые Выражения</i>. Оно отображает произвольные выражения.
<p>Для добавления выражения, введите его в поле редактирования и нажмите Enter
или кликните на кнопку <i>Добавить</i>. Для удаления выражения, выберите его
(выбирайте корень выражения?) и кликните на кнопку <i>Del</i>.
<p>Отслеживаемые выражения сохраняются между сессиями отладки. Поэтому
рекомендуется удалять выражения, которыми вы уже не пользуетесь, т.к. это
повысит скорость отладки.
</body>
</html>

24
kdbg-2.5.5/kdbg/envvar.h Normal file
View file

@ -0,0 +1,24 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef ENVVAR_H
#define ENVVAR_H
/*
* Description of environment variables. Note that the name of the variable
* is given as the key in the map, so we don't repeat it here.
*/
class QTreeWidgetItem;
struct EnvVar {
QString value;
enum EnvVarStatus { EVclean, EVdirty, EVnew, EVdeleted };
EnvVarStatus status;
QTreeWidgetItem* item;
};
#endif // ENVVAR_H

835
kdbg-2.5.5/kdbg/exprwnd.cpp Normal file
View file

@ -0,0 +1,835 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#include "exprwnd.h"
#include "exprwnd.moc"
#include "typetable.h"
#include <QHeaderView>
#include <QStringList>
#include <QPainter>
#include <QPaintEvent>
#include <QFocusEvent>
#include <QKeyEvent>
#include <QScrollBar>
#include <kiconloader.h> /* icons */
#include <klocale.h> /* i18n */
#include "mydebug.h"
VarTree::VarTree(VarTree* parent, ExprValue* v) :
QTreeWidgetItem(parent),
m_varKind(v->m_varKind),
m_nameKind(v->m_nameKind),
m_type(0),
m_exprIndex(0),
m_exprIndexUseGuard(false),
m_baseValue(v->m_value),
m_baseChanged(false),
m_structChanged(false)
{
setText(v->m_name);
updateValueText();
if (v->m_child != 0 || m_varKind == VarTree::VKpointer)
setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
else
setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator);
setExpanded(v->m_initiallyExpanded);
}
VarTree::VarTree(ExprWnd* parent, ExprValue* v) :
QTreeWidgetItem(parent),
m_varKind(VKsimple),
m_nameKind(VarTree::NKplain),
m_type(0),
m_exprIndex(0),
m_exprIndexUseGuard(false),
m_baseValue(v->m_value),
m_baseChanged(false),
m_structChanged(false)
{
setText(v->m_name);
updateValueText();
}
VarTree::~VarTree()
{
}
QString VarTree::computeExpr() const
{
// top-level items are special
if (isToplevelExpr())
return getText();
// get parent expr
VarTree* par = static_cast<VarTree*>(parent());
QString parentExpr = par->computeExpr();
// skip this item's name if it is a base class or anonymous struct or union
if (m_nameKind == NKtype || m_nameKind == NKanonymous) {
return parentExpr;
}
/* augment by this item's text */
QString result;
/* if this is an address, dereference it */
if (m_nameKind == NKaddress) {
ASSERT(par->m_varKind == VKpointer);
result = "*" + parentExpr;
return result;
}
switch (par->m_varKind) {
case VKarray:
{
QString index = getText();
int i = 1;
// skip past the index
while (index[i].isDigit())
i++;
/*
* Some array indices are actually ranges due to repeated array
* values. We use the first index in these cases.
*/
if (index[i] != ']') {
// remove second index
index.remove(i, index.length()-i-1);
}
result = "(" + parentExpr + ")" + index;
}
break;
case VKstruct:
result = "(" + parentExpr + ")." + getText();
break;
case VKsimple: /* parent can't be simple */
case VKpointer: /* handled in NKaddress */
case VKdummy: /* can't occur at all */
ASSERT(false);
result = parentExpr; /* paranoia */
break;
}
return result;
}
bool VarTree::isToplevelExpr() const
{
return parent() == 0;
}
bool VarTree::isAncestorEq(const VarTree* child) const
{
const QTreeWidgetItem* c = child;
while (c != 0 && c != this) {
c = c->parent();
}
return c != 0;
}
bool VarTree::updateValue(const QString& newValue)
{
// check whether the value changed
bool prevValueChanged = m_baseChanged;
if ((m_baseChanged = m_baseValue != newValue)) {
m_baseValue = newValue;
updateValueText();
setForeground(1, QBrush(QColor(Qt::red)));
} else if (prevValueChanged) {
setForeground(1, treeWidget()->palette().text());
}
/*
* We must repaint the cell if the value changed. If it did not change,
* we still must repaint the cell if the value changed previously,
* because the color of the display must be changed (from red to
* black).
*/
return m_baseChanged || prevValueChanged;
}
bool VarTree::updateStructValue(const QString& newValue)
{
// check whether the value changed
bool prevValueChanged = m_structChanged;
if ((m_structChanged = m_structValue != newValue)) {
m_structValue = newValue;
updateValueText();
setForeground(1, QBrush(QColor(Qt::red)));
} else if (prevValueChanged) {
setForeground(1, treeWidget()->palette().text());
}
/*
* We must repaint the cell if the value changed. If it did not change,
* we still must repaint the cell if the value changed previously,
* because the color of the display must be changed (from red to
* black).
*/
return m_structChanged || prevValueChanged;
}
void VarTree::updateValueText()
{
if (m_baseValue.isEmpty()) {
setText(1, m_structValue);
} else if (m_structValue.isEmpty()) {
setText(1, m_baseValue);
} else {
setText(1, m_baseValue + " " + m_structValue);
}
}
void VarTree::inferTypesOfChildren(ProgramTypeTable& typeTable)
{
/*
* Type inference works like this: We use type information of those
* children that have a type name in their name (base classes) or in
* their value (pointers)
*/
// first recurse children
for (int i = 0; i < childCount(); i++)
{
child(i)->inferTypesOfChildren(typeTable);
}
// if this is a pointer, get the type from the value (less the pointer)
if (m_varKind == VKpointer) {
if (isWcharT())
{
/*
* wchart_t pointers must be treated as struct, because the array
* of characters is printed similar to how QStrings are decoded.
*/
m_varKind = VKstruct;
setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator);
}
// don't know how to do this cleanly
} else if (m_varKind == VKstruct) {
// check if this is a base class part
if (m_nameKind == NKtype) {
const QString& typeName =
getText().mid(1, getText().length()-2); // strip < and >
m_type = typeTable.lookup(typeName);
/* if we don't have a type yet, get it from the base class */
if (m_type == 0) {
m_type = inferTypeFromBaseClass();
/*
* If there is a known type now, it is the one from the
* first base class whose type we know.
*/
}
/*
* If we still don't have a type, the type is really unknown.
*/
if (m_type == 0) {
m_type = TypeInfo::unknownType();
}
} // else
/*
* This is not a base class part. We don't assign a type so
* that later we can ask gdb.
*/
}
}
// the value contains the pointer type in parenthesis
bool VarTree::isWcharT() const
{
return value().startsWith("(const wchar_t *)") ||
value().startsWith("(wchar_t *)");
}
/*
* Get the type of the first base class whose type we know.
*/
const TypeInfo* VarTree::inferTypeFromBaseClass()
{
if (m_varKind == VKstruct) {
for (int i = 0; i < childCount(); i++)
{
VarTree* child = VarTree::child(i);
// only check base class parts (i.e. type names)
if (child->m_nameKind != NKtype)
break;
if (child->m_type != 0 &&
child->m_type != TypeInfo::unknownType())
{
// got a type!
return child->m_type;
}
}
}
return 0;
}
ExprValue::ExprValue(const QString& name, VarTree::NameKind aKind) :
m_name(name),
m_varKind(VarTree::VKsimple),
m_nameKind(aKind),
m_child(0),
m_next(0),
m_initiallyExpanded(false)
{
}
ExprValue::~ExprValue()
{
delete m_child;
delete m_next;
}
void ExprValue::appendChild(ExprValue* newChild)
{
if (m_child == 0) {
m_child = newChild;
} else {
// walk chain of children to find the last one
ExprValue* last = m_child;
while (last->m_next != 0)
last = last->m_next;
last->m_next = newChild;
}
newChild->m_next = 0; // just to be sure
}
int ExprValue::childCount() const
{
int i = 0;
ExprValue* c = m_child;
while (c) {
++i;
c = c->m_next;
}
return i;
}
ExprWnd::ExprWnd(QWidget* parent, const QString& colHeader) :
QTreeWidget(parent),
m_edit(0)
{
QTreeWidgetItem* pHeaderItem = new QTreeWidgetItem();
pHeaderItem->setText(0, colHeader);
pHeaderItem->setText(1, i18n("Value"));
setHeaderItem(pHeaderItem);
header()->setResizeMode(0, QHeaderView::Interactive);
header()->setResizeMode(1, QHeaderView::Interactive);
setSortingEnabled(false); // do not sort items
setRootIsDecorated(true);
setAllColumnsShowFocus(true);
m_pixPointer = UserIcon("pointer.xpm");
if (m_pixPointer.isNull())
TRACE("Can't load pointer.xpm");
}
ExprWnd::~ExprWnd()
{
}
QStringList ExprWnd::exprList() const
{
QStringList exprs;
for (int i = 0; i < topLevelItemCount(); i++)
{
exprs.append(topLevelItem(i)->getText());
}
return exprs;
}
VarTree* ExprWnd::insertExpr(ExprValue* expr, ProgramTypeTable& typeTable)
{
// append a new dummy expression
VarTree* display = new VarTree(this, expr);
// replace it right away
updateExpr(display, expr, typeTable);
return display;
}
void ExprWnd::updateExpr(ExprValue* expr, ProgramTypeTable& typeTable)
{
// search the root variable
VarTree* item = 0;
for (int i = 0; i < topLevelItemCount(); i++)
{
if (topLevelItem(i)->getText() == expr->m_name) {
item = topLevelItem(i);
break;
}
}
if (item == 0) {
return;
}
// now update it
updateExprRec(item, expr, typeTable);
collectUnknownTypes(item);
}
void ExprWnd::updateExpr(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable)
{
updateExprRec(display, newValues, typeTable);
collectUnknownTypes(display);
}
/*
* returns true if there's a visible change
*/
void ExprWnd::updateExprRec(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable)
{
bool isExpanded = display->isExpanded();
/*
* If we are updating a pointer without children by a dummy, we don't
* collapse it, but simply insert the new children. This happens when a
* pointer has just been expanded by the user.
*/
if (display->m_varKind == VarTree::VKpointer &&
display->childCount() == 0 &&
newValues->m_varKind == VarTree::VKdummy)
{
replaceChildren(display, newValues);
return;
}
/*
* If the display and newValues have different kind or if their number
* of children is different, replace the whole sub-tree.
*/
if (// the next two lines mean: not(m_varKind remains unchanged)
!(newValues->m_varKind == VarTree::VKdummy ||
display->m_varKind == newValues->m_varKind)
||
(display->childCount() != newValues->childCount() &&
/*
* If this is a pointer and newValues doesn't have children, we
* don't replace the sub-tree; instead, below we mark this
* sub-tree for requiring an update.
*/
(display->m_varKind != VarTree::VKpointer ||
newValues->m_child != 0)))
{
if (isExpanded) {
display->setExpanded(false);
}
// since children changed, it is likely that the type has also changed
display->m_type = 0; /* will re-evaluate the type */
// display the new value
updateSingleExpr(display, newValues);
replaceChildren(display, newValues);
// update the m_varKind
if (newValues->m_varKind != VarTree::VKdummy) {
display->m_varKind = newValues->m_varKind;
if (newValues->m_child != 0 || newValues->m_varKind == VarTree::VKpointer)
display->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
else
display->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator);
}
// get some types (after the new m_varKind has been set!)
display->inferTypesOfChildren(typeTable);
// (note that the new value might not have a sub-tree at all)
return;
}
// display the new value
updateSingleExpr(display, newValues);
/*
* If this is an expanded pointer, record it for being updated.
*/
if (display->m_varKind == VarTree::VKpointer) {
if (isExpanded &&
// if newValues is a dummy, we have already updated this pointer
newValues->m_varKind != VarTree::VKdummy)
{
m_updatePtrs.push_back(display);
}
/*
* If the visible sub-tree has children, but newValues doesn't, we
* can stop here.
*/
if (newValues->m_child == 0) {
return;
}
}
ASSERT(display->childCount() == newValues->childCount());
// go for children
ExprValue* vNew = newValues->m_child;
for (int i = 0; i < display->childCount(); i++)
{
VarTree* vDisplay = display->child(i);
// check whether the names are the same
if (vDisplay->getText() != vNew->m_name) {
// set new name
vDisplay->setText(vNew->m_name);
}
// recurse
updateExprRec(vDisplay, vNew, typeTable);
vNew = vNew->m_next;
}
}
void ExprWnd::updateSingleExpr(VarTree* display, ExprValue* newValue)
{
/*
* If newValues is a VKdummy, we are only interested in its children.
* No need to update anything here.
*/
if (newValue->m_varKind == VarTree::VKdummy) {
return;
}
/*
* If this node is a struct and we know its type then we know how to
* find a nested value. So register the node for an update.
*
* wchar_t types are also treated specially here: We consider them
* as struct (has been set in inferTypesOfChildren()).
*/
if (display->m_varKind == VarTree::VKstruct &&
display->m_type != 0 &&
display->m_type != TypeInfo::unknownType())
{
ASSERT(newValue->m_varKind == VarTree::VKstruct);
if (display->m_type == TypeInfo::wchartType())
{
display->m_partialValue = "L";
}
else
display->m_partialValue = display->m_type->m_displayString[0];
m_updateStruct.push_back(display);
}
display->updateValue(newValue->m_value);
}
void ExprWnd::updateStructValue(VarTree* display)
{
ASSERT(display->m_varKind == VarTree::VKstruct);
display->updateStructValue(display->m_partialValue);
// reset the value
display->m_partialValue = "";
display->m_exprIndex = -1;
}
void ExprWnd::replaceChildren(VarTree* display, ExprValue* newValues)
{
ASSERT(display->childCount() == 0 || display->m_varKind != VarTree::VKsimple);
// delete all children of display
while (VarTree* c = display->child(0)) {
unhookSubtree(c);
delete c;
}
// insert copies of the newValues
for (ExprValue* v = newValues->m_child; v != 0; v = v->m_next)
{
VarTree* vNew = new VarTree(display, v);
// recurse
replaceChildren(vNew, v);
}
}
void ExprWnd::collectUnknownTypes(VarTree* var)
{
QTreeWidgetItemIterator i(var);
for (; *i; ++i)
{
checkUnknownType(static_cast<VarTree*>(*i));
}
}
void ExprWnd::checkUnknownType(VarTree* var)
{
ASSERT(var->m_varKind != VarTree::VKpointer || var->m_nameKind != VarTree::NKtype);
if (var->m_type == 0 &&
var->m_varKind == VarTree::VKstruct &&
var->m_nameKind != VarTree::NKtype &&
var->m_nameKind != VarTree::NKanonymous)
{
if (!var->isWcharT())
{
/* this struct node doesn't have a type yet: register it */
m_updateType.push_back(var);
}
else
{
var->m_type = TypeInfo::wchartType();
var->m_partialValue = "L";
m_updateStruct.push_back(var);
}
}
// add pointer pixmap to pointers
if (var->m_varKind == VarTree::VKpointer) {
var->setPixmap(m_pixPointer);
}
}
QString ExprWnd::formatWCharPointer(QString value)
{
int pos = value.indexOf(") ");
if (pos > 0)
value = value.mid(pos+2);
return value + " L";
}
VarTree* ExprWnd::topLevelExprByName(const QString& name) const
{
for (int i = 0; i < topLevelItemCount(); i++)
{
if (topLevelItem(i)->getText() == name)
return topLevelItem(i);
}
return 0;
}
VarTree* ExprWnd::ptrMemberByName(VarTree* v, const QString& name)
{
// v must be a pointer variable, must have children
if (v->m_varKind != VarTree::VKpointer || v->childCount() == 0)
return 0;
// the only child of v is the pointer value that represents the struct
VarTree* item = v->child(0);
return memberByName(item, name);
}
VarTree* ExprWnd::memberByName(VarTree* v, const QString& name)
{
// search immediate children for name
for (int i = 0; i < v->childCount(); i++)
{
if (v->child(i)->getText() == name)
return v->child(i);
}
// try in base classes and members that are anonymous structs or unions
for (int i = 0; i < v->childCount(); i++)
{
VarTree* item = v->child(i);
if (item->m_nameKind == VarTree::NKtype ||
item->m_nameKind == VarTree::NKanonymous)
{
item = memberByName(item, name);
if (item != 0)
return item;
}
}
return 0;
}
void ExprWnd::removeExpr(VarTree* item)
{
unhookSubtree(item);
delete item;
}
void ExprWnd::unhookSubtree(VarTree* subTree)
{
// must remove any pointers scheduled for update from the list
unhookSubtree(m_updatePtrs, subTree);
unhookSubtree(m_updateType, subTree);
unhookSubtree(m_updateStruct, subTree);
emit removingItem(subTree);
}
void ExprWnd::unhookSubtree(std::list<VarTree*>& list, VarTree* subTree)
{
if (subTree == 0)
return;
std::list<VarTree*>::iterator i = list.begin();
while (i != list.end()) {
std::list<VarTree*>::iterator checkItem = i;
++i;
if (subTree->isAncestorEq(*checkItem)) {
// checkItem is an item from subTree
list.erase(checkItem);
}
}
}
void ExprWnd::clearPendingUpdates()
{
m_updatePtrs.clear();
m_updateType.clear();
m_updateStruct.clear();
}
VarTree* ExprWnd::nextUpdatePtr()
{
VarTree* ptr = 0;
if (!m_updatePtrs.empty()) {
ptr = m_updatePtrs.front();
m_updatePtrs.pop_front();
}
return ptr;
}
VarTree* ExprWnd::nextUpdateType()
{
VarTree* ptr = 0;
if (!m_updateType.empty()) {
ptr = m_updateType.front();
m_updateType.pop_front();
}
return ptr;
}
VarTree* ExprWnd::nextUpdateStruct()
{
VarTree* ptr = 0;
if (!m_updateStruct.empty()) {
ptr = m_updateStruct.front();
m_updateStruct.pop_front();
}
return ptr;
}
void ExprWnd::editValue(VarTree* item, const QString& text)
{
if (m_edit == 0)
m_edit = new ValueEdit(this);
QRect r = visualItemRect(item);
int x = columnViewportPosition(1);
int y = r.y();
int w = columnWidth(1);
int h = r.height();
/*
* Make the edit widget at least 5 characters wide (but not wider than
* this widget). If less than half of this widget is used to display
* the text, scroll this widget so that half of it shows the text (or
* less than half of it if the text is shorter).
*/
QFontMetrics metr = m_edit->font();
int wMin = metr.width("88888");
if (w < wMin)
w = wMin;
int wThis = viewport()->width();
if (x >= wThis/2 && // less than half the width displays text
x+w > wThis) // not all text is visible
{
// scroll so that more text is visible
QScrollBar* pScrollBar = horizontalScrollBar();
int wScroll = qMin(x-wThis/2, x+w-wThis);
pScrollBar->setValue(pScrollBar->value() + wScroll);
x -= wScroll;
}
else if (x < 0)
{
// don't let the edit move out at the left
x = 0;
}
// make the edit box as wide as the visible column
QRect rect(x,y, wThis-x,h);
m_edit->setText(text);
m_edit->selectAll();
m_edit->setGeometry(rect);
m_edit->m_finished = false;
m_edit->m_item = item;
m_edit->show();
m_edit->setFocus();
}
bool ExprWnd::isEditing() const
{
return m_edit != 0 && m_edit->isVisible();
}
ValueEdit::ValueEdit(ExprWnd* parent) :
QLineEdit(parent->viewport())
{
setFrame(false);
hide();
lower(); // lower the window below scrollbars
connect(parent, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
SLOT(slotSelectionChanged()));
connect(parent, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
SLOT(slotSelectionChanged()));
connect(parent, SIGNAL(itemExpanded(QTreeWidgetItem*)),
SLOT(slotSelectionChanged()));
connect(parent, SIGNAL(itemCollapsed(QTreeWidgetItem*)),
SLOT(slotSelectionChanged()));
connect(this, SIGNAL(done(VarTree*, const QString&)),
parent, SIGNAL(editValueCommitted(VarTree*, const QString&)));
}
ValueEdit::~ValueEdit()
{
}
void ValueEdit::terminate(bool commit)
{
TRACE(commit?"ValueEdit::terminate(true)":"ValueEdit::terminate(false)");
if (!m_finished)
{
m_finished = true;
hide(); // will call focusOutEvent, that's why we need m_finished
if (commit) {
emit done(m_item, text());
}
}
}
void ValueEdit::keyPressEvent(QKeyEvent *e)
{
if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter)
terminate(true);
else if(e->key() == Qt::Key_Escape)
terminate(false);
else
QLineEdit::keyPressEvent(e);
}
void ValueEdit::paintEvent(QPaintEvent* e)
{
QLineEdit::paintEvent(e);
QPainter p(this);
p.drawRect(rect());
}
void ValueEdit::focusOutEvent(QFocusEvent* ev)
{
TRACE("ValueEdit::focusOutEvent");
QFocusEvent* focusEv = static_cast<QFocusEvent*>(ev);
if (focusEv->reason() == Qt::ActiveWindowFocusReason)
{
// Switching to a different window should terminate the edit,
// because if the window with this variable display is floating
// then that different window could be the main window, where
// the user had clicked one of the Execute buttons. This in turn
// may pull the item away that we are editing here.
terminate(false);
}
// Don't let a RMB close the editor
else if (focusEv->reason() != Qt::PopupFocusReason)
{
terminate(true);
}
}
void ValueEdit::slotSelectionChanged()
{
TRACE("ValueEdit::slotSelectionChanged");
terminate(false);
}

178
kdbg-2.5.5/kdbg/exprwnd.h Normal file
View file

@ -0,0 +1,178 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef EXPRWND_H
#define EXPRWND_H
#include <QTreeWidget>
#include <QLineEdit>
#include <QPixmap>
#include <list>
class ProgramTypeTable;
class TypeInfo;
struct ExprValue;
class ExprWnd;
class QStringList;
/*! \brief a variable's value is the tree of sub-variables */
class VarTree : public QTreeWidgetItem
{
public:
enum VarKind { VKsimple, VKpointer, VKstruct, VKarray,
VKdummy //!< used to update only children
};
VarKind m_varKind;
enum NameKind { NKplain, NKstatic, NKtype,
NKanonymous, //!< an anonymous struct or union
NKaddress //!< a dereferenced pointer
};
NameKind m_nameKind;
const TypeInfo* m_type; //!< the type of struct if it could be derived
int m_exprIndex; //!< used in struct value update
bool m_exprIndexUseGuard; //!< ditto; if guard expr should be used
QString m_partialValue; //!< while struct value update is in progress
VarTree(VarTree* parent, ExprValue* v);
VarTree(ExprWnd* parent, ExprValue* v);
virtual ~VarTree();
public:
QString computeExpr() const;
bool isToplevelExpr() const;
/** is this element an ancestor of (or equal to) child? */
bool isAncestorEq(const VarTree* child) const;
/** update the regular value; returns whether a repaint is necessary */
bool updateValue(const QString& newValue);
/** update the "quick member" value; returns whether repaint is necessary */
bool updateStructValue(const QString& newValue);
/** find out the type of this value using the child values */
void inferTypesOfChildren(ProgramTypeTable& typeTable);
/** get the type from base class part */
const TypeInfo* inferTypeFromBaseClass();
/** returns whether the pointer is a wchar_t */
bool isWcharT() const;
QString getText() const { return text(0); }
using QTreeWidgetItem::setText;
void setText(const QString& t) { QTreeWidgetItem::setText(0, t); }
void setPixmap(const QPixmap& p) { QTreeWidgetItem::setIcon(0, QIcon(p)); }
QString value() const { return m_baseValue; }
VarTree* child(int i) const { return static_cast<VarTree*>(QTreeWidgetItem::child(i)); }
private:
void updateValueText();
QString m_baseValue; //!< The "normal value" that the driver reported
QString m_structValue; //!< The "quick member" value
bool m_baseChanged : 1;
bool m_structChanged : 1;
};
/**
* Represents the value tree that is parsed by the debugger drivers.
*/
struct ExprValue
{
QString m_name;
QString m_value;
VarTree::VarKind m_varKind;
VarTree::NameKind m_nameKind;
ExprValue* m_child; /* the first child expression */
ExprValue* m_next; /* the next sibling expression */
bool m_initiallyExpanded;
ExprValue(const QString& name, VarTree::NameKind kind);
~ExprValue();
void appendChild(ExprValue* newChild);
int childCount() const;
};
class ValueEdit : public QLineEdit
{
Q_OBJECT
public:
ValueEdit(ExprWnd* parent);
~ValueEdit();
void terminate(bool commit);
VarTree* m_item;
bool m_finished;
protected:
void keyPressEvent(QKeyEvent *e);
void focusOutEvent(QFocusEvent* ev);
void paintEvent(QPaintEvent* e);
public slots:
void slotSelectionChanged();
signals:
void done(VarTree*, const QString&);
};
class ExprWnd : public QTreeWidget
{
Q_OBJECT
public:
ExprWnd(QWidget* parent, const QString& colHeader);
~ExprWnd();
/** returns the list with the expressions at the topmost level */
QStringList exprList() const;
/** appends a copy of expr to the end of the tree at the topmost level;
* returns a pointer to the inserted top-level item */
VarTree* insertExpr(ExprValue* expr, ProgramTypeTable& typeTable);
/** updates an existing expression */
void updateExpr(ExprValue* expr, ProgramTypeTable& typeTable);
void updateExpr(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable);
/** updates the value and repaints it for a single item (not the children) */
void updateSingleExpr(VarTree* display, ExprValue* newValues);
/** updates only the value of the node */
void updateStructValue(VarTree* display);
/** get a top-level expression by name */
VarTree* topLevelExprByName(const QString& name) const;
/** return a member of the struct that pointer \a v refers to */
static VarTree* ptrMemberByName(VarTree* v, const QString& name);
/** return a member of the struct \a v */
static VarTree* memberByName(VarTree* v, const QString& name);
/** removes an expression; must be on the topmost level*/
void removeExpr(VarTree* item);
/** clears the list of pointers needing updates */
void clearPendingUpdates();
/** returns a pointer to update (or 0) and removes it from the list */
VarTree* nextUpdatePtr();
VarTree* nextUpdateType();
VarTree* nextUpdateStruct();
void editValue(VarTree* item, const QString& text);
/** tells whether the a value is currently edited */
bool isEditing() const;
VarTree* selectedItem() const { return static_cast<VarTree*>(QTreeWidget::currentItem()); }
VarTree* topLevelItem(int i) const { return static_cast<VarTree*>(QTreeWidget::topLevelItem(i)); }
protected:
void updateExprRec(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable);
void replaceChildren(VarTree* display, ExprValue* newValues);
void collectUnknownTypes(VarTree* item);
void checkUnknownType(VarTree* item);
static QString formatWCharPointer(QString value);
QPixmap m_pixPointer;
std::list<VarTree*> m_updatePtrs; //!< dereferenced pointers that need update
std::list<VarTree*> m_updateType; //!< structs whose type must be determined
std::list<VarTree*> m_updateStruct; //!< structs whose nested value needs update
ValueEdit* m_edit;
/** remove items that are in the subTree from the list */
void unhookSubtree(VarTree* subTree);
static void unhookSubtree(std::list<VarTree*>& list, VarTree* subTree);
signals:
void removingItem(VarTree*);
void editValueCommitted(VarTree*, const QString&);
};
#endif // EXPRWND_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,92 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef GDBDRIVER_H
#define GDBDRIVER_H
#include "dbgdriver.h"
class GdbDriver : public DebuggerDriver
{
Q_OBJECT
public:
GdbDriver();
~GdbDriver();
virtual QString driverName() const;
virtual QString defaultInvocation() const;
virtual QStringList boolOptionList() const;
void setDefaultInvocation(QString cmd) { m_defaultCmd = cmd; }
static QString defaultGdb();
virtual bool startup(QString cmdStr);
virtual void commandFinished(CmdQueueItem* cmd);
virtual CmdQueueItem* executeCmd(DbgCommand,
bool clearLow = false);
virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg,
bool clearLow = false);
virtual CmdQueueItem* executeCmd(DbgCommand, int intArg,
bool clearLow = false);
virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg, int intArg,
bool clearLow = false);
virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg1, QString strArg2,
bool clearLow = false);
virtual CmdQueueItem* executeCmd(DbgCommand, int intArg1, int intArg2,
bool clearLow = false);
virtual CmdQueueItem* queueCmd(DbgCommand,
QueueMode mode);
virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg,
QueueMode mode);
virtual CmdQueueItem* queueCmd(DbgCommand, int intArg,
QueueMode mode);
virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg, int intArg,
QueueMode mode);
virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg1, QString strArg2,
QueueMode mode);
virtual void terminate();
virtual void detachAndTerminate();
virtual void interruptInferior();
virtual void setPrintQStringDataCmd(const char* cmd);
virtual ExprValue* parseQCharArray(const char* output, bool wantErrorValue, bool qt3like);
virtual void parseBackTrace(const char* output, std::list<StackFrame>& stack);
virtual bool parseFrameChange(const char* output, int& frameNo,
QString& file, int& lineNo, DbgAddr& address);
virtual bool parseBreakList(const char* output, std::list<Breakpoint>& brks);
virtual std::list<ThreadInfo> parseThreadList(const char* output);
virtual bool parseBreakpoint(const char* output, int& id,
QString& file, int& lineNo, QString& address);
virtual void parseLocals(const char* output, std::list<ExprValue*>& newVars);
virtual ExprValue* parsePrintExpr(const char* output, bool wantErrorValue);
virtual bool parseChangeWD(const char* output, QString& message);
virtual bool parseChangeExecutable(const char* output, QString& message);
virtual bool parseCoreFile(const char* output);
virtual uint parseProgramStopped(const char* output, QString& message);
virtual QStringList parseSharedLibs(const char* output);
virtual bool parseFindType(const char* output, QString& type);
virtual std::list<RegisterInfo> parseRegisters(const char* output);
virtual bool parseInfoLine(const char* output,
QString& addrFrom, QString& addrTo);
virtual std::list<DisassembledCode> parseDisassemble(const char* output);
virtual QString parseMemoryDump(const char* output, std::list<MemoryDump>& memdump);
virtual QString parseSetVariable(const char* output);
virtual QString editableValue(VarTree* value);
protected:
QString m_programWD; /* just an intermediate storage */
QString m_redirect; /* redirection to /dev/null */
bool m_haveCoreFile;
QString m_defaultCmd; /* how to invoke gdb */
QString makeCmdString(DbgCommand cmd, QString strArg);
QString makeCmdString(DbgCommand cmd, int intArg);
QString makeCmdString(DbgCommand cmd, QString strArg, int intArg);
QString makeCmdString(DbgCommand cmd, QString strArg1, QString strArg2);
QString makeCmdString(DbgCommand cmd, int intArg1, int intArg2);
virtual int findPrompt(const QByteArray& output) const;
void parseMarker(CmdQueueItem* cmd);
};
#endif // GDBDRIVER_H

View file

@ -0,0 +1,42 @@
[Desktop Entry]
Exec=kdbg -caption "%c" %i
Icon=kdbg
Type=Application
X-DocPath=kdbg/index.html
Name=KDbg
GenericName=Debugger
GenericName[br]=Dizraener
GenericName[da]=Afluser
GenericName[es]=Depurador
GenericName[fi]=Debuggeri
GenericName[fr]=Débogueur
GenericName[is]=Aflúsun
GenericName[no]=Avluser
GenericName[pt]=Depurador
GenericName[pt_BR]=Depurador
GenericName[ro]=Depanator
GenericName[ru]=Отладчик
GenericName[sk]=Ladiaci program
GenericName[sl]=Razhroščevalnik
GenericName[sv]=Avlusare
Comment=Debug programs
Comment[br]=Goulevioù dizraenañ
Comment[ca]=Programes per localització d'errors
Comment[cs]=Ladídí program
Comment[da]=Afluseprogrammer
Comment[de]=Programme debuggen
Comment[es]=Depurador de programas
Comment[fi]=Tutki ohjelmien toimintaa
Comment[fr]=Déboguer un programme
Comment[is]=kdbg: Forrit til ađ aflúsa önnur forrit
Comment[no]=Avluse programmer
Comment[pl]=Program do debugowania
Comment[pt]=Depurador de programas
Comment[pt_BR]=Depurador de programas
Comment[ro]=Depanator de programe
Comment[ru]=Отлаживает программы
Comment[sk]=Ladiaci program
Comment[sl]=Odpravljanje napak v programih
Comment[sv]=Avlusar program
Terminal=false
Categories=Qt;KDE;Development;Debugger;

2
kdbg-2.5.5/kdbg/kdbgrc Normal file
View file

@ -0,0 +1,2 @@
[MainWindow]
State=AAAA/wAAAAD9AAAAAgAAAAEAAAFaAAABUfwCAAAAAfsAAAAMAEwAbwBjAGEAbABzAQAAAEcAAAFRAAAAYQD///8AAAADAAADdwAAAR38AQAAAAL8AAAAAAAAAhsAAADFAP////oAAAAAAQAAAAX7AAAACgBTAHQAYQBjAGsBAAAAAP////8AAABIAP////sAAAAWAEIAcgBlAGEAawBwAG8AaQBuAHQAcwEAAAAA/////wAAAMUA////+wAAAAwATwB1AHQAcAB1AHQBAAAAAP////8AAABIAP////sAAAAMAE0AZQBtAG8AcgB5AQAAAAD/////AAAAbAD////7AAAAEgBSAGUAZwBpAHMAdABlAHIAcwEAAAAA/////wAAAEgA/////AAAAh4AAAFZAAAAmwD////6AAAAAAEAAAAC+wAAAA4AVwBhAHQAYwBoAGUAcwEAAAAA/////wAAAJsA////+wAAAA4AVABoAHIAZQBhAGQAcwEAAAIeAAABWQAAAGwA////AAACGgAAAVEAAAAEAAAABAAAAAgAAAAI/AAAAAEAAAACAAAAAQAAABYAbQBhAGkAbgBUAG8AbwBsAEIAYQByAQAAAAAAAAN3AAAAAAAAAAA=

88
kdbg-2.5.5/kdbg/kdbgui.rc Normal file
View file

@ -0,0 +1,88 @@
<!DOCTYPE kpartgui>
<kpartgui name="kdbg" version="2">
<MenuBar>
<Menu name="file"><text>&amp;File</text>
<Action name="file_executable" append="open_merge"/>
<Action name="file_executable_recent"/>
<Action name="file_core_dump"/>
<Action name="file_reload" append="close_merge"/>
</Menu>
<Menu name="view"><text>&amp;View</text>
<Action name="view_find"/>
<Action name="view_findnext"/>
<Action name="view_findprev"/>
<Separator/>
<Action name="view_stack"/>
<Action name="view_locals"/>
<Action name="view_watched_expressions"/>
<Action name="view_registers"/>
<Action name="view_breakpoints"/>
<Action name="view_threads"/>
<Action name="view_output"/>
<Action name="view_memory"/>
</Menu>
<Menu name="execution"><text>E&amp;xecution</text>
<Action name="exec_run"/>
<Action name="exec_step_into"/>
<Action name="exec_step_over"/>
<Action name="exec_step_out"/>
<Action name="exec_run_to_cursor"/>
<Action name="exec_step_into_by_insn"/>
<Action name="exec_step_over_by_insn"/>
<Action name="exec_movepc"/>
<Separator/>
<Action name="exec_break"/>
<Action name="exec_kill"/>
<Action name="exec_restart"/>
<Action name="exec_attach"/>
<Separator/>
<Action name="exec_arguments"/>
</Menu>
<Menu name="breakpoint"><text>&amp;Breakpoint</text>
<Action name="breakpoint_set"/>
<Action name="breakpoint_set_temporary"/>
<Action name="breakpoint_enable"/>
</Menu>
<Menu name="settings"><text>&amp;Settings</text>
<Action name="settings_program"/>
<Action name="settings_global"/>
</Menu>
</MenuBar>
<Menu name="popup_files">
<Action name="file_open"/>
<Separator/>
<Action name="exec_step_into"/>
<Action name="exec_step_over"/>
<Action name="exec_step_out"/>
<Action name="exec_step_run_to_cursor"/>
<Action name="exec_movepc"/>
<Separator/>
<Action name="breakpoint_set"/>
</Menu>
<Menu name="popup_files_empty">
<Action name="file_open"/>
<Separator/>
<Action name="file_executable"/>
<Action name="file_core_dump"/>
</Menu>
<Menu name="popup_locals">
<Action name="watch_expression"/>
<Action name="edit_value"/>
</Menu>
<ToolBar name="mainToolBar">
<Action name="file_reload"/>
<Action name="file_executable"/>
<Separator/>
<Action name="exec_run"/>
<Action name="exec_step_into"/>
<Action name="exec_step_over"/>
<Action name="exec_step_out"/>
<Action name="exec_step_into_by_insn"/>
<Action name="exec_step_over_by_insn"/>
<Separator/>
<Action name="breakpoint_set"/>
<Separator/>
<Action name="view_find"/>
</ToolBar>
</kpartgui>

127
kdbg-2.5.5/kdbg/main.cpp Normal file
View file

@ -0,0 +1,127 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#include <kapplication.h>
#include <klocale.h> /* i18n */
#include <kmessagebox.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include "dbgmainwnd.h"
#include "typetable.h"
#include "version.h"
#include <stdlib.h> /* getenv(3) */
#include "mydebug.h"
int main(int argc, char** argv)
{
KAboutData aboutData("kdbg", "kdbg", ki18n("KDbg"),
KDBG_VERSION,
ki18n("A Debugger"),
KAboutData::License_GPL,
ki18n("(c) 1998-2015 Johannes Sixt"),
KLocalizedString(), /* any text */
"http://www.kdbg.org/",
"j6t@kdbg.org");
aboutData.addAuthor(ki18n("Johannes Sixt"), KLocalizedString(), "j6t@kdbg.org");
aboutData.addCredit(ki18n("Keith Isdale"),
ki18n("XSLT debugging"),
"k_isdale@tpg.com.au");
aboutData.addCredit(ki18n("Daniel Kristjansson"),
ki18n("Register groups and formatting"),
"danielk@cat.nyu.edu");
aboutData.addCredit(ki18n("David Edmundson"),
ki18n("KDE4 porting"),
"david@davidedmundson.co.uk");
KCmdLineArgs::init( argc, argv, &aboutData );
KCmdLineOptions opts;
opts.add("t <file>", ki18n("transcript of conversation with the debugger"));
opts.add("r <device>", ki18n("remote debugging via <device>"));
opts.add("l <language>", ki18n("specify language: C, XSLT"));
opts.add("x", ki18n("use language XSLT (deprecated)"));
opts.add("a <args>", ki18n("specify arguments of debugged executable"));
opts.add("p <pid>", ki18n("specify PID of process to debug"));
opts.add("+[program]", ki18n("path of executable to debug"));
opts.add("+[core]", ki18n("a core file to use"));
KCmdLineArgs::addCmdLineOptions(opts);
KApplication app;
KGlobal::dirs()->addResourceType("types", "data", "kdbg/types");
KGlobal::dirs()->addResourceType("sessions", "data", "kdbg/sessions");
DebuggerMainWnd* debugger = new DebuggerMainWnd;
debugger->setObjectName("mainwindow");
/* type libraries */
TypeTable::initTypeLibraries();
// session management
bool restored = false;
if (app.isSessionRestored()) {
if (KMainWindow::canBeRestored(1)) {
debugger->restore(1);
restored = true;
}
}
debugger->show();
// handle options
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
QString transcript = args->getOption("t");
QString remote = args->getOption("r");
if (!remote.isEmpty())
debugger->setRemoteDevice(remote);
QString lang = args->getOption("l");
// deprecated option; overrides -l
if (args->isSet("x")){
/* run in xsldbg mode */
lang = "xslt";
}
// check environment variable for transcript file name
if (transcript.isEmpty()) {
transcript = getenv("KDBG_TRANSCRIPT");
}
debugger->setTranscript(transcript);
QString pid = args->getOption("p");
QString programArgs = args->getOption("a");
if (!restored && args->count() > 0) {
// attach to process?
if (!pid.isEmpty()) {
TRACE("pid: " + pid);
debugger->setAttachPid(pid);
}
// check for core file; use it only if we're not attaching to a process
else if (args->count() > 1 && pid.isEmpty()) {
debugger->setCoreFile(args->arg(1));
}
if (!debugger->debugProgram(args->arg(0), lang)) {
// failed
TRACE("cannot start debugger");
KMessageBox::error(debugger, i18n("Cannot start debugger."));
debugger->setCoreFile(QString());
debugger->setAttachPid(QString());
} else {
if (!programArgs.isEmpty()) {
debugger->overrideProgramArguments(programArgs);
}
}
}
int rc = app.exec();
return rc;
}

View file

@ -0,0 +1,286 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#include "memwindow.h"
#include <QHeaderView>
#include <QMouseEvent>
#include <QList>
#include <klocale.h>
#include <kconfigbase.h>
#include <kconfiggroup.h>
#include "debugger.h"
MemoryWindow::MemoryWindow(QWidget* parent) :
QWidget(parent),
m_debugger(0),
m_expression(this),
m_memory(this),
m_layout(QBoxLayout::TopToBottom, this),
m_format(MDTword | MDThex)
{
m_expression.setEditable(true);
QSize minSize = m_expression.sizeHint();
m_expression.setMinimumSize(minSize);
m_expression.setInsertPolicy(QComboBox::NoInsert);
m_expression.setMaxCount(15);
m_memory.setColumnCount(9);
m_memory.setHeaderLabel(i18n("Address"));
for (int i = 1; i < 9; i++) {
m_memory.hideColumn(i);
m_memory.header()->setResizeMode(QHeaderView::ResizeToContents);
m_memory.headerItem()->setText(i, QString());
}
m_memory.header()->setStretchLastSection(false);
m_memory.setSortingEnabled(false); /* don't sort */
m_memory.setAllColumnsShowFocus(true);
m_memory.setRootIsDecorated(false);
m_memory.header()->setClickable(false);
m_memory.setContextMenuPolicy(Qt::NoContextMenu); // defer to parent
// create layout
m_layout.setSpacing(2);
m_layout.addWidget(&m_expression, 0);
m_layout.addWidget(&m_memory, 10);
m_layout.activate();
connect(&m_expression, SIGNAL(activated(const QString&)),
this, SLOT(slotNewExpression(const QString&)));
connect(m_expression.lineEdit(), SIGNAL(returnPressed()),
this, SLOT(slotNewExpression()));
// the popup menu
QAction* pAction;
pAction = m_popup.addAction(i18n("B&ytes"));
pAction->setData(MDTbyte);
pAction = m_popup.addAction(i18n("Halfwords (&2 Bytes)"));
pAction->setData(MDThalfword);
pAction = m_popup.addAction(i18n("Words (&4 Bytes)"));
pAction->setData(MDTword);
pAction = m_popup.addAction(i18n("Giantwords (&8 Bytes)"));
pAction->setData(MDTgiantword);
m_popup.addSeparator();
pAction = m_popup.addAction(i18n("He&xadecimal"));
pAction->setData(MDThex);
pAction = m_popup.addAction(i18n("Signed &decimal"));
pAction->setData(MDTsigned);
pAction = m_popup.addAction(i18n("&Unsigned decimal"));
pAction->setData(MDTunsigned);
pAction = m_popup.addAction(i18n("&Octal"));
pAction->setData(MDToctal);
pAction = m_popup.addAction(i18n("&Binary"));
pAction->setData(MDTbinary);
pAction = m_popup.addAction(i18n("&Addresses"));
pAction->setData(MDTaddress);
pAction = m_popup.addAction(i18n("&Character"));
pAction->setData(MDTchar);
pAction = m_popup.addAction(i18n("&Floatingpoint"));
pAction->setData(MDTfloat);
pAction = m_popup.addAction(i18n("&Strings"));
pAction->setData(MDTstring);
pAction = m_popup.addAction(i18n("&Instructions"));
pAction->setData(MDTinsn);
connect(&m_popup, SIGNAL(triggered(QAction*)), this, SLOT(slotTypeChange(QAction*)));
}
MemoryWindow::~MemoryWindow()
{
}
void MemoryWindow::contextMenuEvent(QContextMenuEvent* ev)
{
m_popup.popup(ev->globalPos());
ev->accept();
}
void MemoryWindow::slotNewExpression()
{
slotNewExpression(m_expression.lineEdit()->text());
}
void MemoryWindow::slotNewExpression(const QString& newText)
{
QString text = newText.simplified();
// see if the string is in the list
// (note: must count downwards because of removeItem!)
for (int i = m_expression.count()-1; i >= 0; i--)
{
if (m_expression.itemText(i) == text) {
// yes it is!
// look up the format that was used last time for this expr
QMap<QString,unsigned>::iterator pFormat = m_formatCache.find(text);
if (pFormat != m_formatCache.end()) {
m_format = *pFormat;
m_debugger->setMemoryFormat(m_format);
}
// remove this text, will be inserted at the top
m_expression.removeItem(i);
}
}
m_expression.insertItem(0, text);
if (!text.isEmpty()) {
m_formatCache[text] = m_format;
}
displayNewExpression(text);
}
void MemoryWindow::displayNewExpression(const QString& expr)
{
m_debugger->setMemoryExpression(expr);
m_expression.setEditText(expr);
// clear memory dump if no dump wanted
if (expr.isEmpty()) {
m_memory.clear();
m_old_memory.clear();
}
}
void MemoryWindow::slotTypeChange(QAction* action)
{
int id = action->data().toInt();
m_old_memory.clear();
// compute new type
if (id & MDTsizemask)
m_format = (m_format & ~MDTsizemask) | id;
if (id & MDTformatmask)
m_format = (m_format & ~MDTformatmask) | id;
m_debugger->setMemoryFormat(m_format);
// change the format in the cache
QString expr = m_expression.currentText();
m_formatCache[expr.simplified()] = m_format;
// force redisplay
displayNewExpression(expr);
}
void MemoryWindow::slotNewMemoryDump(const QString& msg, const std::list<MemoryDump>& memdump)
{
m_memory.clear();
if (!msg.isEmpty()) {
new QTreeWidgetItem(&m_memory, QStringList() << QString() << msg);
return;
}
std::list<MemoryDump>::const_iterator md = memdump.begin();
// show only needed columns
QStringList sl = md->dump.split( "\t" );
for (int i = m_memory.columnCount()-1; i > 0; i--)
m_memory.setColumnHidden(i, i > sl.count());
QMap<QString,QString> tmpMap;
for (; md != memdump.end(); ++md)
{
QString addr = md->address.asString() + " " + md->address.fnoffs;
QStringList sl = md->dump.split( "\t" );
// save memory
tmpMap[addr] = md->dump;
QTreeWidgetItem* line =
new QTreeWidgetItem(&m_memory, QStringList(addr) << sl);
QStringList tmplist;
QMap<QString,QString>::Iterator pos = m_old_memory.find( addr );
if( pos != m_old_memory.end() )
tmplist = pos.value().split( "\t" );
for (int i = 0; i < sl.count(); i++)
{
bool changed =
i < tmplist.count() &&
sl[i] != tmplist[i];
line->setForeground(i+1, changed ? QBrush(QColor(Qt::red)) : palette().text());
}
}
m_old_memory.clear();
m_old_memory = tmpMap;
}
static const char MemoryGroup[] = "Memory";
static const char NumExprs[] = "NumExprs";
static const char ExpressionFmt[] = "Expression%d";
static const char FormatFmt[] = "Format%d";
static const char ColumnWidths[] = "ColumnWidths";
void MemoryWindow::saveProgramSpecific(KConfigBase* config)
{
KConfigGroup g = config->group(MemoryGroup);
int numEntries = m_expression.count();
g.writeEntry(NumExprs, numEntries);
QString exprEntry;
QString fmtEntry;
for (int i = 0; i < numEntries;) {
QString text = m_expression.itemText(i);
i++; /* entries are counted 1-based */
exprEntry.sprintf(ExpressionFmt, i);
fmtEntry.sprintf(FormatFmt, i);
g.writeEntry(exprEntry, text);
QMap<QString,unsigned>::iterator pFormat = m_formatCache.find(text);
unsigned fmt = pFormat != m_formatCache.end() ? *pFormat : MDTword | MDThex;
g.writeEntry(fmtEntry, fmt);
}
// column widths
QList<int> widths;
for (int i = 0; i < 2; i++) {
int w = m_memory.columnWidth(i);
widths.append(w);
}
g.writeEntry(ColumnWidths, widths);
}
void MemoryWindow::restoreProgramSpecific(KConfigBase* config)
{
KConfigGroup g = config->group(MemoryGroup);
int numEntries = g.readEntry(NumExprs, 0);
m_expression.clear();
QString exprEntry;
QString fmtEntry;
// entries are counted 1-based
for (int i = 1; i <= numEntries; i++) {
exprEntry.sprintf(ExpressionFmt, i);
fmtEntry.sprintf(FormatFmt, i);
QString expr = g.readEntry(exprEntry, QString());
unsigned fmt = g.readEntry(fmtEntry, MDTword | MDThex);
m_expression.addItem(expr);
m_formatCache[expr] = fmt & (MDTsizemask | MDTformatmask);
}
// initialize with top expression
if (numEntries > 0) {
m_expression.setCurrentIndex(0);
QString expr = m_expression.itemText(0);
m_format = m_formatCache[expr];
m_debugger->setMemoryFormat(m_format);
displayNewExpression(expr);
}
// column widths
QList<int> widths = g.readEntry(ColumnWidths, QList<int>());
QList<int>::iterator w = widths.begin();
for (int i = 0; i < 2 && w != widths.end(); ++i, ++w) {
m_memory.setColumnWidth(i, *w);
}
}
#include "memwindow.moc"

View file

@ -0,0 +1,55 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef MEMWINDOW_H
#define MEMWINDOW_H
#include <QBoxLayout>
#include <QComboBox>
#include <QMap>
#include <QMenu>
#include <QTreeWidget>
#include "dbgdriver.h"
class KDebugger;
class KConfigBase;
class MemoryWindow : public QWidget
{
Q_OBJECT
public:
MemoryWindow(QWidget* parent);
~MemoryWindow();
void setDebugger(KDebugger* deb) { m_debugger = deb; }
protected:
KDebugger* m_debugger;
QComboBox m_expression;
QTreeWidget m_memory;
QMap<QString,QString> m_old_memory;
QBoxLayout m_layout;
unsigned m_format;
QMap<QString,unsigned> m_formatCache;
QMenu m_popup;
virtual void contextMenuEvent(QContextMenuEvent* ev);
void displayNewExpression(const QString& expr);
public slots:
void slotNewExpression(const QString&);
void slotNewExpression();
void slotTypeChange(QAction*);
void slotNewMemoryDump(const QString&, const std::list<MemoryDump>&);
void saveProgramSpecific(KConfigBase* config);
void restoreProgramSpecific(KConfigBase* config);
};
#endif // MEMWINDOW_H

25
kdbg-2.5.5/kdbg/mydebug.h Normal file
View file

@ -0,0 +1,25 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#include <kdebug.h>
#include <assert.h>
#include "config.h"
#ifdef ASSERT
#undef ASSERT
#endif
#ifdef NDEBUG
# define ASSERT(x) do {} while (0)
#else
# define ASSERT(x) kDebug(!(x)) << "assertion failed: " #x "\n"
#endif
#ifdef WANT_TRACE_OUTPUT
# define TRACE(x) kDebug() << (x)
#else
# define TRACE(x) do {} while (0)
#endif

223
kdbg-2.5.5/kdbg/pgmargs.cpp Normal file
View file

@ -0,0 +1,223 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#include "pgmargs.h"
#include <kfiledialog.h>
#include <klocale.h> /* i18n */
#include "mydebug.h"
PgmArgs::PgmArgs(QWidget* parent, const QString& pgm,
const std::map<QString,QString>& envVars,
const QStringList& allOptions) :
QDialog(parent)
{
setupUi(this);
{
QFileInfo fi = pgm;
QString newText = labelArgs->text().arg(fi.fileName());
labelArgs->setText(newText);
}
// add options only if the option list is non-empty
if (!allOptions.isEmpty())
{
xsldbgOptions->addItems(allOptions);
}
else
{
delete xsldbgOptionsPage;
xsldbgOptionsPage = 0;
}
EnvVar val;
val.status = EnvVar::EVclean;
for (std::map<QString,QString>::const_iterator i = envVars.begin(); i != envVars.end(); ++i)
{
val.value = i->second;
val.item = new QTreeWidgetItem(envList, QStringList() << i->first << i->second);
m_envVars[i->first] = val;
}
envList->setAllColumnsShowFocus(true);
buttonDelete->setEnabled(envList->currentItem() != 0);
}
PgmArgs::~PgmArgs()
{
}
// initializes the selected options
void PgmArgs::setOptions(const QSet<QString>& selectedOptions)
{
if (xsldbgOptionsPage == 0)
return;
for (int i = 0; i < xsldbgOptions->count(); i++) {
if (selectedOptions.contains(xsldbgOptions->item(i)->text()))
{
xsldbgOptions->item(i)->setSelected(true);
}
}
}
// returns the selected options
QSet<QString> PgmArgs::options() const
{
QSet<QString> sel;
if (xsldbgOptionsPage != 0)
{
for (int i = 0; i < xsldbgOptions->count(); i++) {
if (xsldbgOptions->item(i)->isSelected())
sel.insert(xsldbgOptions->item(i)->text());
}
}
return sel;
}
// this is a slot
void PgmArgs::on_buttonModify_clicked()
{
modifyVar(true); // re-add deleted entries
}
void PgmArgs::modifyVar(bool resurrect)
{
QString name, value;
parseEnvInput(name, value);
if (name.isEmpty() || name.indexOf(' ') >= 0) // disallow spaces in names
return;
// lookup the value in the dictionary
EnvVar* val;
std::map<QString,EnvVar>::iterator i = m_envVars.find(name);
if (i != m_envVars.end()) {
val = &i->second;
// see if this is a zombie
if (val->status == EnvVar::EVdeleted) {
// resurrect
if (resurrect)
{
val->value = value;
val->status = EnvVar::EVdirty;
val->item = new QTreeWidgetItem(envList, QStringList() << name << value);
}
} else if (value != val->value) {
// change the value
val->value = value;
val->status = EnvVar::EVdirty;
val->item->setText(1, value);
}
} else {
// add the value
val = &m_envVars[name];
val->value = value;
val->status = EnvVar::EVnew;
val->item = new QTreeWidgetItem(envList, QStringList() << name << value);
}
envList->setCurrentItem(val->item);
buttonDelete->setEnabled(true);
}
// delete the selected item
void PgmArgs::on_buttonDelete_clicked()
{
QTreeWidgetItem* item = envList->currentItem();
if (item == 0)
return;
QString name = item->text(0);
// lookup the value in the dictionary
std::map<QString,EnvVar>::iterator i = m_envVars.find(name);
if (i != m_envVars.end())
{
EnvVar* val = &i->second;
// delete from list
val->item = 0;
// if this is a new item, delete it completely, otherwise zombie-ize it
if (val->status == EnvVar::EVnew) {
m_envVars.erase(i);
} else {
// mark value deleted
val->status = EnvVar::EVdeleted;
}
}
delete item;
// there is no selected item anymore
buttonDelete->setEnabled(false);
}
void PgmArgs::parseEnvInput(QString& name, QString& value)
{
// parse input from edit field
QString input = envVar->text();
int equalSign = input.indexOf('=');
if (equalSign >= 0) {
name = input.left(equalSign).trimmed();
value = input.mid(equalSign+1);
} else {
name = input.trimmed();
value = QString(); /* value is empty */
}
}
void PgmArgs::on_envList_currentItemChanged()
{
QTreeWidgetItem* item = envList->currentItem();
buttonDelete->setEnabled(item != 0);
if (item == 0)
return;
// must get name from list box
QString name = item->text(0);
envVar->setText(name + "=" + m_envVars[name].value);
}
void PgmArgs::accept()
{
// simulate that the Modify button was pressed, but don't revive
// dead entries even if the user changed the edit box
modifyVar(false);
QDialog::accept();
}
void PgmArgs::on_wdBrowse_clicked()
{
// browse for the working directory
QString newDir = KFileDialog::getExistingDirectory(wd(), this);
if (!newDir.isEmpty()) {
setWd(newDir);
}
}
void PgmArgs::on_insertFile_clicked()
{
QString caption = i18n("Select a file name to insert as program argument");
// use the selection as default
QString f = programArgs->selectedText();
f = KFileDialog::getSaveFileName(f, QString::null,
this, caption);
// don't clear the selection if no file was selected
if (!f.isEmpty()) {
programArgs->insert(f);
}
}
void PgmArgs::on_insertDir_clicked()
{
QString caption = i18n("Select a directory to insert as program argument");
// use the selection as default
QString f = programArgs->selectedText();
f = KFileDialog::getExistingDirectory(f, this, caption);
// don't clear the selection if no file was selected
if (!f.isEmpty()) {
programArgs->insert(f);
}
}
#include "pgmargs.moc"

51
kdbg-2.5.5/kdbg/pgmargs.h Normal file
View file

@ -0,0 +1,51 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef PgmArgs_included
#define PgmArgs_included
#include "ui_pgmargsbase.h"
#include <QDialog>
#include <QSet>
#include <map>
#include "envvar.h"
class QStringList;
class PgmArgs : public QDialog, private Ui::PgmArgsBase
{
Q_OBJECT
public:
PgmArgs(QWidget* parent, const QString& pgm,
const std::map<QString,QString>& envVars,
const QStringList& allOptions);
virtual ~PgmArgs();
void setArgs(const QString& text) { programArgs->setText(text); }
QString args() const { return programArgs->text(); }
void setOptions(const QSet<QString>& selectedOptions);
QSet<QString> options() const;
void setWd(const QString& wd) { wdEdit->setText(wd); }
QString wd() const { return wdEdit->text(); }
const std::map<QString,EnvVar>& envVars() { return m_envVars; }
protected:
std::map<QString,EnvVar> m_envVars;
void parseEnvInput(QString& name, QString& value);
void modifyVar(bool resurrect);
virtual void accept();
protected slots:
void on_buttonModify_clicked();
void on_buttonDelete_clicked();
void on_envList_currentItemChanged();
void on_wdBrowse_clicked();
void on_insertFile_clicked();
void on_insertDir_clicked();
};
#endif // PgmArgs_included

View file

@ -0,0 +1,372 @@
<ui version="4.0" >
<class>PgmArgsBase</class>
<widget class="QDialog" name="PgmArgsBase" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>528</width>
<height>410</height>
</rect>
</property>
<property name="windowTitle" >
<string>Program Arguments</string>
</property>
<property name="sizeGripEnabled" >
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QTabWidget" name="tabWidget" >
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="argsPage" >
<attribute name="title" >
<string>&amp;Arguments</string>
</attribute>
<layout class="QHBoxLayout" >
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="labelArgs" >
<property name="text" >
<string>Run &lt;i>%1&lt;/i> with these arguments:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
<property name="buddy" >
<cstring>programArgs</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="programArgs" >
<property name="whatsThis" >
<string>Specify the arguments with which the program shall be invoked for this debugging session. You specify the arguments just as you would on the command line, that is, you can even use quotes and environment variables, for example:&lt;p>&lt;tt>--message 'start in: ' $HOME&lt;/tt></string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<item>
<widget class="QPushButton" name="insertFile" >
<property name="whatsThis" >
<string>Browse for a file; the full path name will be inserted at the current cursor location in the edit box above.</string>
</property>
<property name="text" >
<string>Insert &amp;file name...</string>
</property>
<property name="shortcut" >
<string>Alt+F</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="insertDir" >
<property name="whatsThis" >
<string>Browse for a directory; the full path name will be inserted at the current cursor location in the edit box above.</string>
</property>
<property name="text" >
<string>Insert &amp;directory name...</string>
</property>
<property name="shortcut" >
<string>Alt+D</string>
</property>
</widget>
</item>
<item>
<spacer name="spacer1" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>61</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="spacer2" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>81</width>
<height>180</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="wdPage" >
<attribute name="title" >
<string>&amp;Working Directory</string>
</attribute>
<layout class="QHBoxLayout" >
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QLineEdit" name="wdEdit" >
<property name="whatsThis" >
<string>Specify here the initial working directory where the program is run.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<item>
<widget class="QPushButton" name="wdBrowse" >
<property name="whatsThis" >
<string>Browse for the initial working directory where the program is run.</string>
</property>
<property name="text" >
<string>&amp;Browse...</string>
</property>
<property name="shortcut" >
<string>Alt+B</string>
</property>
</widget>
</item>
<item>
<spacer name="spacer4" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>321</width>
<height>31</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="spacer5" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>111</width>
<height>161</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="envPage" >
<attribute name="title" >
<string>&amp;Environment</string>
</attribute>
<layout class="QHBoxLayout" >
<item>
<layout class="QHBoxLayout" >
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="envLabel" >
<property name="text" >
<string>Environment variables (&lt;tt>NAME=value&lt;/tt>):</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
<property name="buddy" >
<cstring>envVar</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="envVar" >
<property name="whatsThis" >
<string>To add a new environment variable or to modify one, specify it here in the form &lt;tt>NAME=value&lt;/tt> and click &lt;b>Modify&lt;/b>.</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="envList" >
<property name="whatsThis" >
<string>Environment variables that are set &lt;i>in addition&lt;/i> to those that are inherited are listed in this table. To add new environment variables, specify them as &lt;tt>NAME=value&lt;/tt> in the edit box above and click &lt;b>Modify&lt;/b>. To modify a value, select it in this list and click &lt;b>Modify&lt;/b>. To delete an environment variable, select it in this list and click &lt;b>Delete&lt;/b>.</string>
</property>
<property name="rootIsDecorated" >
<bool>false</bool>
</property>
<property name="itemsExpandable" >
<bool>false</bool>
</property>
<property name="allColumnsShowFocus" >
<bool>true</bool>
</property>
<column>
<property name="text" >
<string>Name</string>
</property>
</column>
<column>
<property name="text" >
<string>Value</string>
</property>
</column>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QPushButton" name="buttonModify" >
<property name="whatsThis" >
<string>Enters the environment variable that is currently specified in the edit box into the list. If the named variable is already in the list, it receives a new value; otherwise, a new entry is created.</string>
</property>
<property name="text" >
<string>&amp;Modify</string>
</property>
<property name="shortcut" >
<string>Alt+M</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonDelete" >
<property name="whatsThis" >
<string>Deletes the selected environment variable from the list. This cannot be used to delete environment variables that are inherited.</string>
</property>
<property name="text" >
<string>&amp;Delete</string>
</property>
<property name="shortcut" >
<string>Alt+D</string>
</property>
</widget>
</item>
<item>
<spacer name="spacer6" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>51</width>
<height>141</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="xsldbgOptionsPage" >
<attribute name="title" >
<string>&amp;xsldbg Options</string>
</attribute>
<layout class="QHBoxLayout" >
<item>
<widget class="QListWidget" name="xsldbgOptions" >
<property name="selectionMode" >
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="KDialogButtonBox" name="kdialogbuttonbox" >
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11" />
<customwidgets>
<customwidget>
<class>KDialogButtonBox</class>
<extends>QDialogButtonBox</extends>
<header>kdialogbuttonbox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>tabWidget</tabstop>
<tabstop>programArgs</tabstop>
<tabstop>insertFile</tabstop>
<tabstop>insertDir</tabstop>
<tabstop>wdEdit</tabstop>
<tabstop>wdBrowse</tabstop>
<tabstop>envVar</tabstop>
<tabstop>buttonModify</tabstop>
<tabstop>buttonDelete</tabstop>
<tabstop>envList</tabstop>
<tabstop>xsldbgOptions</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>kdialogbuttonbox</sender>
<signal>accepted()</signal>
<receiver>PgmArgsBase</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>440</x>
<y>575</y>
</hint>
<hint type="destinationlabel" >
<x>440</x>
<y>591</y>
</hint>
</hints>
</connection>
<connection>
<sender>kdialogbuttonbox</sender>
<signal>rejected()</signal>
<receiver>PgmArgsBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>521</x>
<y>580</y>
</hint>
<hint type="destinationlabel" >
<x>549</x>
<y>588</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -0,0 +1,111 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#include "pgmsettings.h"
#include <klocale.h> /* i18n */
#include <kglobal.h>
#include <QFileInfo>
#include <QLineEdit>
#include <QLabel>
#include <QRadioButton>
#include <QButtonGroup>
#include <QVBoxLayout>
#include "mydebug.h"
ChooseDriver::ChooseDriver(QWidget* parent) :
QWidget(parent)
{
QVBoxLayout* layout = new QVBoxLayout(this);
QLabel* label = new QLabel(this);
label->setText(i18n("How to invoke &GDB - leave empty to use\n"
"the default from the global options:"));
label->setMinimumSize(label->sizeHint());
layout->addWidget(label);
m_debuggerCmd = new QLineEdit(this);
m_debuggerCmd->setMinimumSize(m_debuggerCmd->sizeHint());
layout->addWidget(m_debuggerCmd);
label->setBuddy(m_debuggerCmd);
layout->addStretch();
this->setLayout(layout);
}
void ChooseDriver::setDebuggerCmd(const QString& cmd)
{
m_debuggerCmd->setText(cmd);
}
QString ChooseDriver::debuggerCmd() const
{
return m_debuggerCmd->text();
}
OutputSettings::OutputSettings(QWidget* parent) :
QWidget(parent)
{
m_group = new QButtonGroup(this);
QVBoxLayout* layout = new QVBoxLayout(this);
QRadioButton* btn;
btn = new QRadioButton(i18n("&No input and output"), this);
m_group->addButton(btn, 0);
layout->addWidget(btn);
btn = new QRadioButton(i18n("&Only output, simple terminal emulation"), this);
m_group->addButton(btn, 1);
layout->addWidget(btn);
btn = new QRadioButton(i18n("&Full terminal emulation"), this);
m_group->addButton(btn, 7);
layout->addWidget(btn);
layout->addStretch();
this->setLayout(layout);
// there is no simpler way to get to the active button than
// to connect to a signal
connect(m_group, SIGNAL(buttonClicked(int)), SLOT(slotLevelChanged(int)));
}
void OutputSettings::setTTYLevel(int l)
{
QAbstractButton* button = m_group->button(l);
Q_ASSERT(button);
button->setChecked(true);
m_ttyLevel = l;
}
void OutputSettings::slotLevelChanged(int id)
{
m_ttyLevel = id;
TRACE("new ttyLevel: " + QString().setNum(id));
}
ProgramSettings::ProgramSettings(QWidget* parent, QString exeName) :
KPageDialog(parent),
m_chooseDriver(this),
m_output(this)
{
// construct title
QFileInfo fi(exeName);
QString cap = KGlobal::caption();
QString title = i18n("%1: Settings for %2");
setCaption(title.arg(cap, fi.fileName()));
addPage(&m_chooseDriver, i18n("Debugger"));
addPage(&m_output, i18n("Output"));
}
#include "pgmsettings.moc"

View file

@ -0,0 +1,53 @@
/*
* Copyright Johannes Sixt
* This file is licensed under the GNU General Public License Version 2.
* See the file COPYING in the toplevel directory of the source directory.
*/
#ifndef PGMSETTINGS_H
#define PGMSETTINGS_H
#include <KPageDialog>
class QButtonGroup;
class QLineEdit;
class ChooseDriver : public QWidget
{
public:
ChooseDriver(QWidget* parent);
void setDebuggerCmd(const QString& cmd);
QString debuggerCmd() const;
protected:
QLineEdit* m_debuggerCmd;
};
class OutputSettings : public QWidget
{
Q_OBJECT
public:
OutputSettings(QWidget* parent);
void setTTYLevel(int l);
int ttyLevel() const { return m_ttyLevel; }
protected:
int m_ttyLevel;
QButtonGroup* m_group;
protected slots:
void slotLevelChanged(int);
};
class ProgramSettings : public KPageDialog
{
Q_OBJECT
public:
ProgramSettings(QWidget* parent, QString exeName);
public:
ChooseDriver m_chooseDriver;
OutputSettings m_output;
};
#endif

Some files were not shown because too many files have changed in this diff Show more