When debugging a development project, the company encountered a headache. A function was called in many places, but I only needed to execute this breakpoint when a certain parameter value. This kind of advanced debugging has never been used, I searched the internet and found debugging technology in this regard. The following is the information I am looking for. It is very useful. Please share it with me.
Http://hhfighting.blog.163.com/blog/static/55700323200922093543827/
C ++ code and debugging
This section describes the good C ++ code style, How to Write secure code, and program debugging technology in the Visual C ++ environment, this content is important for new employees to grow from students to Real programmers, gradually participate in the development of actual projects, and read Third-Party code.
1. Standardized and easy-to-understand code
At this stage, software development relies on the cooperation of teams. Programmers are no longer synonymous with personal heroism. On the one hand, programmers must rely on a large number of other programmers to complete the code, and on the other hand, provide a large amount of code to them.
For others to use the code, there are actually two elements: first, providing a reliable function, and then clearly expressing the author's thoughts. Any communication must have certain specifications.
Easy to understand. In addition, standardized and easy-to-understand code can be reused. Standardized Code has a longer life cycle, better maintainability, and more convenient extension later.
1.1 several features of good code
What kind of code can be regarded as a standard and easy to understand? It is reflected in countless arguments in details. In fact, no matter the style and habits, good code has several common features:
1. Good naming: A good variable name and function name let people who read the code immediately know the role of the variable or function, and it is easy to understand the approximate structure and function of the program. It is necessary for programmers to understand the Hungarian naming law.
2. consistency: consistency leads to better programs. consistent code indent style can display the code structure. It doesn't matter what indent style is used. In fact, specific Code styles are far from consistent.
3. NOTE: Annotations are a way to help program readers, and program authors are also one of the Future Program readers. The best comments are the highlights of the program, or provide an overview to help others understand the program. However, if comments only indicate what the code has already said, or conflict with the code, or confusing and interfering with readers in a well-organized manner helps.
1.2 develop good habits
As mentioned above, it is far from important to use specific code styles. Therefore, it is a waste of time to put too much energy into the choice of A or B. What you need to do is to stick to it. Below are some tips on how to write standard and easy-to-understand code and develop good habits.
1. Name the variables and functions according to the Hungarian naming method.
2. Follow the international popular code style.
3. When writing code, you must follow your naming rules and writing style. You must never remedy the issue afterwards.
4. Use the tool (parasoft C ++ test) to check your code and evaluate whether you have formed good habits.
5. persevere until you develop habits.
2. Write secure and reliable code
In large application software systems, code snippets constitute a complete system. Code interactions are frequent, and program crashes do not occur when errors occur, it is a delay of some time
It takes a lot of time and effort to locate and locate errors after several functions are transitioned. How can we reflect errors in the program in a timely manner and avoid some naive Semantic Errors in the code? A function usually
It is used by other programmers, but how can he correctly use functions compiled by others? This part can (partially) help solve these problems.
2.1 contract Programming
The design by contract idea is written in C ++ Bible-level books, and Bjarne, father of C ++
Stroustrup's "C ++ Programming Language" has slightly mentioned that the Bible-level book "Object-Oriented Software Architecture" in the OO field has explained contract programming in a large space. Now more and more software development
People recognize the importance of contract programming and gradually adopt contract programming in actual work.
A simple explanation of contract programming is to define a contract between the implementer and caller of the function by specifying the call conditions (constraints) and output results of the implemented code blocks (functions and classes.
As for our work, developers should define the contract for each function and class completed. Contract programming seems to be unremarkable and does not have any specific help for program development. In fact, contract programming can ensure the reliability and security of software to the maximum extent in the development stage.
In
In actual work, whenever you need to use modules provided by other programmers, you do not know how to call them or whether the parameters you pass in are legal, sometimes the processing results of functional modules cannot be believed. These
It should be obvious that because the module provider does not provide explicit information, the caller can only feel the stones and cross the river with anxiety, thus wasting a lot of time, and in order to make his code more secure and reliable, in the code
After a lot of judgments and assumptions, the code structure is damaged and the execution efficiency is lost. Finally, the caller still cannot ensure that his or her calls are correct.
Contract programming strictly defines the mutual rights and obligations between function providers and callers by specifying the behavior of functions (or classes), so as to avoid the above situation, this ensures code quality and software quality.
2.2 active debugging
Active debugging refers to adding a proper amount of debugging code when writing code to help us pop up a message box when a software error occurs, tell the developers where the error occurred, and stop the program. The debugging code is only valid in the debug version. After full testing and release of the release version program, the debugging code will automatically become invalid.
Active debugging and contract programming complement each other to jointly ensure the quality of software development. Contract programming is equivalent to various contracts signed in economic life, and active debugging is equivalent to the legal penalty measures taken when a party fails to comply with the contract.
Various development languages and development tools provide these debugging statements. The standard C ++ provides the assert function, and the MFC provides the assert debugging macro to help us perform active debugging. In actual work, we recommend that you use the assert debugging macro of MFC.
2.2.1 parameter check
In addition to specifying a contract, you should check the input parameters at the beginning of the function to ensure that the error message is immediately reported when an invalid parameter is passed in. For example:
Bool getpathitem (int I, lptstr szitem, int ilen)
{
Assert (I> 0 );
Assert (null! = Szitem );
Assert (ilen> 0) & (ilen <max_path ));
Assert (false = isbadwritestringptr (szitem, ilen ));
}
Check the pointer. Generally, the programmer checks the pointer as follows:
// An example of checking only a part of the error condition
Bool enumeratelistitems (pfnelcallback pfncallback)
{
Assert (null! = Pfncallback );
}
This check can only exclude null pointers. However, if the pointer points to an invalid address or the pointer points to an object that is not of the expected type, the above example cannot be checked out, but all think it is correct. The complete check should be as follows:
// An example of completely checking the error condition
Bool enumeratelistitems (pfnelcallback pfncallback)
{
Assert (false = isbadcodeptr (pfncallback ));
}
2.2.2 internal check
The proper use of assert in the code can greatly help bug detection and improve debugging efficiency. The following is a simple example.
Switch (ntype)
{
Case gk_entity_point:
// Do something
Break;
Case gk_entity_pline:
// Do something
Break;
Default:
Assert (0 );
}
In the preceding example, the switch statement only processes gk_entity_point and gk_entity_pline.
But if the system needs to handle more situations in the future, and the above Code is not updated in a timely manner, or the developer has neglected it for a while. One that may cause system errors or
A crashed bug occurs, and the use of assert can promptly remind developers of their negligence and eliminate the bug as quickly as possible.
In other cases, when developers write code, if you are sure that A is incorrect at a certain point, you can add assert here to exclude situation.
In conclusion, the proper and flexible use of assert for active debugging can greatly improve the stability and security of the program, reduce debugging time, and improve work efficiency.
2.3 useful code styles
Some good code styles can also help you avoid some naive and low-level errors, which are difficult to detect. The C ++ language is concise and flexible.
Features, sometimes typing a wrong character or missing a character, can cause a great disaster, this kind of error is not gradually avoided with the improvement of your programming level and experience. No one can knock the wrong character,
Right.
For example, programmers often mistake =, place the constant on the left of =. If = is entered by mistake, the compiler reports an error during compilation.
If (int_max = I)
3. Visual C ++ debugging technology
Check the code until you are dizzy and have not found any errors. When the program is running, it will crash, so you have to sacrifice the final magic weapon: the debugger. Visual
The C ++ debugger can be called the best C/C ++ debugger on the Windows platform.
The C ++ debugger can also be used to debug programs written in other languages such as Delphi and Java, Which is powerful.
Even though visual C ++ debuggers are so powerful, they can only help you discover hidden logical errors and have little to do with program design and structural defects.
The most common visual c ++ debugging technologies for programmers include breakpoint setting, tracing call stack, and disassembly debugging. Other compiler functions are auxiliary tools in debugging, because disassembly debugging requires the programmer to have the Assembly language knowledge and the underlying structure of the language, I will not introduce it here.
3.1 prerequisites for debugging
Professional debugs share a common feature, that is, they are also excellent developers. Obviously, if you are not a good developer, you cannot become a debugging expert, and vice versa. The following are the fields that must be mastered by qualified debuggers or developers.
1. Understanding projects: Understanding projects is the first element to prevent errors in user interfaces, logic, and performance. To learn how to implement various functions in various source files and where to implement them, you can narrow down the search scope and quickly find out the problem.
2. master the language: master the language used by the project. The debugger (developer) must know how to program using these languages and what these languages are doing in the background.
3. master the technology: To solve the thorny problem, the first important step is to grasp the essentials of the technology used, which does not mean that you must understand all the details of the technology used, instead, you should have a general understanding of the technology in use, and more importantly, you should know exactly where to search for more detailed information.
4. operating System and CPU: Any project is actually running on a specific operating system and a specific CPU. The more you know about the operating system, the more help you will find for errors. Theoretically, with the compilation language in mind, you can debug and solve any bugs.
No matter what job you are engaged in, as long as you are often engaged in technical work, you must constantly learn to keep up with the development of technology, let alone want to do better or want to stay at the forefront of technological development. Read excellent
Technical books and magazines, more hands-on compilation of some utilities, reading the code of other excellent developers, and doing some disassembly work, it will help you improve the level of development and debugging (especially when you integrate these four
).
3.2 debugging process
It is difficult to determine a debugging process suitable for solving all errors, but the debugging process proposed by John Robbins should be the most practical:
1. Copy Error
2. Incorrect description
3. Always assume that the error is your problem.
4. Break down and solve errors
5. Have creative ideas
6. Use debugging tools
7. Start debugging
8. The verification error has been corrected.
9. learning and communication
Describe the error to help you correct the error and get help from your colleagues. Gradually narrow down the problem scope and eliminate code segments without errors until the problem is located. This is a common solution to all problems.
Applicable methods. Some strange errors require you to shift your line of sight from code heap to other aspects such as the operating system and hardware environment. Using a variety of debugging auxiliary tools can save you a lot of time, and some tools themselves
You will not be given the opportunity to make some mistakes. When you solve a bug, stop and think about what caused you (or him) to make such a mistake. How can you avoid it in the future?
Remember that the debugger is just a tool, just like a screw, and you only do what you want it to do. The real debugger is the debugging idea in your own mind.
3.3 breakpoint and usage
In Microsoft Visual
It is easy to set a breakpoint in the source code line in the C ++ debugger. You only need to open the source file, place the cursor on the line of code that wants to set the breakpoint, press the F9 shortcut, and press the F9 shortcut again.
Cancel a breakpoint. When you run the code in this code line, the debugger stops at the specified position. This simple position breakpoint feature is extremely powerful. After statistics, you only need to use this breakpoint separately to solve the problem.
99.46% debugging problems.
If the program does not encounter errors every time it runs to the breakpoint, it will become annoying to keep moving between the debugger and the application, and the advanced breakpoint will come in handy. In essence,
The advanced breakpoint allows you to write some wisdom into the breakpoint, so that when the debugger executes at the breakpoint, the program will be interrupted at the breakpoint only when the internal state of the program meets the conditions you specify, switch to the debugger.
Press the Alt + F9 shortcut key to bring up the breakpoints dialog box. You can view the dialog box and find that the dialog box contains three tabs: location, data, and messages, which correspond to three breakpoints:
1. location breakpoint: the simple breakpoint we usually use is a location breakpoint. We can also set the breakpoint on a binary address or any function, and enhance the location breakpoint function by specifying various conditions.
2.
Expression and variable breakpoint: the debugger keeps the program running until the set conditions are met or data changes are specified. At Intel
On the CPU, both breakpoints use a hardware breakpoint through a specific debugging register of the CPU. If the debugging register can be used, the program will be able to run at full speed; otherwise, the debugger will execute each
Compile commands and check the conditions in each step. The program runs very slowly or even cannot run.
3. Windows message breakpoint: when a message breakpoint is used, the debugger is interrupted when receiving a specific windows message during the window process. Message breakpoint is applicable to c sdk programs. For C ++ class library programs such as MFC (which should be the vast majority), message breakpoint is not practical, you can use a location breakpoint to achieve the same effect.
The advanced breakpoint settings are described in msdn in detail. Search for the topic using breakpoints: additional information in the Visual C ++ subset and read the relevant content.
3.4 call stack
Sometimes we don't know where to set the breakpoint. We only know that the program is running and suddenly crashes. How can we locate the location of the error? In this case, you can view the call stack. The call stack helps us determine the call relationships between various functions in the program at a specific time.
Fang
When the program is executed at a breakpoint or the program crashes, after the control is transferred to the debugger, press the Alt + 7 shortcut key to bring up the call
Stack window, you can see the current function call status, the current function is at the top, and the following functions call the above functions in turn. In the call
In the Stack window, select parameter values and parameter types to display the parameter types and input values of each function.
3.5 use tracking tools
Sometimes, we want to understand the collaboration between different functions in the program, or because of the lack of documentation, we want to be able to confirm the input parameter values when the function is called under different circumstances. In this case, it is too troublesome to use the breakpoint function, and the call stack can only view the calling status of the current function. A better method is to use the trace macro and the corresponding tool.
Cheng
When a trace macro is running in debug, the specified string in the trace macro is output to the debugger of the current Windows system and displayed.
In the C ++ environment, you can view the output content of the trace macro on the debug page of the output window when you call the test run (Press F5) program. In fact, the trace macro is encapsulated.
Windows API function outputdebugstring, some auxiliary tools can not disturb the visual
The C ++ debugger intercepts the output content of the trace macro in the program, for example, the Microsoft System
The tracewin tool introduced by the C/C ++ column of Journal (MSJ) in January 1996 (source code and documentation can be found in older versions of msdn) and powerful free-of-charge
Tool debugview.
With the trace macro, we can easily understand the cooperative relationship between various functions in the program and the order and time of calls. Further, you can fully master the execution process of the program.
Note that the trace macro may affect the program efficiency. Therefore, it is best to delete or comment out the unused trace macro.
4 reading program skills
For programmers, whether they are studying or working, they often need to read the source code of other programmers, how to quickly comprehend the program ideas, understand the program structure and the functions of each component, it is an important basic skill for programmers to fully understand all aspects of the program. The following describes some common techniques.
4.1 start with functions and interfaces
A complete application or system consists of several relatively independent functions. These functions are reflected in the graphic interface of user interaction, such as various menu commands and toolbar button commands. So if
Currently, you are only interested in a certain number of functions of the program. You can find the ID response functions of these menu commands, button commands, and so on in the program. Starting from this, you can gradually go deep into the program, until you fully understand the implementation of this function
So far. The time spent in this process depends largely on the programmer's mastery of the debugging technology.
It should be emphasized that, when you are not familiar with the program core structure and implementation technology, you can directly use this method to explore the program. When you gradually go deep into the program core, the number of program modules involved will increase dramatically, and the difficulty of understanding will also increase. Once you understand the core structure and implementation technology of the program, you will feel like a storm when using this method to explore the program.
4.2 cut the branches and leave only the trunk
As mentioned above, in any case, you must master the core structure and implementation technology of the program. How to master it? The method is to first complete the backup of the obtained program, and then remove the secondary functions from the program.
Drop, leaving only the necessary parts. Removing secondary features is a process that is repeated multiple times. The time spent depends on the programmer's understanding of the industry, the level and experience of programming technology.
I often encounter situations where I cannot judge whether a module is secondary in a short period of time (as the understanding of the program deepens and the accumulation of experience and technology, this situation will become fewer and fewer ), in this case, we recommend that you directly remove this module, re-compile the Connection Program, and run the program to check whether the program runs normally.
The two methods described above are frequently used, and they can be combined and used in turn. However, no matter what method is used to explore the reading program, do not expect to be able to spend no effort, it takes an hour or two to understand tens of thousands of lines of the program.
5 References
Program Design practices, Mechanical Industry Press
High quality c ++ programming guide, Lin Rui
Application debugging technology, John Robbins, Tsinghua University Press
Object-oriented software architecture, Bertrand Meyer, Tsinghua University Press