From d25245fe76e6b975515d0d39636b38d08c5a9c61 Mon Sep 17 00:00:00 2001
From: Ray-V Choose Execution|Arguments to open a dialog where you can set program
+arguments, the working directory for your program, and environment variables. In the edit box enter the arguments that shall be passed on to your
+program. Insert file name lets you browse for a file;
+the file name will be inserted in the edit box (at the cursor position). Next time the program is started, the new arguments will be used. In the edit box you can specify the working directory for your program.
+Browse lets you browse for a directory.
+Your program will use the new directory only when it is run the next time. 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 OK. This can influence whether
+source code files are found. 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 VARIABLE=value
+to set the environment variable VARIABLE to the value value,
+and click Modify. To remove a variable, select it from the list
+below and click Delete. To change the value, edit the value in the
+edit field and click Modify. If you change the name of the variable
+and click Modify, you add a new variable! The new environment variables
+will be used by your program the next time it is run. This tab is only available when a XSLT script is
+debugged. Here you can specify various flags that influence the
+XSL translation and XSLDBG. The breakpoint list displays all breakpoints and watchpoints that are set
+and allows you to manipulate them. It can be displayed using View|Breakpoints. For each breakpoint the following is shown: 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 orphaned
+(a 'x' is overlaid). Watchpoints are indicated by an eye glas icon in front of the line. Orphaned breakpoints 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. But there is an important consequence: Orphaned breakpoints are not effective,
+and the program will not 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 main()
+and for dynamically loaded modules it is after the call to dlopen()
+(or equivalent). When the program stops at this breakpoint the orphaned
+breakpoints from the dynamic module are set and become effective. 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 Execution|Break. Note
+that this will not terminate the program, it just interrupts it. You can
+now manipulate the breakpoints; then choose Execution|Continue to
+let the program continue. 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 Add Breakpoint. You can disable and enable breakpoints by selecting them in the list
+and clicking Disable or Enable. 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. 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 Conditional button and enter the condition and/or ignore
+count. 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 above
+for more information. To set a watchpoint, type an expression in the edit box above the list,
+then click Add Watchpoint. 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 Execution|Break). To remove the watchpoint, select it from the list and click Remove.
+If the expression involves a local variable, the watchpoint will be removed
+automatically when the program leaves the current frame. You can set a condition and an ignore count on the watchpoint just like
+on breakpoints by selecting it and clicking Conditional. To specify some global options, choose Settings|Global Options. You
+can set the following: There's more than one way to set a breakpoint: 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
+Execution|Break.
+If you still can't set breakpoints, make sure that you have compiled and
+linked your program with debugging information enabled. Use the Watch window. Watchpoints are manipulated in the breakpoint
+list. First load the executable using File|Executable, then specify the
+core dump using File|Core dump. Start the program and let it run until it is in the endless loop. Then
+switch to KDbg and choose Execution|Break. You've just caught the
+nasty program in flagranti! In the breakpoint list select the breakpoint;
+then click Conditional and specify the number of times to skip the
+breakpoint in the Ignore count field. Select Execution|Arguments and specify the environment variables
+in the program arguments dialog. Select Execution|Arguments and specify the working directory in
+the program arguments dialog. Select Settings|This Program and switch to the Output tab.
+Select Only output, simple terminal emulation and click OK.
+Now restart the program (choose it from the list under File|Recent Executables).
+The program output goes now to the built-in output
+window and stdin is redirected to /dev/null. You must do this for every new program that you debug. Important: 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. KDbg is a front-end for gdb, the GNU debugger. This means that KDbg itself is not the debugger. Rather, it communicates
+with gdb, 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 gdb commands, and the output of gdb
+is translated into (more or less) visible information, such as structured
+variable contents. The upshot of all this is that KDbg completely relies on the capabilities
+of the underlying command line debugger, gdb. KDbg can do no more
+than gdb can. For example, if you have a gdb that does
+not supports debugging of threaded programs, KDbg cannot, either (even
+though it offers a threads window). Before you start using KDbg, you may want to review the options in the
+Global Options dialog that you invoke
+with Settings|Global Options. To debug a program, choose File|Executable from the menu. If you
+have debugged the program earlier, you can choose it from File|Recent
+Executables. The program is loaded. If you want to debug a core dump, you must first load the executable
+that produced the core dump, then choose
+File|Core Dump from the
+menu. Now KDbg goes to the point in the program that caused the core dump. You can now set breakpoints, using the Breakpoint menu, the right
+mouse button menu, or the breakpoint window. You can also choose program specific settings that apply only to the
+currently loaded executable using Settings|This Program, in the
+Program Settings dialog. Furthermore, it is possible to debug XSLT scripts. Now run the program by selecting Execution|Run. The program now
+executes as usual until it either exits, hits a breakpoint or watchpoint,
+or receives a signal. You can run the program with arguments, set a working directory, or
+set environment variables. To do this, choose Execution|Arguments
+and specify your options in the Program Arguments
+dialog (before you start the program). You can also attach to a program that is currently running. To do this,
+first load the executable file like above. Then choose Execution|Attach.
+From the list processes specify the one you want to attach to
+and click OK. The running program is
+halted (not terminated), and the current point of execution is displayed
+in the source window. 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. When the program stops at a breakpoint, watchpoint, or due to a signal,
+the source code window displays the line
+where the program stopped. It is very common that the program stops due
+to a signal (usually a SIGSEGV, segmentation violation) in a function
+that is not part of the program, that you have written. In this case you
+investigate the stack window 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. In the menu Execution you find the commands that you need to
+run
+the program, step through code, and to interrupt the program (Break)
+while it is running. The important commands (Run and all kinds of
+Step) are bound to function keys. For efficient debugging it is
+strongly recommend that you get used to using them. You can use
+Settings|Configure Shortcuts if you want to bind the functions
+to different keys. In the menu Breakpoint you find commands to set, clear, disable,
+and enable permanent and temporary breakpoints. You can display a list
+of breakpoints in the breakpoints window.
+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. 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 Execution|Break. KDbg displays information and accepts commands in number of different windows.
+In the menu View 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. The following topics give some useful hints on using KDbg. KDbg is written by Johannes Sixt
+with contributions from these people (in no particular order): KDbg homepage is at http://www.kdbg.org/.
+Specifying program arguments, working directory, environment variables
+Tab Arguments
+Tab Working Directory
+Tab Environment
+Tab xsldbg Settings
+
+The Breakpoint List
+
+The list of breakpoints
+
+
+
+Orphaned breakpoints
+
+Manipulating breakpoints
+
+Manipulating watchpoints
+
+Global Options Dialog
+
+
+
+
+How to invoke gdb
+
+If you want to use a different version of gdb, you can specify
+it under
+How to invoke GDB. The default command is gdb --fullname
+--nx. 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.
+
+
+How to invoke a terminal emulator
+
+If you want to use a different terminal program to show the
+output of the program, specify it under Terminal for program output.
+The default setting is xterm -name kdbgio -title %T -e sh -c %C.
+In this entry,
+%T will be replaced by a title string, %C
+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 sleep
+3600 in a loop :) An alternative for this setting could be konsole
+--name kdbgio --caption %T -e sh -c %C.
+
+
+Pop into foreground
+
+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.
+
+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 Step
+commands.
+
+
+File filters
+
+You can specify wildcards for source files and header files,
+which are used in the file dialog of the File|Open Source
+command.
+
+
+
diff --git a/doc/en/howdoi.html b/doc/en/howdoi.html
new file mode 100644
index 0000000..6191144
--- /dev/null
+++ b/doc/en/howdoi.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+How Do I...?
+
+
+... set breakpoints?
+
+
+
+... display the value of a global variable or an arbitrary expression?
+
+... set watchpoints?
+
+... use a core dump?
+
+... debug a program that's caught in an endless loop?
+
+... achieve that the program passes over a breakpoint a number of times
+before it stops?
+
+... set environment variables for the executable?
+
+... set a working directory for the executable?
+
+... get rid of this terminal window?
+
+KDbg - User's Manual
+
+
+Contents
+
+
+
+
+
+
+Introduction
+
+Using KDbg
+
+Specifying a debugging target
+
+Running the program
+
+The program stopped - now what?
+
+KDbg's information windows
+
+
+
+
+Tips and such
+
+
+
+
+Author
+
+
+Invoking KDbg from the command line
+
+Usage: kdbg [TQt-options] [KDE-options] [options] [program] [core]
+
+Generic options:
+ --help Show help about options
+ --help-qt Show TQt 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 <file> transcript of conversation with the debugger
+ -r <device> remote debugging via <device>
+ -l <language> specify language: C, XSLT []
+ -p <pid> specify PID of process to debug
+
+Arguments:
+ program path of executable to debug
+ core a core file to use
+
The local variables window is opened using View|Locals. The local +variables window displays the contents of the local variables at the currently +selected stack frame.
+The set of local variables that are displayed is determined by the stack +frame that is selected in the stack window.
+Variable values that changed between stops of the program are displayed +in red color.
+The values of most variables can be changed. For this purpose, press F2 +while the input focus is in the window or choose Edit value from the +context menu. Then edit the value and hit Enter. Note that you cannot modify +the strings that char* values point to in this way, just the pointer +value.
+Using the context menu you can move +the active variable or structure member to the watched +expressions window.
+ + diff --git a/doc/en/memory.html b/doc/en/memory.html new file mode 100644 index 0000000..75693f9 --- /dev/null +++ b/doc/en/memory.html @@ -0,0 +1,26 @@ + + + + + +The memory dump window is displayed using View|Memory. It displays +the contents of the program's memory at arbitrary adresses.
+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.
+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.
+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.
+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.
+ + diff --git a/doc/en/pgmoutput.html b/doc/en/pgmoutput.html new file mode 100644 index 0000000..3e18902 --- /dev/null +++ b/doc/en/pgmoutput.html @@ -0,0 +1,46 @@ + + + + + +The program output window is displayed using View|Output. The output +window captures text that is written to stdout and stderr by the program +being debugged.
+The output window does not allow to type input for the program and it +features only minimal terminal emulation: \n (line-feed), +\t (horizontal tab), and \r (carriage-return) +are treated. These capabilities are usually sufficient to debug GUI programs +which only write debugging output to stdout and stderr.
+When a program is debugged with KDbg for the first time, the program +output window is not 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:
+You can clear the contents of the output window by selecting Clear +from the popup menu that appears when you click the right mouse button.
+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.
+ + diff --git a/doc/en/pgmsettings.html b/doc/en/pgmsettings.html new file mode 100644 index 0000000..64225fb --- /dev/null +++ b/doc/en/pgmsettings.html @@ -0,0 +1,81 @@ + + + + + +In this dialog, program specific settings can be selected. It is invoked +by Settings|This Program. The settings apply only to the currently loaded +executable and will be saved across sessions.
+Important note: The chosen settings will only +apply the next time the executable is loaded into KDbg. This means that +after pressing +OK in this dialog, you must reload the executable +using File|Recent Executables!!+ + + +
In this section, the debugger to be used for the program can be chosen.
+Enter the command to invoke gdb. Leave this field empty to +use the default gdb command as specified in the global +options. 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 gdb --fullname --nx. Be sure to specify +at least --fullname if you change the gdb command. +If you remove this command switch, KDbg will not work. ++ +
In this section, the terminal emulation under which the program will run +can be selected.
+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 stdout and stderr (if any). All three standard channels +(stdin, stdout, and stderr) are effectively +redirected to /dev/null.+ +
Check this option if your program does not receive input from +the terminal (stdin will be redirected to /dev/null), +and the output that it writes to stdout and stderr does +not require sophisticated terminal emulation. The output will be shown +in the Output window. ++ +
Important: The integrated terminal emulator will only interpret +the line-feed character \n (ASCII 10) to break lines. It will +not +handle the carriage-return character \r (ASCII 13). This is sufficient +for displaying plain debugging output that is often used by developers +of GUI programs.
Check this option if your program reads input from stdin +or if the output to stdout or stderr requires terminal +emulation. A terminal emulator will be invoked as specified in the global +options.+ + + diff --git a/doc/en/registers.html b/doc/en/registers.html new file mode 100644 index 0000000..fc9fb5b --- /dev/null +++ b/doc/en/registers.html @@ -0,0 +1,35 @@ + + + + + +
Whenever the program stops, KDbg displays the contents of the CPU registers +in the register dump window. To display this window, choose View|Registers.
+The registers are grouped by the kind of register. The window contains 3 columns:
+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.
+ + diff --git a/doc/en/sourcecode.html b/doc/en/sourcecode.html new file mode 100644 index 0000000..9d1bb7f --- /dev/null +++ b/doc/en/sourcecode.html @@ -0,0 +1,28 @@ + + + + + +The source code window is the main window and is always visible.
+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.
+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.
+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.
+Mostly, source code windows are opened automatically. To open a new +source file manually, click the right mouse button and choose Open Source +or choose File|Open Source.
+ + diff --git a/doc/en/stack.html b/doc/en/stack.html new file mode 100644 index 0000000..0db570b --- /dev/null +++ b/doc/en/stack.html @@ -0,0 +1,23 @@ + + + + + +The stack window is displayed using View|Stack. The stack window +lists the stack frames, i.e. the functions that the program has entered, +but not yet left.
+The innermost frame (where the program currently executes) is shown +at the top.
+To switch to a different stack frame, simply click on that stack frame. +The source window displays the source line +where the function invocation took place and the local +variables window and the watch window change +to reflect the local variables of the selected stack frame.
+ + diff --git a/doc/en/threads.html b/doc/en/threads.html new file mode 100644 index 0000000..3f0d7fb --- /dev/null +++ b/doc/en/threads.html @@ -0,0 +1,42 @@ + + + + + +The threads window is displayed using View|Threads. The threads +window lists the active threads of the program.
+Note: 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).
+The contents of the threads window are updated every time the program +is stopped by the debugger. (That is, the window does not reflect +the state while the program is running.)
+The first column shows the thread ID, the second column identifies the +location where the thread currently executes.
+The marker in front of the line tells which thread currently is active:
+By clicking a listed thread, the active thread is switched, and the corresponding +windows are updated. In particular, the source +window displays the location where the active thread is currently halted.
+ + diff --git a/doc/en/tips.html b/doc/en/tips.html new file mode 100644 index 0000000..6a0292a --- /dev/null +++ b/doc/en/tips.html @@ -0,0 +1,47 @@ + + + + + ++LD_ASSUME_KERNEL=2.4.19 kdbg myprogram +I.e. you run KDbg from the command line such that the old +Linuxthreads implementation is used.
KDbg can display a short description of structured types, so +that it is not necessary to expand the variable in the local +variables window or watched expressions window. +The information which member variable is displayed is stored in type +tables. There is generally one type table per shared library.
+ +KDbg's default type tables are located under $prefix/share/apps/kdbg/types. +User defined type tables can be placed in ${TDEHOME}/share/apps/kdbg/types, where +${TDEHOME} is ~/.kde if it is not a defined environment variable. +The file names end with .kdbgtt. Example: The type table for libqt.so +is named qt.kdbgtt. +User defined type tables override the type tables provided by the system.
+A type table file obeys the regular KDE configuration file syntax. The +file has the following groups:
+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 ShlibRE 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.
+KDbg's type recognition only works for libraries that are linked dynamically +to the program being debugged.
+This group contains the following entries:
+In the case of regular types the names of types should follow the output of the +whatis gdb command less any const, spaces, or trailing +&. +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). +
+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.
+ +There is one group for each type that is named exactly as the type. At +the moment C++ template classes are not supported. Each group contains +the following entries:
+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.
+KDbg recognizes a special extension that is used to display TQt 2.x's and TQt 3.x's +unicode strings: If an Exprx is prepended with /TQString::Data, +it is assumed that the result of the expression is a pointer to a TQString::Data. +The value displayed is the unicode string that this instance of TQString::Data +represents (which can be TQString::null if it is TQt's well-defined +null string or (null) if the unicode member is the null +pointer). See qt2.kdbgtt for examples.
+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 +Alias +entry to quickly specify that a type should be treated like a non-leftmost +base class for a multiple-inheritance class.
+The example shows how TQString and TQRect are defined +in qt3.kdbgtt. Furthermore, the template type TQValueVector +is defined. This example applies to TQt 3.x, which is located in shared library +whose name ends in libtqt-mt.so.3.
+[Type Table] +Types1=TQString,TQRect +Types2=TQValueVector +LibDisplayName=libqt 3.x +ShlibRE=libtqt-mt\.so\.3$ +EnableBuiltin=TQString::Data,TQCharIsShort + +[TQString] +Display={ % } +Expr1=/TQString::Data (%s).d + +[TQValueVector] +Template=TQValueVector<*> +Display={ size=% shared=% capacity=% } +Expr1=($tmp=(%s).sh)->finish-$tmp->start +Expr2=(%s).sh->count +Expr3=($tmp=(%s).sh)->end-$tmp->start + +[TQRect] +Display={ tl=(%,%) br=(%,%) } +Expr1=(%s).x1 +Expr2=(%s).y1 +Expr3=(%s).x2 +Expr4=(%s).y2+
This example shows these features:
+The watched expressions window is opened using View|Watched Expressions. +It displays arbitrary expressions.
+To add an expression, type it into the edit field and press Enter or +click Add. To remove an expression, click on it (choose the root +of the expression) and click Del.
+You can also move a variable or structure member from the local +variables window to this window using the context menu in the local +variables window.
+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 char* values point +to in this way, just the pointer value.
+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.
+ + diff --git a/doc/en/xslt.html b/doc/en/xslt.html new file mode 100644 index 0000000..fdc5ec3 --- /dev/null +++ b/doc/en/xslt.html @@ -0,0 +1,24 @@ + + + + + +KDbg allows to debug XSLT (XML stylesheet translation) scripts using +xsldbg, which must be available +on your system.
+XSLT mode is automatically entered if a "program" is loaded +that has a file name that ends in .xsl. In addition, the +command line option -l XSL can be +specified to explicitly choose this mode.
+To debug an XSLT script it is necessary to specify an XML data file +that the script can transform. This is done in the +Program Arguments dialog, where the XML +file is specified in the Program Arguments edit box.
+ + -- cgit v1.2.1