Native exception produced

Source: Internet
Author: User
Tags exception handling signal handler

Create an exception yourself

Native Exception, abbreviated as NE, is the most common anomaly that occurs in C + + code.

When we write code, some common operations can cause NE, such as null pointer assignment, array access, and so on, now I add a simple exception in the code:

TEST.C:

  1 #include <stdio.h>
  2 
  3 void Func4 ()
  4 {
  5     char *p = NULL;
  6     *p = 0x5;//anomaly produced place
  7}
  8 
  9 void func3 () {one     int var4 = 4;
 A 
 void Func2 ()     int var3 = 3;     func3 ();     Func4 ();
 The 
 void Func1 ()
 {     int var1,var2;     var1 = 2;
 {     int var0 = 1
 ) of void Main ()     func1 ();     Func2 ();
 return     ;
 34}

Android.mk

1 Local_path: = $ (call My-dir)
  2 include $ (clear_vars)
  3 
  4 local_cflags + =-g3-o0
  5     
  6 Local_src_file S: = test.c
  7 
  8 Local_module: = Test
  9 
 local_multilib: = All     
 include $ (build_executable )

I put it under the pls/vendor/mediatek/proprietary/external/libtest/directory, we compile it and push it to the phone:

Mmm vendor/mediatek/proprietary/external/libtest/
out/target/product/xxx/system/bin/test
adb push out/ Target/product/xxx/system/bin/test  system/bin/

gdb-server Debug Program

Start Gdbserver:

$ adb shell./system/bin/gdbserver:1234 system/bin/test
    Process system/bin/test created; pid = 4130
    Listening On port 1234
$ adb forward tcp:1234 tcp:1234

GDB Debug This bin file:

$./prebuilts/gcc/linux-x86/arm/cit-arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gdb out/target/product/ Xxx/symbols/system/bin/test
Reading symbols from Out/target/product/xxx/symbols/system/bin/test...done.
(GDB) Set Solib-search-path out/target/product/xxx/symbols/system/lib/
(gdb) set Solib-absolute-prefix out/ target/product/xxx/symbols/
(gdb) target remote:1234
remote debugging using:1234
Reading symbols from out /target/product/xxx/symbols/system/bin/linker...done.
Loaded symbols for Out/target/product/xxx/symbols/system/bin/linker
__dl__start () at bionic/linker/arch/arm/ Begin. s:32    mov r0, sp
(GDB) List

The test program is now loaded successfully:

(GDB) B main//Set breakpoint
Breakpoint 1 at 0xaaaaa772:file vendor/mediatek/proprietary/external/libtest/test.c, line 30.< c11/> (GDB) n//One step to perform    bl __linker_init

An exception occurs when you run into the Func function:

(GDB) n program
received signal SIGSEGV, segmentation fault.
0xaaaaa740 in Func4 () at Vendor/mediatek/proprietary/external/libtest/test.c:6
6       *p = 0x5;

Can know very clearly, we have a problem in the call Libtest, AEE is a set of MTK platform to deal with the exception of the tool, the code is packaged, when the application of the app has an exception, it collects exception information to compress in the db file, we need to use the GAT tool to open this file, Through the Main_log, we can search for the following information:

01-02 04:16:18.768 4180 4180 I aee_aed:build fingerprint: ' Xxx:7.0/nrd90m/v6h5e-2:eng/test-keys ' 01-02 04:16:18.768 4  180 4180 I aee_aed:revision: ' 0 ' 01-02 04:16:18.768 4180 4180 i aee_aed:abi: ' Arm ' 01-02 04:16:18.768 4180 I aee_aed:pid:4142, tid:4142, name:test >>> system/bin/test <<< 01-02 04:16:18.769 4180 4180 I AE E_aed:signal (SIGSEGV), Code 1 (segv_maperr), fault addr 0x0 01-02 04:16:18.770 4180 I 4180 000000 R1 00000005 R2 fffefa2c R3 00000000 01-02 04:16:18.770 4180 4180 I aee_aed:r4 aaaaa76f R5 fffefa24 R6 0000 0001 R7 fffefa2c 01-02 04:16:18.771 4180 4180 I Aee_aed:r8 00000000 R9 00000000 SL 00000000 FP fffefa00 01-02 04:16:18.771 4180 4180 I aee_aed:ip f750085c sp fffef9cc lr aaaaa761 pc aaaaa740 cpsr 00070030 01-02 04:16:18. 796 4180 4180 i aee_aed:01-02 04:16:18.796 4180 4180 i aee_aed:backtrace:01-02 04:16:18.799 4180 4180 i AEE_AE D: #00 pc 00000740 /system/bin/test 01-02 04:16:18.800 4180 4180 I aee_aed: #01 pc 0000075d/system/bin/test 01-02 04:16:18.800 418  0 4180 i aee_aed: #02 pc 0000077b/system/bin/test 01-02 04:16:18.800 4180 4180 I aee_aed: #03 pc 0001708c /system/lib/libc.so (__libc_init+84) 01-02 04:16:18.800 4180 4180 I aee_aed: #04 pc 00000660/system/bin/test 01-0 2 04:16:18.819 290 290 I WMT_LAUNCHER:FW Log CTRL flag has been set

When the native layer program is abnormal, the system kernel into the abnormal mode will send a signal to USR side, handling this anomaly signal is the Android Debuggerd this process, will be found in the log similar to the following log:

LIBC    : Fatal signal (SIGSEGV), code 1, fault addr 0x14 in Tid 9765 (capture@cmdque)

This process detects the crash of the program and outputs the process state information to the file and the serial port for the developer to analyze and debug using. Debuggerd's data is stored in the/data/tombstone/directory, and Linux kernel has its own set of signal mechanisms, and when the application crashes, the system kernel usually sends signal to the offending process to inform the process of what's going wrong. These processes can capture these signal and handle them accordingly.

Debuggerd creates a socket called "Android:debuggerd" as a connection to the server side waiting for other client-side processes, Receiving the TID and action information sent by the client-side process will be the running information of the process specified by Tid, dump to the file according to the action specified by the action;

Clinet-C + + program end

The following is a brief introduction to the process of the debuggerd process:

After the application entry address is __start, the Debugger_init () function is invoked in __linker_init to register the exception signal processing handler to implement several SINGAL:SIGILL,SIGABRT, Sigbus, that intercept the system anomaly. SIGFPE,SIGSEGV and Sigpipe:

Bionic/linker/linker.cpp:

4172static ELFW (Addr) __linker_init_post_relocation (kernelargumentblock& args, ELFW (Addr) linker_base) {
4173#if TIMING
4174  struct timeval t0, T1;
4175  gettimeofday (&t0, 0);
4176#endif

4179  __libc_init_at_secure (args);
4180
4184  debuggerd_init ();

Bionic/linker/debugger.cpp:

302__libc_hidden__ void Debuggerd_init () {
303  struct sigaction action;
304  memset (&action, 0, sizeof (action));
305  Sigemptyset (&action.sa_mask);
306  action.sa_sigaction = debuggerd_signal_handler;//exception handling function;
307  action.sa_flags = Sa_restart | Sa_siginfo;
308
309  //Use the alternate signal stack if available so we can catch stack overflows.
310  action.sa_flags |= sa_onstack;
311
312  sigaction (SIGABRT, &action, nullptr);
313  sigaction (Sigbus, &action, nullptr);  sigaction (SIGFPE, &action, nullptr);
315  sigaction (Sigill, &action, nullptr);
316  sigaction (SIGSEGV, &action, nullptr);
317#if defined (Sigstkflt)
318  sigaction (Sigstkflt, &action, nullptr);
319#endif  sigaction (Sigtrap, &action, nullptr);
321}

The linker in the Bionic Library sets handler (Debugger_signal_handler) for the following seven signals:

 Sigill (illegal instruction exception)//before assigning value to null pointer, the kernel sends this signal to the process Cameraserver SIGABRT (Abort exit Exception) Sigbus (Hardware access exception SIGFPE (floating-point operation exception) SIGSEGV (Memory Access Exception) Sigstkflt (coprocessor stack exception) Sigpipe (Pipe exception 
262static void Debuggerd_signal_handler (int signal_number, siginfo_t* info, void*) {263//It ' s possible somebody
D the SA_SIGINFO flag, which would mean 264//our "info" arg holds a undefined value. 265 if (!have_siginfo (Signal_number)) {266 info = nullptr; 267} 268 mb Log_signal_summary (Signal_number, info); Print the problem process information; 270 271 Send_debuggerd_packet (info);//Now at the clinet end, connect with the service via the socket,//Then through write (s, &msg, S Izeof (MSG) sends the info to Debuggerd,debugger_action_crash for the act of taking; 272 273//We need to return from signal handler Ggerd can dump the 274//thread that crashed, but returning this does not guarantee this signal 275/would be thro WN again, even for SIGSEGV and friends, since the signal, could 276//have been sent.
Resend the signal with Rt_tgsigqueueinfo (2) to 277//Preserve the sa_siginfo contents.
278 signal (Signal_number, SIG_DFL);//Set the action associated with the signal, SIG_DFL indicate the default action, restore to default; 279 280 struct Siginfo si;
281 if (!info) {282 memset (&si, 0, sizeof (SI));
283 Si.si_code = Si_user;
284 si.si_pid = Getpid ();
285 si.si_uid = Getuid ();
286 info = &si;  287} else if (info->si_code >= 0 | | info->si_code = = si_tkill) {//Rt_tgsigqueueinfo (2) ' s documentation Appears to is incorrect on kernels 289//that contain commit 66dd34a (3.9+). The manpage claims to a allow 290//negative si_code values that are not si_tkill, but 66dd34a-changed the 291/
/Check to allow all Si_code values in calls coming from inside the house.
292} 293 294 int rc = Syscall (Sys_rt_tgsigqueueinfo, Getpid (), Gettid (), signal_number, info); System call Tgsigqueueinfo: signal will be passed to any member of the thread group; 295 if (RC!= 0) {296 __libc_format_log (android_log_fatal, "libc", "Failed to R
Esend signal during crash:%s ", 297 strerror (errno));
298 _exit (0); 299} 300}

debuggered Process Service end:

System/core/debuggerd/debuggerd.cpp

871int Main (int argc, char** argv) {
872  Union Selinux_callback CB;
873  if (argc = = 1) {
874    cb.func_audit = audit_callback;
875    selinux_set_callback (Selinux_cb_audit, CB);
876    cb.func_log = selinux_log_callback;
877    selinux_set_callback (selinux_cb_log, CB);
878 return    Do_server ()//no-b parameter calls this process
879  }
880
895  if (!have_tid) {
896    usage ();
897 return    1;
898  }
899 return  do_explicit_dump (tid, dump_backtrace);//Manually Export Debuggerd-b tid 
900}

When the number of arguments passed by the startup Debuggerd process is 1 o'clock, Debuggerd will be used as a background service process to receive the application exception exit message tombstone:

792static int Do_server () {793//Debuggerd crashes can ' t be reported to debuggerd. 794//Reset all of the crash Handl
     ERs.
Ignoring the processing of Debuggerd's own crash; 795 Signal (SIGABRT, SIG_DFL);
796 Signal (Sigbus, SIG_DFL);
797 Signal (SIGFPE, SIG_DFL);
798 signal (Sigill, SIG_DFL);
799 Signal (SIGSEGV, SIG_DFL);
800#ifdef Sigstkflt 801 Signal (Sigstkflt, SIG_DFL);
802#ENDIF 803 Signal (sigtrap, SIG_DFL);
804 805//Ignore failed writes to closed sockets 806 (signal, sigpipe);
807 808//block SIGCHLD so we can sigtimedwait for it.
809 sigset_t sigchld;
810 Sigemptyset (&AMP;SIGCHLD);
811 Sigaddset (&AMP;SIGCHLD, SIGCHLD);
812 Sigprocmask (Sig_setmask, &AMP;SIGCHLD, nullptr);                              813//Establish the server side of the socket communication; 814 int s = socket_local_server (Socket_name, android_socket_namespace_abstract, 815 Sock_stream |
SOCK_CLOEXEC);
816 if (s = = 1) return 1;
817 818//Fork a process that stays root, and listens on a pipe to pause and resume the target. 819 if (!starT_signal_sender ()) {820 Aloge ("debuggerd:failed to fork Signal sender"), 821 return 1 822} 823 824 Alogi ("Debu
Ggerd:starting\n "); 825 826 for (;;)  {827 Sockaddr_storage ss; 828 sockaddr* ADDRP = reinterpret_cast<sockaddr*> (&AMP;SS); 829 socklen_t alen =
sizeof (SS);
830 831 ALOGV ("Waiting for connection\n");
832 int fd = ACCEPT4 (S, ADDRP, &alen, sock_cloexec); 833 if (fd = 1) {834 Aloge ("Accept failed:%s\n", Strerror (errno)); 835 continue; 836} 837 838 Hand
Le_request (FD);//handle_request processing request; 839} 840 return 0; 841}

System/core/debuggerd/debuggerd.cpp:

751static void handle_request (int fd) {
752  alogv ("handle_request (%d) \ n", FD);
753
754  scopedfd Closer (FD);
755  debugger_request_t request;
756  memset (&request, 0, sizeof (request));
757  int status = Read_request (FD, &request);
     Read the data sent from the client-side process and read the debugger_msg_t structure on the socket;
758  if (status!= 0) {
759 return    ;
760  }
781  //Fork a child to handle the rest of the request.
782  pid_t fork_pid = fork ();
783  if (fork_pid = = 1) {
784    aloge ("debuggerd:failed to Fork:%s\n", Strerror (errno));
785  } else if (Fork_pid = = 0) {
786    worker_process (FD, request
Related Article

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.