Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Sangamesh Mallayya" <sangamesh.swamy@in.ibm.com>
To: gdb-patches@sourceware.org, "Ulrich Weigand" <Ulrich.Weigand@de.ibm.com>
Cc: "David Edelsohn" <edelsohn@us.ibm.com>,
	       "Sanket Rathi" <sanrathi@in.ibm.com>
Subject: [PATCH] Adding support for reading signal hanlder frame in AIX
Date: Mon, 15 Jan 2018 03:42:00 -0000	[thread overview]
Message-ID: <OFFEA6F7CE.B2E29B77-ON65258216.0013560E-65258216.0014653C@notes.na.collabserv.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3780 bytes --]

Hi All,

Attached patch adds support for reading signal handler frame in AIX.

If gdb is debugging an application which has a signal handler and reaches 
the signal handler frame, 
then we need to read the back chain address from sigconext saved on the 
stack, similarly the LR.

As backchain at an offset 0 will be 0, because we will have sigconext 
saved after the minimum stack size. 
So, correct backchain will be at an offset after minimum stack and the LR 
at an offset 8 will be of the signal millicode address.
If the back chain pointer is NULL and the LR field is in the kernel 
segment(ex. 0x00004a14) then we can probably assume we are in a signal 
handler.

This can be demonstrated using the below sample program.

#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

void sig_handle(int signo)
{
  printf("Caught signal: %d\n",signo);
  signal(SIGSEGV,sig_handle);
}

void foo()
{
  char *p; 
  signal(SIGSEGV, sig_handle); /* signal handler */
  strcpy(p,"Hello");
  sleep(1); /* Sleep to catch signal */
}

int main()
{
  pthread_t tid;
  pthread_attr_t attr;

  pthread_attr_init(&attr);
  pthread_create(&tid, &attr, (void*)foo, NULL);
  sleep(1);
  pthread_kill(tid,SIGSEGV);

  pthread_join(tid,NULL);
}


Debugging without the patch
------------------------------------
Here gdb stops at frame #1 as it doesn't understand the signal handler 
frame as backchain at offset 0 will be 0.

Reading symbols from /home/sangam/gdb_sighandle/thread-signal1...done.
(gdb) br sig_handle
Breakpoint 1 at 0x10000550: file thread-signal1.c, line 9.
(gdb) r
Starting program: /home/sangam/gdb_sighandle/thread-signal1 
[New Thread 1]
[New Thread 258]

Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1]
0xd057b720 in _vp_start () from /usr/lib/libpthread.a(shr_xpg5.o)
(gdb) c
Continuing.
[Switching to Thread 258]

Thread 3 hit Breakpoint 1, sig_handle (signo=11) at thread-signal1.c:9
9         printf("Caught signal: %d\n",signo);

(gdb) bt
#0  sig_handle (signo=11) at thread-signal1.c:9
#1  0x00004a14 in ?? ()
(gdb) 

Debugging with the patch
--------------------------------
Here gdb reads the signal handler frame  and gets the correct back and LR 
value.

Reading symbols from /home/sangam/gdb_sighandle/thread-signal1...done.
(gdb) br sig_handle
Breakpoint 1 at 0x10000550: file thread-signal1.c, line 9.
(gdb) r
Starting program: /home/sangam/gdb_sighandle/thread-signal1 
[New Thread 1]
[New Thread 258]

Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1]
0xd057b720 in _vp_start () from /usr/lib/libpthread.a(shr_xpg5.o)
(gdb) c
Continuing.
[Switching to Thread 258]

Thread 3 hit Breakpoint 1, sig_handle (signo=11) at thread-signal1.c:9
9         printf("Caught signal: %d\n",signo);
(gdb) bt
#0  sig_handle (signo=11) at thread-signal1.c:9
#1  0x100005e0 in foo () at thread-signal1.c:17
#2  0x100005cc in foo () at thread-signal1.c:16
#3  0xd0564f68 in _pthread_body () from /usr/lib/libpthread.a(shr_xpg5.o)
#4  0x00000000 in ?? ()
(gdb) 


Here is the gdb.base testsuite summary

                === gdb Summary ===

# of expected passes            13509
# of unexpected failures        4229
# of expected failures          14
# of unresolved testcases       3
# of untested testcases         61
# of unsupported tests          32


# of expected passes            13515
# of unexpected failures        4224
# of expected failures          14
# of unresolved testcases       3
# of untested testcases         61
# of unsupported tests          32


Please review and let me know your comments.



Thanks,
Sangamesh

[-- Attachment #2: signal_handler_aix.patch --]
[-- Type: application/octet-stream, Size: 5015 bytes --]

--- ./gdb/rs6000-tdep.h_orig	2018-01-09 06:37:49.000000000 -0600
+++ ./gdb/rs6000-tdep.h	2018-01-13 04:47:50.000000000 -0600
@@ -18,3 +18,25 @@
  /* Minimum possible text address in AIX.  */
  #define AIX_TEXT_SEGMENT_BASE 0x10000000
  
+ /* For sighandler.
+ 
+    In case of signal handler, sigcontext is saved on the stack along with
+    minimum stack size.
+  
+    sigconext structure have the mstsave saved under the sc_jmpbuf.jmp_context.
+ 
+    STKMIN(minimum stack size) is 56 for 32-bit processes, and iar offset
+    under sc_jmpbuf.jmp_context is 40 for the signal context.
+    ie offsetof(struct sigcontext, sc_jmpbuf.jmp_context.iar).
+    so PC offset in this case is STKIM+iar offset, which is 96 */
+ 
+ #define SIG_FRAME_PC_OFFSET 96
+ #define SIG_FRAME_LR_OFFSET 108
+ /* STKMIN+grp1 offset, which is 56+228=284 */
+ #define SIG_FRAME_FP_OFFSET 284
+ 
+ /* 64 bit process */
+ /* STKMIN64  is 112 and iar offset is 312. So 112+312=424 */
+ #define SIG_FRAME_PC_OFFSET64 424
+ /* STKMIN64+grp1 offset. 112+56=168 */
+ #define SIG_FRAME_FP_OFFSET64 168 
--- ./gdb/rs6000-tdep.c_orig	2018-01-09 06:53:04.000000000 -0600
+++ ./gdb/rs6000-tdep.c	2018-01-10 07:28:10.000000000 -0600
@@ -61,6 +61,8 @@
  #include "trad-frame.h"
  #include "frame-unwind.h"
  #include "frame-base.h"
+ #include "rs6000-tdep.h"
+ #include "xcoffread.h"
  
  #include "ax.h"
  #include "ax-gdb.h"
@@ -3238,8 +3240,24 @@
  static CORE_ADDR
  rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
  {
-   return frame_unwind_register_unsigned (next_frame,
- 					 gdbarch_pc_regnum (gdbarch));
+   ULONGEST r;
+   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+   int size = register_size (gdbarch, gdbarch_pc_regnum (gdbarch));
+ 
+   r = frame_unwind_register_unsigned (next_frame,
+                                       gdbarch_pc_regnum (gdbarch));
+   if (r && (r < AIX_TEXT_SEGMENT_BASE )) {
+     if (is64)  {
+       r = read_memory_unsigned_integer
+             (get_frame_base (next_frame) + SIG_FRAME_PC_OFFSET64,
+              size, byte_order); 
+     } else {
+       r = read_memory_unsigned_integer
+             (get_frame_base (next_frame) + SIG_FRAME_PC_OFFSET+8,
+              size, byte_order);
+     }
+   }
+   return r;
  }
  
  static struct frame_id
@@ -3273,7 +3291,7 @@
    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
    struct rs6000_framedata fdata;
    int wordsize = tdep->wordsize;
-   CORE_ADDR func = 0, pc = 0;
+   CORE_ADDR func = 0, pc = 0, save_cache_base = 0;
  
    if ((*this_cache) != NULL)
      return (struct rs6000_frame_cache *) (*this_cache);
@@ -3298,6 +3316,7 @@
  	 base address of this frame.  */
        cache->base = get_frame_register_unsigned
  	(this_frame, gdbarch_sp_regnum (gdbarch));
+       save_cache_base = cache->base;
      }
    CATCH (ex, RETURN_MASK_ERROR)
      {
@@ -3347,6 +3366,31 @@
  					     byte_order, &backchain))
          cache->base = (CORE_ADDR) backchain;
      }
+ 
+   /* If frame is a AIX signal handler frame, we need to read the base
+      address from sigconext offset. Backchain at an offset 0 will be
+      0, so backchain will be at an offset SIG_FRAME_FP_OFFSET(284)+8
+      for 32-bit applications. */
+   if (!cache->base && !fdata.frameless)
+   {
+     LONGEST backchain, sig_pc = 0;
+     
+     if (is64) {
+       if (safe_read_memory_integer (save_cache_base + 16, wordsize,
+                byte_order, &sig_pc)
+                && (sig_pc && (sig_pc < AIX_TEXT_SEGMENT_BASE)))
+         if (safe_read_memory_integer (save_cache_base + SIG_FRAME_FP_OFFSET64,
+                                       wordsize, byte_order, &backchain))
+           cache->base = (CORE_ADDR) backchain;
+     } else {
+       if (safe_read_memory_integer (save_cache_base + 8, wordsize,
+                byte_order, &sig_pc)
+                && (sig_pc && (sig_pc < AIX_TEXT_SEGMENT_BASE)))
+         if (safe_read_memory_integer (save_cache_base + SIG_FRAME_FP_OFFSET + 8,
+                                       wordsize, byte_order, &backchain))
+           cache->base = (CORE_ADDR) backchain;
+     }
+   }
  
    trad_frame_set_value (cache->saved_regs,
  			gdbarch_sp_regnum (gdbarch), cache->base);
--- ./gdb/xcoffread.h_orig	2018-01-09 07:12:34.000000000 -0600
+++ ./gdb/xcoffread.h	2018-01-09 07:12:53.000000000 -0600
@@ -23,4 +23,6 @@
  
  extern int xcoff_get_n_import_files (bfd *abfd);
  
+ extern int is64;
+ 
  #endif /* xcoffread.h */
--- ./gdb/xcoffread.c_orig	2018-01-09 07:13:53.000000000 -0600
+++ ./gdb/xcoffread.c	2018-01-09 07:15:31.000000000 -0600
@@ -52,6 +52,8 @@
  /* For interface with stabsread.c.  */
  #include "aout/stab_gnu.h"
  
+ int is64;
+ 
  \f
  /* Key for XCOFF-associated data.  */
  
@@ -1747,6 +1749,7 @@
  {
    struct objfile *objfile = this_symtab_objfile;
    int xcoff64 = bfd_xcoff_is_xcoff64 (objfile->obfd);
+   is64 = xcoff64;
  
    struct coff_symfile_info *info = XCOFF_DATA (objfile);
    int nsyms = info->symtbl_num_syms;

             reply	other threads:[~2018-01-15  3:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-15  3:42 Sangamesh Mallayya [this message]
2018-01-15 10:23 ` Yao Qi
2018-01-15 10:54   ` Sangamesh Mallayya
2018-01-15 16:27 ` Ulrich Weigand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=OFFEA6F7CE.B2E29B77-ON65258216.0013560E-65258216.0014653C@notes.na.collabserv.com \
    --to=sangamesh.swamy@in.ibm.com \
    --cc=Ulrich.Weigand@de.ibm.com \
    --cc=edelsohn@us.ibm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=sanrathi@in.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox