Android Debuggerd Brief introduction and Source Analysis (reprint)

Source: Internet
Author: User
Tags stack trace

Reprint: http://dylangao.com/2014/05/16/android-debuggerd-%E7%AE%80%E8%A6%81%E4%BB%8B%E7%BB%8D%E5%92%8C%E6%BA%90%E7% a0%81%e5%88%86%e6%9e%90/

Code word very hard, reprint please indicate from Dylan's Zone "Android debuggerd Brief introduction and Source analysis"

Based on android4.1, this paper analyzes the use and source of Debuggerd tool.

1.Debuggerd Introduction

Debuggerd is a daemon process that starts with the INIT process when the system starts. The main responsibility is to dump the information from the process runtime to the file or console.

Operating principle of 1.1 Debuggerd
    • Create a socket named "Android:debuggerd" as the server side waits for other client-side processes to connect
    • Receive TID and action information sent by the client side process
    • Run information for the process specified by the TID, dump to file or console according to action specified by action

There are several main processes that can be used as the client side of Debuggerd:

    • Exception for C + + programs

This program is installed by bionic linker to install abnormal signal processing function, when the program generates abnormal signal, enter the signal processing function, and debuggerd established.

    • Debuggerd Program

Debuggerd can start with the command debuggerd-b [<tid>] in the console, and then establish a connection with Debuggerd daemon. This allows the debuggerd to dump the information for the process specified by the TID without interrupting the execution of the process.

    • Callstack/dumpstate

The console runs command callstack/dumpstate and specifies the necessary parameters, and the command calls Dump_backtrace_to_file to interact with Debuggerd

How to use 1.2 debuggerd
    • After the C + + program that generates the abnormal signal is connected to the Debuggerd, Debuggerd dumps the process information to the Tombstone_xx file and saves it to the/data/tombstone/folder. Stack information for the exception process can be analyzed by viewing tombstone_xx
    • Start with the command debuggerd-b [<tid>] in the console. If the-b parameter is added, the information for the process specified by the TID will be dump to the console or dump into the tombstone file
    • The console runs the command callstack/dumpstate, and the process information is written to the files specified in both commands
Analysis methods for 1.3 tombstone file

Using the tools under Prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin

    1. Arm-linux-androideabi-addr2line translates a call stack 16 binary value similar to libxxx.so 0x00012345 into a file name and function name Arm-linux-androideabi-addr2line-e Libxxx.so 0x00012345
    2. ARM-LINUX-ANDROIDEABI-NM listing symbol information for a file arm-linux-androideabi-nm-l-c-n-S libdvm.so > Dvm.data
    3. Arm-linux-androideabi-objdump Listing File Details arm-eabi-objdump-c-D libc.so > Libc.s

Through the analysis of the above tools, we can get a more complete call stack and call logic assembly code

Useful tools and reference articles for analysis of tombstone files:

    1. tombstones.py Python script to retrieve line info from an Android tombstone using Ndk-stack and Addr2line. Https://github.com/feichh/android-tombstones
    2. Android-ndk-stacktrace-analyzer A Simple tool for analyzing the stack trace generated from crashing native code in the and  Roid System. http://code.google.com/p/android-ndk-stacktrace-analyzer/
    3. How to read Android crash log and stack trace This article briefly explains the structure of the log, how to read it. Http://bootloader.wikidot.com/linux:android:crashlog
1.4 Debuggerd Frame Diagram

2.linker DEBUGGER.C Source Analysis

Bionic libc is a C-standard library for Android embedded systems. The linker in the Bionic Library will set the handler (Debugger_signal_handler) for the following seven types of signals:

    • Sigill (Illegal instruction exception)
    • SIGABRT (Abort exit Exception)
    • Sigbus (Hardware access exception)
    • SIGFPE (floating-point arithmetic exception)
    • SIGSEGV (Memory Access exception)
    • Sigstkflt (coprocessor Stack exception)
    • Sigpipe (Pipe exception)

When a C + + program that is linked to a bionic library crashes, the kernel sends the corresponding signal, and the process receives an abnormal signal and is transferred to the Debugger_signal_handler function for processing.

The Debugger_init function (see file BIONIC/LINKER/DEBUGGER.C) sets the signal processing function

voidDebugger_init () {structSigaction Act; memset (&act,0,sizeof(act)); Act.sa_sigaction=Debugger_signal_handler; Act.sa_flags= Sa_restart |Sa_siginfo; Sigemptyset (&act.sa_mask); Sigaction (Sigill,&Act, NULL); Sigaction (SIGABRT,&Act, NULL); Sigaction (Sigbus,&Act, NULL); Sigaction (SIGFPE,&Act, NULL); Sigaction (SIGSEGV,&Act, NULL); Sigaction (Sigstkflt,&Act, NULL); Sigaction (Sigpipe,&Act, NULL);}

Debugger_init in act.sa_flags = Sa_restart | The meaning of Sa_siginfo:

    • Sa_restart

If this parameter is specified, the system call is automatically initiated if the signal interrupts a system call to the process. If this parameter is not specified, the interrupted system call returns a failure with the error code EINTR. This flag bit is used to handle slow system calls (system calls that may be blocked). For example, calling write system call writes a device is blocked, when the process captures a signal and enters the corresponding signal processing function return, the system call may return a ENINTR error. After you specify this parameter, the system call restarts, and with the RETRY_ON_EINTR macro, you can guarantee the completion of the write operation.

    • Sa_siginfo

If this parameter is specified, the parameters that accompany the signal (the siginfo_t struct) can be passed to the signal processing function.

Debugger_signal_handler function Processing Flow

    • Debugger_signal_handler function Analysis: Call Logsignalsummary to write signal information to file
    • Call the Socket_abstract_client function to establish a socket connection with Debuggerd
    • If the connection is successful, the structure body debugger_msg_t is set and sent to Debuggerd
Msg.action = Debugger_action_crash; // tell Debuggerd what line to take  = tid; // Thread Number  sizeof(msg));
    • Wait for Debuggerd's reply, block in the following call, and then execute the following process after receiving the reply
1));
    • Reset the signal processing function to SIG_DFL, i.e. take the default action
Signal (n, SIG_DFL);
    • Resend the signal, the process from the current signal processing function returned, will process the signal, the default signal processing action, that is, the interrupt process.

logsignalsummary function Analysis:

    • Gets the name of the exception signal and the thread name, and formats the string
    • Call the function __libc_android_log_write function, fill in the struct Iovec vec[3] with the relevant information, the contents of this struct array will eventually be written to the log file
    • In function __libc_android_log_write, log_id is Log_id_main, so
Log_channels[log_id_main] = {__write_to_log_init,-1"/dev/"Logger_log_main}
    • Log_channels[log_id].logger (log_id, VEC) will call __write_to_log_init
    • In the function __write_to_log_init, the log file is written to "/dev/log/main", and the function that performs the write log operation is __write_to_log_kernel
3.Debuggerd Source Code Analysis

There are two ways to start a debuggerd:

    • Started in Deamon in the init process, in init.rc
Service debuggerd/system/bin/debuggerdclass Main

When started in this way, after entering the main function, the Do_server function is called, serving as the server side that provides the dump process information for other processes

    • Run the System/bin/debuggerd executable directly, you need to specify the parameters, use the
// parameter-B means output backtrace in the console

When started in this way, after entering the main function, the Do_explicit_dump function is called, communicating with the Debuggerd daemon to dump the information of the specified process to the file or console

Debuggerd frame Diagram

Do_server Function Flow Analysis

(This function will be entered when the daemon mode is started)

1. Install the processing function SIG_DFL for the abnormal signal, that is to ignore the error problem signal (Sigill, SIG_DFL); Signal (SIGABRT, SIG_DFL);

Signal (Sigbus, SIG_DFL); signal (SIGFPE, SIG_DFL); signal (SIGSEGV, SIG_DFL); signal (sigpipe, SIG_DFL); Signal (Sigstkflt , SIG_DFL);

2. Call the following code to establish the server side of the socket communication

s = Socket_local_server (Debugger_socket_name,android_socket_namespace_abstract, sock_stream);

3. Enter the infinite loop, wait for the connection request, the relevant code is as follows

 for (;;) {        struct  sockaddr addr;        Socklen_t Alen;         int FD;         sizeof (addr);         = Accept (S, &ADDR, &Alen);         if 0 ) {            continue;        }        Fcntl (FD, F_SETFD, fd_cloexec);        Handle_request (FD);    }

Final call Handle_request processing the request on the socket

handle_request Function Flow Analysis

1. Call Read_request to handle the data sent by the client side process on the socket, the process is

<1.1> First Call function GETSOCKOPT to structure variable ucred CR assignment

     &CR, &len);

ucred PID uid GID that stores the client-side process of the socket

<1.2> reading the debugger_msg_t structure from the socket

<1.3> assigning values to debugger_request_t* out_request

Out_request->action = msg.action;out_request->tid = msg.tid;out_request->pid = cr.pid ; out_request->uid = cr.uid;out_request->gid = Cr.gid;

<1.4> if the ACTION set in debugger_msg_t is Debugger_action_crash, it is the request sent by the C + + process of CRASH to determine if the TID passed in is valid

<1.5> if the action set in debugger_msg_t is

Debugger_action_dump_backtrace or    Debugger_action_dump_backtrace_to_log

Description is a request from another method (Debuggerd/callstack) that requires root or system permissions, and then determines if the TID is valid

2. After returning from Read_request, call the Ptrace function attach the process specified by the TID, at which time Debuggerd becomes the parent process of the attache process, and then the Ptrace function sends a sigstop signal to the child process to stop the child process. At this point, the parent process has an opportunity to check the value of the child process core image and register

3. Call the following statement to the client terminal process to reply to the message, so that the clinet side of the process can be returned from the read call

"  / " 1)

4. Wait for the child process to stop in the For loop

int signal = wait_for_signal (Request.tid, &total_sleep_time_usec);

When a child process receives a sigstop signal, it acts according to a different action

if(Request.action = =Debugger_action_dump_tombstone) {Tombstone_path=Engrave_tombstone (request.pid, Request.tid, Signal,true,true, &detach_failed,&total_sleep_time_usec);} Else if(Request.action = =debugger_action_dump_backtrace) {Dump_backtrace (FD, Request.pid, Request.tid,&detach_failed,&total_sleep_time_usec);} Else if(Request.action = =Debugger_action_dump_backtrace_to_log) {Dump_backtrace_for_thread (FD, Request.pid, Request.tid,&detach_failed,&AMP;TOTAL_SLEEP_TIME_USEC);

When a child process receives seven kinds of abnormal signals, the calling function Engrave_tombstone to process notes: Sigstop instructions are not crash to communicate with Debuggerd, and the process information is written to the tombstone file according to the action, or The socket file is written and processed by the corresponding client process that reads the socket file. Received seven abnormal signal description is crash process, call Engrave_tombstone directly to write dump information to tombstone file

5. Call PTRACE (Ptrace_detach, Request.tid, 0, 0) to remove the trace from the child process

6. Call Kill (Request.pid, Sigcont) to restore the stopped child process and let it terminate naturally

Notes on the Attach_gdb

1. If you run a command similar to the following:

10000

Then all uid<10000 processes crash Attach_gdb The process of True,crash will stop.

2. After calling PTRACE (Ptrace_detach, Request.tid, 0, 0) to dismiss the child process, start waiting for GDB to connect

ADB forward TCP:5039 tcp:5039adb shell gdbserver:5039 --attach pid &

3. The user presses home or volume down button, can make the process continue, natural crash 4.attach_gdb is false, will only release the child process tracking

Engrave_tombstone Function Flow Analysis

For crash, the C + + process, mainly through this function dump process information

1. Create the "/data/tombstones" folder and modify the permissions

2. Call function Find_and_open_tombstone,tombstone_xx file up to 10, over then overwrite the oldest

3. Call Dump_crash to dump all information to the tombstone file

4. If Issystemservercrash (the crash process is gaiad) or issystemfinalizertimeout is true, the run logcat command will log buffer (System under/dev/log, Events, radio,main files) output to the tombstone file

Dump_crash Function Flow Analysis

1.dump_build_info (log)

Dump "Build fingerprint"

2.DUMP_FAULT_ADDR (log, TID, signal) call PTRACE (Ptrace_getsiginfo, tid, 0, &si) dump Siginfo information

3.dump_thread (context, log, Tid, true, total_sleep_time_usec)

Context information for the dump process

4.dump_maps (log, PID)

Information in the Dump/proc/pid/maps

5.dump_smaps (log, PID)

Information in the Dump/proc/pid/smaps

6.dump_status (log, PID)

Information in the Dump/proc/pid/status

7.dump_sibling_thread_report (context, log, PID, Tid, Total_sleep_time_usec)

Do_explicit_dump Function Flow Analysis

(This function will be entered when the parameter is started at the command line)

To determine Dump_backtrace to true, call Dump_backtrace_to_file

(1) Call socket_local_client to establish a connection with Debuggerd Deamon

(2) Assigning a value to the debugger_msg_t variable and sending it to Debuggerd

     debugger_msg_t msg;      = tid;      = Debugger_action_dump_backtrace;

(3) Wait for Debuggerd to reply and read the dump information, write to the console

 while sizeof 0 {                if (Temp_failure_retry (fd, buffer, n))! = N)                    {=-1;                      Break ;                }     }

To determine Dump_backtrace to false, call Dump_tombstone

(1) Call socket_local_client to establish a connection with Debuggerd Deamon

(2) Assigning a value to the debugger_msg_t variable and sending it to Debuggerd

     debugger_msg_t msg;      = tid;      = Debugger_action_dump_tombstone;

(3) Wait for debuggerd reply, call

1))

Here and

     Write of Handle_request (FD, Tombstone_path, strlen (Tombstone_path))

Mutual echoes read reads Tombstone_path, assigned to Pathbuf and called by Do_explicit_dump

" Tombstone written to:%s\n ", Tombstone_path)

Output

Android Debuggerd Brief introduction and Source Analysis (reprint)

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.