GDB observation point

Source: Internet
Author: User
Tags print format
Http://learn.akae.cn/media/ch10s03.html3. Observation Point

Next we will know the steps in the previous section after debugging, althoughSumThe initial value 0 has been assigned, butWhile (1)Add at the beginning of the loopSum = 0;:

Example 10.3. debug an instance at the observation point

 
# Include <stdio. h> int main (void) {int sum = 0, I = 0; char input [5]; while (1) {sum = 0; scanf ("% s ", input); for (I = 0; input [I]! = '\ 0'; I ++) sum = sum * 10 + input [I]-'0'; printf ("input = % d \ n", sum );} return 0 ;}

UseScanfFunctions are very dangerous. Even if you fix this bug, there are still many problems. What if the input string is too long? We know that array access is not checked out of bounds, soScanfWrite it out of bounds. The phenomenon is as follows:

 
$./Main123input = 12367 input = 6712345 input = 123407

Next we will use the debugger to see how this strange result came out [21].

$ GDB main... (GDB) startbreakpoint 1 at 0x80483b5: file main. c, line 5. starting program:/home/akaedu/main () at main. c: 55int sum = 0, I = 0; (GDB) n9sum = 0; (GDB) (Press ENTER) 10 scanf ("% s", input); (GDB) (Press enter directly) 12341_for (I = 0; input [I]! = '\ 0'; I ++) (GDB) P Input $1 = "12345"

InputThe array has only five elements.ScanfAutomatically added'\ 0', UseXThe command is clearer:

 
(GDB) x/7B input0xbfb8f0a7: 0x310x320x330x340x350x000x00

XCommand to print the content of the specified storage unit.7bIs the print format,BIndicates a group of each byte, and 7 indicates printing 7 groups [22], fromInputThe first byte of the array starts to print 7 bytes consecutively. The first five bytes areInputThe storage unit of the array prints the hexadecimal ASCII code.'1'To'5', 6th bytes are written out of bounds'\ 0'. According to the running result, the first four characters are correct to convert to numbers. The first 5th characters are incorrect, that isIThe cycle from 0 to 3 is correct. We set a condition breakpoint fromIEqual to 4 to start single-step debugging:

 
(GDB) l6char input [5]; 78 while (1) {9sum = 0; 10 scanf ("% s", input); 11for (I = 0; input [I]! = '\ 0'; I ++) 12sum = sum * 10 + input [I]-'0'; 13 printf ("input = % d \ n", sum ); 14} 15 return 0; (GDB) B 12 if I = 4 breakpoint 2 at 0x80483e6: file main. c, line 12. (GDB) ccontinuing. breakpoint 2, main () at main. c: 1212sum = sum * 10 + input [I]-'0'; (GDB) P sum $2 = 1234

NowSumYes, it is 1234. According to the running result 123407, we know that the calculation in this step will definitely go wrong. The calculation should be 12340, that is to sayInput [4]Certainly not'5'It turns out that this reasoning is not rigorous:

 
(GDB) x/7B input0xbfb8f0a7: 0x310x320x330x340x350x040x00

Input [4]It is indeed 0x35, and there is another possibility of generating 123407, that is, in the next cycle, 123450 is not added but subtracted from a number to get 123407. But is it not at the end of the string? How can there be a next loop? Note that the cyclic control condition isInput [I]! = '\ 0'But it should have been 0x04 at the position of 0x00, so the loop will not end. Continue step:

 
(GDB) n11for (I = 0; input [I]! = '\ 0'; I ++) (GDB) P sum $3 = 12345 (GDB) n12sum = sum * 10 + input [I]-'0'; (GDB) x/7B input0xbfb8f0a7: 0x310x320x330x340x350x050x00

In the next cycle, the original 0x04 is inexplicably changed to 0x05. What is the problem? This cannot be explained for the time being, but the 123407 result can be explained. The result is 12345*10 + 0x05-0x30. Although the loop is repeated once, it will definitely exit the loop next time, because 0x05 is followed'\ 0'.

input [4] when is the next byte changed? You can use watchpoint for tracking. We know that the breakpoint is interrupted when the Program executes a Code line, the observation point is interrupted when the program accesses a storage unit. If we do not know where a storage unit is modified, the observation point is particularly useful. Next, we will delete the previously set breakpoint and execute the program from scratch. Repeat the previous input and use the watch command to set the observation point, trace the byte following input [4] (which can be expressed by input [5] ,

 (GDB) delete breakpoints delete all breakpoints? (Y or N) y (GDB) startbreakpoint 1 at 0x80483b5: file main. c, line 5. starting program:/home/akaedu/main () at main. c: 55int sum = 0, I = 0; (GDB) n9sum = 0; (GDB) (Press ENTER) 10 scanf ("% s", input); (GDB) (Press enter directly) 12341_for (I = 0; input [I]! = '\ 0'; I ++) (GDB) Watch input [5] hardware watchpoint 2: input [5] (GDB) I watchpoints num type disp ENB address what2 HW watchpoint keep y input [5] (GDB) ccontinuing. hardware watchpoint 2: input [5] Old value = 0' \ 0' new value = 1' \ 001' 0x0804840c in main () at main. c: 1111for (I = 0; input [I]! = '\ 0'; I ++) (GDB) ccontinuing. hardware watchpoint 2: input [5] Old value = 1' \ 001' new value = 2' \ 002' 0x0804840c in main () at main. c: 1111for (I = 0; input [I]! = '\ 0'; I ++) (GDB) ccontinuing. hardware watchpoint 2: input [5] Old value = 2' \ 002 'New value = 3' \ 003' 0x0804840c in main () at main. c: 1111for (I = 0; input [I]! = '\ 0'; I ++) 

ObviouslyForIt changed at the beginning of the loop.Input [5]The value of, and is to add 1 each time, while the Loop VariableIAdd 1 before each return to the beginning of the loop.Input [5]Is variableIIn other words,IIs followedInputArray.

It is difficult for beginners to fix this bug. If you find this bug but do not expect array access to cross-border, you may first handle another bug that is easier to fix without looking at the cause: if the input is not a number but a letter or other symbol, the result can be calculated. This is obviously not correct. You can add a condition in the loop to check for invalid characters:

 
While (1) {sum = 0; scanf ("% s", input); for (I = 0; input [I]! = '\ 0'; I ++) {If (input [I] <'0' | input [I]> '9') {printf ("invalid input! \ N "); sum =-1; break;} sum = sum * 10 + input [I]-'0';} printf (" input = % d \ n ", sum );}

 

Then, you will be pleasantly surprised to find that not only will an error be reported when you enter a letter, but will also report an error if you enter too long:

 
$./Main123ainvalid input! Input =-1 deadinvalid input! Input =-11234578 invalid input! Input =-11234567890 abcdefinvalid input! Input =-123 input = 23

It seems that the two bugs have been solved together, but this is a solution to the symptoms. It seems that the input is too long, but it cannot be solved as long as the root cause is not found. When the condition changes, it may come up again, in the next section, you will see that it has emerged in a new form. Now, let's take a look at why an error is reported if the entered code is too long after the code is added to check for invalid characters. Finally, we will summarizeGDBCommand:

Table 10.3. GDB basic command 3

Command Description
Watch Set observation points
Info (or I) watchpoints View the observed points currently set
X The content of the storage unit is printed from a certain position. It is regarded as byte, but it does not distinguish which byte belongs to which variable.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.