In the arm system, when the crash occurs, the back trace debugging output

Source: Internet
Author: User
Reprinted please indicate the source and the author contact: http://blog.csdn.net/mimepp arm system, when the crash occurs back trace debugging output: Yu Tao (yut616_at_sohu.com) KEYWORDS: general protection Error Back trace
On the arm target board, if an exception occurs, such as out-of-bounds memory access, it is sometimes very difficult to debug where the error occurs. Recently, I have looked at the back trace backtracking function and implementation, take a note here. First, back trace involves a bunch of registers, but don't worry. It's actually not as difficult as you think. In the Linux kernel code, you can see the definition of the arm register, which is listed here:
Linux/include/ASM-arm/proc-armv/ptrace. hstruct pt_regs ...{
Long uregs [18];
};

# Define arm_cpsr uregs [16] // current Program Status Register
# Define arm_pc uregs [15] // program counter command counter, next command to be executed
# Define arm_lr uregs [14] // link register, which is the value to be loaded into the PC when exiting, and the previous code is executed in the returned result.
# Define arm_sp uregs [13] // Stack pointer
# Define arm_ip uregs [12] // command pointer pointing to the next command
# Define arm_fp uregs [11] // frame pointer
# Define arm_r10 uregs [10]
# Define arm_r9 uregs [9]
# Define arm_r8 uregs [8]
# Define arm_r7 uregs [7]
# Define arm_r6 uregs [6]
# Define arm_r5 uregs [5]
# Define arm_r4 uregs [4]
# Define arm_r3 uregs [3]
# Define arm_r2 uregs [2]
# Define arm_r1 uregs [1]
# Define arm_r0 uregs [0]
# Define arm_orig_r0 uregs [17]

Several important registers here are FP, LR, and sp. We will continue to discuss them later. We can first think of a scenario where a call process (...)
{
...;
B (...);
Printf ("AAA ");
} When a calls B, the general process will be executed by a, executed to B, and executed to B. After B is executed, the execution will continue under B in. In this case, when you go to B for execution, you should prepare something to ensure that B will return to a to continue the execution. How can we ensure the above problem? We need to use the LR register to store the information at location A. This is the abbreviation of the link Register link register. It is like a chain, concatenate a bunch of calls. Therefore, the above process is to put the address of B into the PC when it is executed to B, so that B is executed below. PC is the instruction counter, and the address in it will be executed. At this time, we need to save the information we mentioned just now and put the value to be returned in LR. In the arm process call, there is a structure called backtracing structure, and there are two concepts called frames and stacks. Their relationships are: backtracking structure | ----------- | ---------------------------- | frame stack... Frame... The frame backtracking structure is at the high end of the frame. Through this backtracking structure, one frame can be connected to a stack. Frame pointer FP. Frame Pointer Points to the last structure in the list consisting of a trace structure that concatenates stacks. In this way, the FP can be used to trace the call sequence of the function. When the system crashes, the final called function can be obtained.

The backtracking structure is:
High address
Save code pointer [FP] FP point to here
Returns the LR value [FP, #-4].
Return sp value [FP, #-8]
Returns the FP value [FP, #-12] pointing to the next structure.
...
From the above content, we only need to print the above LR value cyclically to get the desired address series.

Long FP, nextfp;
Fp = regs-> arm_fp;
Long LR;
For (xxx; XXX) // you can decide the number of cycles.
...{
LR = * (long *) (FP-4 ));
Nextfp = * (long *) FP-12 ));
Fp = nextfp;
 
Printk ("call address: 0x % lx", LR-current-> MM-> start_code-4 );
}

The above current-> MM-> start_code is the base address of the data segment of the current process, and then minus 4 to get the address before the return. The printed content is the address for calling the function. For example, call address: 0x2849cc
Call address: 0x3b8b70
Call address: 0x2c270
Call address: 0x2c5ec
Call address: 0x2b298
Call address: 0x283934
Call address: 0x3c41a8 you can use objdump to get the sym file of your execution file, for example, arm-elf-objdump-SD test. GDB>/tmp/test. GDB. then, you can use the address printed in this loop to search for the wrong location.
The above code is just a reference. It depends on the actual situation of your system. In addition, we also see a start_thread, which is listed as a record. # Define start_thread (regs, PC, SP)
(...{
Unsigned long * stack = (unsigned long *) SP;
Set_fs (user_ds );
Memzero (regs-> uregs, sizeof (regs-> uregs ));
If (current-> personality & addr_limit_32bit)
Regs-> arm_cpsr = usr_mode;
Else
Regs-> arm_cpsr = usr26_mode;
Regs-> arm_pc = pc;/** // * pC */
Regs-> arm_sp = sp;/** // * sp */
Regs-> arm_r2 = stack [2];/** // * R2 (envp )*/
Regs-> arm_r1 = stack [1];/** // * r1 (argv )*/
Regs-> arm_r0 = stack [0];/** // * R0 (argc )*/
Regs-> arm_r10 = Current-> MM-> start_data;/** // * Data Segment Base */
})

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.