Disassembly of Linux kernel debug methods Summary

Source: Internet
Author: User
Tags signal handler

Linux Disassembly Debugging Method

Linux kernel modules or applications often crash for a variety of reasons, usually printing function call stack information, then, in this case, how do we locate the problem? This document describes an disassembly method that assists in locating such problems.

The code examples are as follows:

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>

#include <execinfo.h>

#include <fcntl.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#define Print_debug

#define MAX_BACKTRACE_LEVEL 10

#define BACKTRACE_LOG_NAME "Backtrace.log"

static void Show_reason (int sig, siginfo_t *info, void *secret)

{

void *array[max_backtrace_level];

size_t size;

#ifdef Print_debug

Char **strings;

size_t i;

Size = BackTrace (array, max_backtrace_level);

strings = Backtrace_symbols (array, size);

printf ("Obtain%ZD stack frames.\n", size);

for (i = 0; i < size; i++)

printf ("%s\n", Strings[i]);

Free (strings);

#else

int fd = open (Backstrace_log_name, O_creat | O_WRONLY);

Size = BackTrace (array, max_backtrace_level);

BACKTRACE_SYMBOLS_FD (array, size, FD);

Close (FD);

#endif

Exit (0);

}

void Die () {

Char *str1;

Char *str2;

Char *STR3;

char *STR4 = NULL;

strcpy (STR4, "AB");

}

void Let_it_die () {

Die ();

}

int main (int argc, char **argv) {

struct Sigaction Act;

Act.sa_sigaction = Show_reason;

Sigemptyset (&act.sa_mask);

Act.sa_flags = Sa_restart | Sa_siginfo;

Sigaction (SIGSEGV, &act, NULL);

Sigaction (SIGUSR1, &act, NULL);

Sigaction (SIGFPE, &act, NULL);

Sigaction (Sigill, &act, NULL);

Sigaction (Sigbus, &act, NULL);

Sigaction (SIGABRT, &act, NULL);

Sigaction (Sigsys, &act, NULL);

Let_it_die ();

return 0;

}

In this example, we get and print the function call stack information by calling the BackTrace () and Backtrace_symbols () functions through a custom signal handler function when the program is abnormal. Next we compile and run the program.

When compiling, the-G and –rdynamic options are added, mainly to add debugging information. As you can see, there is an exception at runtime, the function call stack is printed, and the stack layer (stack frame) is 7 layers. In the stack frame information, the kernel is pushed up and down in order to get the function call stack information, so the sequence of function calls is reversed, that is, Main->let_it_die ()->die ().

Each line of the function call stack is displayed in the form of the executable file (symbol + relative offset) where the offending code is located [load address]

Take "./backtrace (Main+0xf7) [0X80488CD]" This line call stack information as an example, that the current executable is backtrace, code behavior the main symbol is located at the address of the offset 0xf7 line, In the assembly code that is normally disassembled by the executable, the address of the main symbol and the relative displacement are equal to the load address at the back. Sometimes, because of the version update, after we recompile the code to generate the executable file, and then disassemble the parsing problem, because the code is newer than when it was a problem, the Main+0xf7 may not be equal to the load address of the calling stack that was printed when the problem occurred. By calculating the value of the symbol plus relative displacement, and then comparing it to the load address, you can confirm that the code is consistent with the problem.

Next we disassemble the executable file

[Email protected]:~/workspace/backtrace$ objdump-ds backtrace > Backtrace.asm

Next, we analyze the disassembly of the assembly code and the problem of the call stack information positioning problems, first from the bottom of the call stack, that is./backtrace () [0x804873d], in the assembly code to search for 0x804873d address characters, as follows:

You can see that the code line corresponds to size = BackTrace (array, max_backtrace_level); By looking at the code you can tell that the function was called in the Show_reason function, and tried to find the address of the Show_reason symbol in the assembly code:

Parsing the code, discovering that the Show_reason function is a custom exception handler at the time of the exception, trying to find the address 0xb7707410 that is printed on a layer of function call stack, and finds that it is not in the assembly code and that the description is an external address because show_ Reason is called when the program is inside an exception, so it must be the internal code that causes the program to be abnormal, so next we parse the next line of call stack information, namely./backtrace (die+0x18) [0x80487c0]. First, the die symbol is found in the assembly code with the address 0x80487a8.

Using this address to load relative displacement 0x18 equals 0x80487c0 and the function call stack displays the same load address. Locate the Address line in the assembly code:

As you can see, the problem is in strcpy (STR4, "AB"); This line of code, you can see clearly that the previously defined STR4 is a null pointer, the null pointer to the area of the copy string will cause a null pointer exception.

Of course, more often than not, we will not find the corresponding code when the problem occurs, or the resulting executable file at compile time without adding debugging options, and can not disassemble the source code and assembly of the relative picture of the disassembly information. In the former case, loading the address is not a reference, we can only find the symbol in the disassembly information, the error line is found by relative displacement, and the problem is analyzed against the existing code. For the latter, we can only locate the assembly code for the faulted line, and then read the assembly code snippet to analyze the cause of the problem.

Usually we use objdump disassembly to analyze the problem is that another two particularly useful commands, NM and addr2line, are also used.

NM is used to export the symbol table from an executable file, which acts like Readelf–s or Objdump–t (T)

The address and disassembly address of the die symbol and the Let_it_die symbol found through the NM command are consistent.

The Addr2line command allows you to print symbols, executables, and error lines of code from executable files by specifying an address:

Here I try to find the load address in./backtrace (die+0x18) [0x80487c0], find the die function that was called when an error occurred, and the line is line 80th:

It is clear that addr2line is locating the line where strcpy is called in the Die function.

Disassembly of Linux kernel debug methods Summary

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.