Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] Adding support for reading signal hanlder frame in AIX
@ 2018-01-15  3:42 Sangamesh Mallayya
  2018-01-15 10:23 ` Yao Qi
  2018-01-15 16:27 ` Ulrich Weigand
  0 siblings, 2 replies; 4+ messages in thread
From: Sangamesh Mallayya @ 2018-01-15  3:42 UTC (permalink / raw)
  To: gdb-patches, Ulrich Weigand; +Cc: David Edelsohn, Sanket Rathi

[-- 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;

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Adding support for reading signal hanlder frame in AIX
  2018-01-15  3:42 [PATCH] Adding support for reading signal hanlder frame in AIX Sangamesh Mallayya
@ 2018-01-15 10:23 ` Yao Qi
  2018-01-15 10:54   ` Sangamesh Mallayya
  2018-01-15 16:27 ` Ulrich Weigand
  1 sibling, 1 reply; 4+ messages in thread
From: Yao Qi @ 2018-01-15 10:23 UTC (permalink / raw)
  To: Sangamesh Mallayya
  Cc: gdb-patches, Ulrich Weigand, David Edelsohn, Sanket Rathi

"Sangamesh Mallayya" <sangamesh.swamy@in.ibm.com> writes:

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

Out of curiosity, how do you get a working gdb on AIX?  Do you build gdb
with libstdc++ and libgcc dynamic linking?  I remember that GDB's
exception handling on AIX is still broken if libstdc++ and libgcc is
statically linked (which is the default).  See PR 21187
https://sourceware.org/bugzilla/show_bug.cgi?id=21187

-- 
Yao (齐尧)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Adding support for reading signal hanlder frame in AIX
  2018-01-15 10:23 ` Yao Qi
@ 2018-01-15 10:54   ` Sangamesh Mallayya
  0 siblings, 0 replies; 4+ messages in thread
From: Sangamesh Mallayya @ 2018-01-15 10:54 UTC (permalink / raw)
  To: Yao Qi; +Cc: David Edelsohn, gdb-patches, Sanket Rathi, Ulrich Weigand

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="GB2312", Size: 1239 bytes --]

Hi Yao,

Yes. As a work around i used dynamic linking to build and test the GDB.

Thanks,
Sangamesh



From:   Yao Qi <qiyaoltc@gmail.com>
To:     "Sangamesh Mallayya" <sangamesh.swamy@in.ibm.com>
Cc:     gdb-patches@sourceware.org, "Ulrich Weigand" 
<Ulrich.Weigand@de.ibm.com>, "David Edelsohn" <edelsohn@us.ibm.com>, 
"Sanket Rathi" <sanrathi@in.ibm.com>
Date:   01/15/2018 03:53 PM
Subject:        Re: [PATCH] Adding support for reading signal hanlder 
frame in AIX



"Sangamesh Mallayya" <sangamesh.swamy@in.ibm.com> writes:

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

Out of curiosity, how do you get a working gdb on AIX?  Do you build gdb
with libstdc++ and libgcc dynamic linking?  I remember that GDB's
exception handling on AIX is still broken if libstdc++ and libgcc is
statically linked (which is the default).  See PR 21187
https://urldefense.proofpoint.com/v2/url?u=https-3A__sourceware.org_bugzilla_show-5Fbug.cgi-3Fid-3D21187&d=DwIFaQ&c=jf_iaSHvJObTbx-siA1ZOg&r=J-WMWRjg8du7SbBf1G7Q4MCo_pbrJAUTpeQbQAzRnbk&m=o2QXj6A96evr3OC1c8yvIuuo8_n_6zZJOIWNdFDsoBo&s=_jdSN3n_LTzB2RO-eNSc-UBkEZ_EIeMo_CJA0BsrwcQ&e=


-- 
Yao (ÆëÒ¢)




\x16º&Öéj×!zÊÞ¶êç׎;ó‰b²Ö«r\x18\x1dn–­r\x17¬

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Adding support for reading signal hanlder frame in AIX
  2018-01-15  3:42 [PATCH] Adding support for reading signal hanlder frame in AIX Sangamesh Mallayya
  2018-01-15 10:23 ` Yao Qi
@ 2018-01-15 16:27 ` Ulrich Weigand
  1 sibling, 0 replies; 4+ messages in thread
From: Ulrich Weigand @ 2018-01-15 16:27 UTC (permalink / raw)
  To: Sangamesh Mallayya
  Cc: gdb-patches, Ulrich Weigand, David Edelsohn, Sanket Rathi

Sangamesh Mallayya wrote:

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

Thanks for working on this!

However, you should not patch AIX-specific code into the generic
PowerPC code in rs6000-tdep.c.  Instead, you should create
code to handle AIX signal frames in rs0000-aix-tdep.c.

To do so, you'll want to call something like
  tramp_frame_prepend_unwinder (gdbarch,  ... your handler ...);
in the rs6000_aix_init_osabi function.  For guidance, you may want to
look at ppc-linux-tdep.c:ppc_linux_init_abi, which already does
the same thing to handle Linux signal frames.

Note that rs6000-aix-tdep.c already defines the SIG_FRAME_* constants.

You should also be able to easily distinguish the 32-bit and 64-bit
cases by just checking tdep->wordsize; no need to export a new global
from xcoffread.c.

As an added bonus, it would be great if you could convert the test
case you had in your email into an actual new test in the GDB test suite,
to help prevent regressing on this support in the future :-)

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-01-15 16:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-15  3:42 [PATCH] Adding support for reading signal hanlder frame in AIX Sangamesh Mallayya
2018-01-15 10:23 ` Yao Qi
2018-01-15 10:54   ` Sangamesh Mallayya
2018-01-15 16:27 ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox