MS-VC uses map files to quickly locate program crash code lines

Source: Internet
Author: User

Programmers are most worried about seeing a program crash. Whether the pointer crosses the border or the operation is illegal, it will cause huge losses to our application system. However, during the testing of a large system, program crashes in the early stages seem inevitable. In fact, a program crash during the test is not terrible, but the test is successful. We are more concerned about which line in the program causes the system to crash so that we can make targeted corrections.
In VC, we can use the VC's automatic jump when the program crashes to locate the error code line. However, during a large number of stress tests, especially multi-threaded tests, there are dozens of errors at the same time. In this case, the redirection of VC Errors often fails.
Here we will introduce a good way to help you find code lines that crash. The core of this method is to use the information in the map file generated during compilation to locate the code lines.
Let's start with our introduction.
First, we must generate the map file of the program. So what is a map file? In short, a map file is the only text Representation Method of the program's global symbols, source files, and code line numbers. It is the static text of the entire program's engineering information. It can be used anywhere and at any time without additional programs. It can be opened through a text reading tool such as ultra edit. Moreover, this is the only savior who can find the code line for program crash.
So how should we generate a map file? In VC, we can press Alt + F7 to open the "Project Settings" option page, select the C/C ++ tab, and enter/ZD in the following project options, select the link tab, select the "generate mapfile" check box, and enter:/MapInfo: lines in the bottom project options to add row information when the map file is generated. Finally, press F7 to compile and generate the EXE executable file and map file. In this case, you can find the generated map file under the DEBUG directory of the project, with the file name "project name. Map ".
The map file has been obtained through the above steps. How can we use it? Let's start with a simple example and demonstrate step by step the process of locating program crashes using map files.
First, assume that our VC project contains the following file:
# Include

Int crashtest (int A, int B)
{
Int C;
C = A/B;
Return C;
}

Void main (void)
{
Int A = 30;
Int B = 0;
Int ret;
Printf ("Let's begin crash test.../N ");
Ret = crashtest (A, B );
}

Obviously, this program has a "except 0 error". during compilation in debug mode, "invalid operations" will be generated during running ". We recorded the address that generated the crash -- on my machine it is 0x0040102f. This address may be different on different machines, but we will use it below to write down this address.
Open its map file: (list the content that we care about, and the rest will be skipped)

Abort (project name)

Timestamp is 3ef16533 (Thu Jun 19 15:24:35 2003)

Preferred load address is 00400000

Start length name class
0001:00000000 0001081dh. Text code
000:00000000 000013bah. RDATA data
0002: 12713ba 00000000 H. edata
0003:00000000 00000104 H. CRT $ xca data
0003:00000104 00000104 H. CRT $ xcz data
0003:00000208 00000104 H. CRT $ Xia data
0003: 0000030c 00000109 H. CRT $ xic data
0003:00000418 00000104 H. CRT $ xiz data
0003: 0000051c 00000104 H. CRT $ xpa data
0003: 00000620 00000104 H. CRT $ xpx data
0003: 00000724 00000104 H. CRT $ xpz data
0003: 00000828 00000104 H. CRT $ xta data
0003: 0000092c 00000104 H. CRT $ xtz data
0003: 00000a30 00003236 H. Data
0003: 20173c68 201719c8h. BSS data
0004:00000000 00000014 H. idata $2 Data
0004:00000014 00000014 H. idata $3 data
0004:00000028 00000120 H. idata $ data
0004:00000148 00000120 H. idata $5 Data
0004: 00000268 000004f4h. idata $6 data

Address publics by value RVA + base Lib: Object

0001:00000020? Crashtest @ yahhh @ Z 00401020 F Main. OBJ
0001: 0000003c _ main 0040103c F Main. OBJ
0001: 000000b0 _ printf 004010b0 F libcd: printf. OBJ
000:00000130 _ chkesp 00401130 F libcd: chkesp. OBJ
0001: 00000170 _ maincrtstartup 00401170 F libcd: crt0.obj
0001: 000002a0 _ amsg_exit 004012a0 F libcd: crt0.obj
000:00000300 _ stbuf 00401300 F libcd: _ sftbuf. OBJ
0001: 00000460 _ ftbuf 00401460 F libcd: _ sftbuf. OBJ
000:00000520 _ output 00401520 F libcd: output. OBJ
0001: 201713c0 ___ initstdio 004023c0 F libcd: _ file. OBJ
0001: Listen 14f0 ___ endstdio 004024f0 F libcd: _ file. OBJ
0001:00001510 _ crtdbgbreak 00402510 F libcd: dbgrpt. OBJ
0001:00001520 _ crtsetreportmode 00402520 F libcd: dbgrpt. OBJ
0001: 00001580 _ crtsetreportfile 00402580 F libcd: dbgrpt. OBJ
0001: 00001600 _ crtsetreporthook 00402600 F libcd: dbgrpt. OBJ
0001: 00001620 _ crtdbgreport 00402620 F libcd: dbgrpt. OBJ

If you carefully read the RVA + base column, we can find that the first function address that is larger than the crashed address 0x0040102f is 0x0040103c, so the entry before the address 0x0040103c is the function that generates a crash, that is, this line:

0001:00000020? Crashtest @ yahhh @ Z 00401020 F Main. OBJ

So what is the function that crashes? Crashtest @ yahhh @ Z. All function names starting with question marks are c ++ modified names. So in our source program, the function that crashes is crashtest ()!

Now we can easily know the name of the function that crashed. Write it down, and then we will directly locate the code line that crashes. Pay attention to line numbers information, the last part of the map file, which is displayed in this form:

Line numbers for./debug/Main. OBJ (D:/my work/technology/exception example abort/Main. cpp) segment. Text

12 0001:00000020 14 0001: 0000002b 15 0001:00000035 16 0001:00000038
19 0001: 0000003c 20 0001:00000057 21 0001: 0000005e 23 0001: 00000065
24 0001: 00000072 25 0001: 00000085

The first number indicates the code line number in the source code, and the second number indicates the offset of the code line in the code segment to which it belongs. To find the code row number, use the following formula to perform hexadecimal subtraction:

Crash line offset = crash address-base address (imagebase address)-0x1000

Why? Because the crash address we get is obtained from the offset address (RVA) + base address (base), we need to subtract the base address when calculating the row number. Generally, the base address is 0x00400000. In addition, because the code segments of a PE file generally start from 0x1000 offset, 0x1000 must be subtracted.
So our: crash line offset = 0x0040102f-0x00400000-0x1000 = 0x2f
In the code line information of the map file, we can find the nearest number in the code line information that does not exceed the calculation result 0x2f. Found in the main. cpp file:

14 0001: 0000002b

That means 14th lines in the source code! Let's take a look at the source code. Note that the comments and blank lines must also be included. The program's 14th behavior:

C = A/B;

It is actually Row 3. It has an "exception except 0 "!

The method has been introduced. From now on, we can precisely locate the crash line in the source code, and as long as the compiler can generate a map file, whether on win or UNIX platforms, this method is applicable.
In this article, we only list a very simple example of "Division by 0 exception". The effect of using the map file may not be very obvious. However, we believe that in our large-scale application system debugging, the map file's auxiliary methods can be used to quickly locate functions and code lines in case of a program crash, it will save a lot of time and energy for our program debugging and improve our debugging quality. We can even ask a remote user to directly provide the address of the program crash, and then we can use the map file on our machine to statically find the line with the error, and corrected it in the program.

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.