See an article about Linux/C + + development debugging skills, feel quite use, where to share with you.
10 steps to a UNIX paradise
Author:arpan Sen, Senior technician, Systems Documentation, Inc. (SDI)
Discusses several techniques and free tools that can help C + + developers save time.
C + + developers typically accomplish multiple tasks in their daily work: developing new software, debugging other people's code, developing test plans, developing tests for each plan, managing recession Software (regression suite), and more. Frequent conversions between multiple roles can consume a lot of valuable time. To help alleviate this problem, this article provides 10 ways to effectively increase productivity. The examples in this article use TCSH version 6, but the ideas provided apply to all UNIX? Shell Variant. This article also describes several open source tools that can be used on UNIX platforms.
Keep your data safe
Using RM-RF * or its variants on shell hints can be the most common cause of the loss of hours of work for UNIX developers. There are several ways to solve this problem: connect these commands to their interactive version by using alias RM, alias CP, or alias MV in the $HOME/.aliases, and then reference the file when the system starts. Depending on the login shell, this means placing the source $HOME/.aliases in. CSHRC (for c/tcsh shell) or. Profile or. bash_profile (for Bourne Shell), as shown in Listing 1.
Listing 1. Setting aliases for RM, CP, and MV
Alias RM ' Rm–i '
Alias CP ' Cp–i '
Alias MV ' Mv–i '
There is another way for users of the TCSH shell to add the following line in the startup script:
Set Rmstar on
With the Rmstar variable set, if you issue the RM * command, you will be prompted to confirm, as shown in Listing 2.
Listing 2. Using the Rmstar shell variable in tcsh
[Email protected]# pwd
/home/arpan/ibm/documents
[Email protected]# set Rmstar on
[Email protected]# RM *
Really want to delete all files? [n/y] n
However, if you use RM, CP, or MV commands with the-f option, the interaction mode is suppressed. One more efficient way is to create your own version of these UNIX commands and save the deleted data using predefined folders such as $HOME/.recycle_bin. Listing 3 shows a sample script called Saferm, which only accepts file and folder names.
Listing 3. Saferm Script
#!/usr/bin/tcsh
if (!-D ~/.recycle_bin) Then
mkdir ~/.recycle_bin
endif
MV $ ~/.recycle_bin/$1. ' Date +%f '
Automatically back up data
Recovering your data requires comprehensive policies and measures. Depending on the requirements, data backups can be performed nightly, or every few hours. By default, you should use the Cron tool to back up $HOME and all of its subdirectories, and save the backup in a pre-specified file system area. Note that only the system administrator should have read (Write) or execute (EXECUTE) permissions on the backup data. The following Cron script briefly demonstrates the settings of the backup:
0 * * */home/tintin/bin/databackup.csh
This script backs up data at 20:00 every day. The data backup script is shown in Listing 4.
Listing 4. Data backup Scripts
Cd/home/tintin/database/src
Tar cvzf database-src.tgz. ' Date +%f ' database/main/sql-processor/
MV Database-src.tgz. ' Date +%f ' ~/.backup/
chmod ~/.backup/database-src.tgz. ' Date +%f '
Another strategy is to maintain some simple and straightforward file system areas in the network, such as/BACKUP_AREA1,/BACKUP_AREA2, and so on. Developers who want to back up data should create directories or files in these zones. Also, be aware that, like/TMP, this area must have the sticky bit open.
Browse Source code
Using the free download Cscope utility (see Resources for links) is a great way to discover and explore existing source code. Cscope requires a file list (C or C + + header files, source code files, Flex and Bison files, inline source code [. inl] files, and so on) to create its own database. Once the database is created, it lists the source code in a concise interface. Listing 5 shows how to build and invoke the Cscope database.
Listing 5. Build and invoke the source code database using Cscope
[Email protected]# Find. –name "*. [chyli]*] > Cscope.files
[Email protected]# cscope–b–q–k
[Email protected]# cscope–d
The-B option of Cscope lets it create an internal database; the-q option lets it create index files to speed up searches; the-k option allows cscope to search without taking into account the system header files (otherwise, even the simplest searches produce a lot of results).
Use the-D option to invoke the Cscope interface, as shown in Listing 6.
Listing 6. Cscope interface
Cscope version 15.5 Press the? Key for help
Find this C symbol:
Find This global definition:
Find functions called by this function:
Find functions Calling this function:
Find This text string:
Change the This text string:
Find This egrep pattern:
Find This file:
Find files #including This file:
Press ctrl-d to exit Cscope. Use the TAB key to switch between the data Cscope list and the Cscope option (for example, find C symbol and find file). Listing 7 shows a screenshot when searching for a file with a database in its name. View individual files by 0, 1, and so on.
Listing 7. Output of Cscope when searching for a file named database
Cscope version 15.5 Press the? Key for help
File
0 Database.cpp
1.database.h
2.databasecomponents.cpp
3.databasecomponents.h
Find this C symbol:
Find This global definition:
Find functions called by this function:
Find functions Calling this function:
Find This text string:
Change the This text string:
Find This egrep pattern:
Find This file:
Find files #including This file:
Debug legacy code with Doxygen
To effectively debug code developed by others, take the time to understand the overall structure of the existing software-classes and their hierarchies, global variables and static variables, and public interface routines. The GNU utility Doxygen (links in resources) may be the best tool for extracting class hierarchies from existing source code.
To run Doxygen on a project, you first need to run doxygen-g on the shell prompt. This command generates a file named Doxyfile in the current working directory, which must be edited manually. After editing, run Doxygen again for Doxyfile. Listing 8 shows a running example.
Listing 8. Run Doxygen
[Email protected]# doxygen-g
[Email protected]# ls
Doxyfile
... [After editing doxyfile]
[Email protected]# doxygen doxyfile
You need to understand several fields in the Doxyfile. The more important fields are:
* Output_directory. The directory where the generated document files are saved.
* INPUT. This is a space-delimited list of all source code files and folders for which the document must be generated.
* RECURSIVE. If the source code list is hierarchical, set this field to Yes. This eliminates the need to specify all folders in input, just specify the top-level folder in input and set this field to YES.
* Extract_all. This field must be set to YES, which tells Doxygen that the document should be extracted from all classes and functions that do not have a document.
* Extract_private. This field must be set to YES, which tells Doxygen that a private data member of the class should be included in the document.
* File_patterns. Unless the project does not use a generic C or C + + source code file extension, such as. c,. cpp,. CC,. cxx,. h, or. HPP, you do not need to add a setting in this field.
Note: Other fields that must be studied in Doxyfile depend on the project requirements and the required documentation details. Listing 9 shows an example of Doxyfile.
Listing 9. Example Doxyfile
Output_directory =/home/tintin/database/docs
INPUT =/home/tintin/project/database
File_patterns =
RECURSIVE = yes
Extract_all = yes
Extract_private = yes
Extract_static = yes
Using STL and GDB
In software developed with C + +, the most complex sections often use classes in the C standard Template Library (STL). Unfortunately, it's not easy to debug code that contains many STL classes, and GNU Debugger often points out the lack of information, the inability to display related data, and possibly even crashes. To solve this problem, you can use one of the advanced features of GDB-add user-defined commands. For example, consider the code snippet in Listing 10, which uses a vector and displays information.
Listing 10. Using STL vectors in C + + code
#include <vector>
#include <iostream>
using namespace Std;
int main ()
{
Vector<int> V;
V.push_back (9);
V.push_back (8);
for (int i=0; i < v.size (); i++)
cout << v[i] << "\ n";
return 0;
}
Now, when debugging this program, if you want to find out the length of the vector, you can run V._m_finish–v._m_start on the GDB hint, where _m_finish and _m_start are pointers at the beginning and end of the vector, respectively. However, this requires you to understand the internal workings of the STL, which is not always feasible. My recommended alternative is to use a free download of gdb_stl_utils, which defines several user-defined commands in GDB, such as p_stl_vector_size (the size of the display vector) or p_stl_vector (the contents of the display vector). Listing 11 shows how P_stl_vector loops through the data specified by the _m_start and _m_finish pointers.
Listing 11. Use P_stl_vector to display the contents of a vector
Define P_stl_vector
Set $vec = ($arg 0)
Set $vec _size = $vec->_m_finish-$vec->_m_start
if ($vec _size! = 0)
Set $i = 0
while ($i < $vec _size)
printf "Vector Element%d:", $i
P * ($vec->_m_start+ $i)
Set $i + +
End
End
End
Run Help user-defined on the GDB prompt to see a list of commands defined using Gdb_stl_utils.
Faster compilation
Compiling the source code can take time for any more complex software. One of the best tools for speeding up the compilation process is CCache (see the links in resources). CCache is a compiler cache, which means that if a file has not been modified during compilation, it is fetched from the tool's cache. If the user only modifies a header file and calls make clean; Make,ccache will significantly speed up compilation. Because CCache not only uses timestamps to determine whether a file needs to be recompiled, it can save valuable compilation time. Here is an example of using CCache:
[Email protected]# ccache g__ foo.cxx
CCache generates a hash (hash) internally, using this hash and other things to consider the preprocessing version of the source code file (obtained using g++–e), the options used to invoke the compiler, and so on. The compiled object file is stored in the cache according to this hash.
CCache defines several environment variables that can be customized:
* Ccache_dir. CCache stores the cached files in this directory. By default, files are stored in the $HOME/.ccache.
* Ccache_tempdir. CCache Store temporary files in this directory. This folder should be located in the same file system as the $CCACHE _dir.
* Ccache_readonly. Setting this environment variable can be helpful if the increasing cache folder can cause problems. If this variable is enabled, CCache does not add any files to the cache during compilation, but it uses the existing cache to search for object files.
Resolve memory errors by using GDB with Valgrind and electric-fence together
There are several drawbacks to C + + programming-The most significant problem is memory errors. There are two UNIX open source tools-valgrind and electric-fence-that can be used in conjunction with GDB to resolve memory errors. The following is a brief discussion of how to use these tools.
Valgrind
The easiest way to use Valgrind with a program is to run it on the shell and then use the general program options. Note that in order to get the best results, you should run the debug version of the program.
[Email protected]# valgrind <valgrind options>
<program name> <program option1> <program option2>.
Valgrind reports some common memory errors, such as improperly freeing memory (you should use malloc allocations, using Delete to release), using variables that have not been initialized, and deleting the same pointer two times. The example code in Listing 12 has an obvious array overlay problem.
Listing 12. Examples of C + + memory errors
int main ()
{
int* P_arr = new INT[10];
P_ARR[10] = 5;
return 0;
}
Valgrind and GDB can be used together. By using the-db-attach=yes option in Valgrind, you can call GDB directly when you run Valgrind. For example, if you call Valgrind in the code in Listing 12 with the –db-attach option, the first time you encounter a memory problem, it calls GDB, as shown in Listing 13.
Listing 13. Connecting GDB during the execution of Valgrind
==5488== Conditional Jump or move depends on uninitialised value (s)
==5488== at 0x401206c:strlen (in/lib/ld-2.3.2.so)
==5488== by 0x4004e35: _dl_init_paths (in/lib/ld-2.3.2.so)
==5488== by 0x400305a:dl_main (in/lib/ld-2.3.2.so)
==5488== by 0x400f87d: _dl_sysdep_start (in/lib/ld-2.3.2.so)
==5488== by 0x4001092: _dl_start (in/lib/ld-2.3.2.so)
==5488== by 0x4000c56: (within/lib/ld-2.3.2.so)
==5488==
==5488==----Attach to debugger? ---[return/n/n/y/y/c/c]----N
==5488==
==5488== Invalid Write of size 4
==5488== at 0x8048466:main (test.cc:4)
==5488== Address 0x4245050 is 0 bytes after a block of size alloc ' d
==5488== at 0x401adeb:operator new[] (unsigned)
(m_replacemalloc/vg_replace_malloc.c:197)
==5488== by 0x8048459:main (Test.cc:3)
==5488==
==5488==----Attach to debugger? ---[return/n/n/y/y/c/c]----
Electric-fence
Electric-fence is a set of libraries that are used to detect overflows or overflows on buffers in a GDB-based environment. In the event of an erroneous memory access, this tool (in conjunction with GDB) accurately identifies the instruction that caused the problem in the source code. For example, for the code in Listing 12, listing 14 shows how GDB behaves in the case of electric-fence enabled.
Listing 14. Electric-fence accurately identifies the part of the source code that caused the crash
(GDB) Efence on
Enabled Electric Fence
(GDB) Run
Starting program:/home/tintin/efence/a.out
Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <[email protected]>
Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <[email protected]>
Program received signal SIGSEGV, segmentation fault.
0x08048466 in Main () at Test.cc:4
<b>4 p_arr[10] = 5;</b>
After installing Electric-fence, add the following line in the. gdbinit file:
Define Efence
Set Environment Ef_protect_below 0
Set Environment ld_preload/usr/lib/libefence.so.0.0
echo Enabled Electric fence\n
End
Using Gprof for code coverage
One of the most common programming tasks is to improve code performance. To accomplish this task, be sure to find out which parts of the code spend the most time executing. In technical terms, this is called profiling. The GNU profiling tool Gprof (see links in resources) is easy to use and offers a number of useful features.
In order to collect profiling information for a program, the first step is to specify the –PG option when invoking the compiler:
[Email protected]# g++ DATABASE.CPP–PG
Next, run the program as you normally would. After the program has been successfully run (that is, no crashes or calls to _exit system call), profiling information is written to the Gmon.out file. After the Gmon.out file is generated, run the Gprof (shown below) against the executable file. Note that if the executable file name is not specified, the default file is a.out. Similarly, if you do not specify a profiling data file name, the default file is gmon.out in the current working directory.
[Email protected]# gprof <options> <executable name>
<profile-data-file name> > outfile
By default, Gprof displays output in standard output, so you need to redirect the output to a file. GPROF provides two sets of information: Planar profiling data and call graphs, which together form an output file. The flat profile data shows the total time spent by each function. Cumulative seconds represents the total time spent by a function plus the time spent by other functions called from this function. The self seconds only calculates the time it takes for the function itself.
Displaying source code listings in GDB
Developers often need to debug code through very slow remote connections, so graphical interfaces such as Data Display Debugger (DDD) are not supported for GDB. In this case, using the CTRL-X-A key combination in GDB can save time because it displays the source code list during debugging. Press the CTRL-W-A key to return to the GDB hint. Another method is to invoke gdb with the –tui option, which launches the source code list for text mode directly. Listing 15 shows the scenario in which GDB is called in text mode.
GDB source code Listing using text mode
3using namespace Std;
4
5int Main ()
6 {
B+>7 vector<int> V;
8 V.push_back (9);
9 V.push_back (8);
Ten for (int i=0; i < v.size (); i++)
cout << v[i] << "\ n";
return 0;
13}
14
--------------------------------------------------------------------------------------
Child process 6069 In:main line:7 pc:0x804890e
(GDB) B main
Breakpoint 1 at 0x804890e:file test.cc, line 7.
(GDB) R
Maintain an orderly source code listing using CVS
Different coding styles are used for various projects. For example, some developers prefer to use tabs in their code, while others don't like it. But it is important that all developers adhere to the same coding standards. However, the reality is often not the case. By using version control systems such as Concurrent Versions system (CVS), you can examine the files you want to check in against a set of coding standards, effectively implementing a unified coding standard. To complete this task, CVS comes with a set of predefined trigger scripts that run when specific user actions are involved. The format of the trigger script is simple:
<regular expression> <program to Run>
One of the predefined trigger scripts is the Commitinfo file in the $CVSROOT folder. To check whether the file you want to check in contains tabs, use the following Commitinfo file syntax:
all/usr/local/bin/validate-code.pl
The Commitinfo file identifies the All keyword (which means that each file you submit should be checked; You can also specify the set of files to check). Then run the associated script to check the file according to the source code standard.
Conclusion
This article discusses several free tools that can help increase the productivity of C + + developers. For more information about the individual tools, please refer to resources.
Linux c C + + development debugging Tips