* [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\x1dnr\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