aboutsummaryrefslogtreecommitdiff
path: root/gdb/rs6000-aix-nat.c
AgeCommit message (Collapse)AuthorFilesLines
2023-01-01Update copyright year range in header of all files managed by GDBJoel Brobecker1-1/+1
This commit is the result of running the gdb/copyright.py script, which automated the update of the copyright year range for all source files managed by the GDB project to be updated to include year 2023.
2022-11-15Enable multi-process debugging for AIXAditya Vidyadhar Kamath1-7/+174
This patch adds multi-process debugging feature in AIX. Till now AIX supported debugging only one inferior at a time, now we can be able to debug multi process. Users can use set follow fork mode in child or parent and set detach on fork on or off to enable/disable simultaneous debugging of parent/child.
2022-10-19internal_error: remove need to pass __FILE__/__LINE__Pedro Alves1-2/+1
Currently, every internal_error call must be passed __FILE__/__LINE__ explicitly, like: internal_error (__FILE__, __LINE__, "foo %d", var); The need to pass in explicit __FILE__/__LINE__ is there probably because the function predates widespread and portable variadic macros availability. We can use variadic macros nowadays, and in fact, we already use them in several places, including the related gdb_assert_not_reached. So this patch renames the internal_error function to something else, and then reimplements internal_error as a variadic macro that expands __FILE__/__LINE__ itself. The result is that we now should call internal_error like so: internal_error ("foo %d", var); Likewise for internal_warning. The patch adjusts all calls sites. 99% of the adjustments were done with a perl/sed script. The non-mechanical changes are in gdbsupport/errors.h, gdbsupport/gdb_assert.h, and gdb/gdbarch.py. Approved-By: Simon Marchi <simon.marchi@efficios.com> Change-Id: Ia6f372c11550ca876829e8fd85048f4502bdcf06
2022-07-21gdb: move the type cast into gdbarch_tdepAndrew Burgess1-3/+3
I built GDB for all targets on a x86-64/GNU-Linux system, and then (accidentally) passed GDB a RISC-V binary, and asked GDB to "run" the binary on the native target. I got this error: (gdb) show architecture The target architecture is set to "auto" (currently "i386"). (gdb) file /tmp/hello.rv32.exe Reading symbols from /tmp/hello.rv32.exe... (gdb) show architecture The target architecture is set to "auto" (currently "riscv:rv32"). (gdb) run Starting program: /tmp/hello.rv32.exe ../../src/gdb/i387-tdep.c:596: internal-error: i387_supply_fxsave: Assertion `tdep->st0_regnum >= I386_ST0_REGNUM' failed. What's going on here is this; initially the architecture is i386, this is based on the default architecture, which is set based on the native target. After loading the RISC-V executable the architecture of the current inferior is updated based on the architecture of the executable. When we "run", GDB does a fork & exec, with the inferior being controlled through ptrace. GDB sees an initial stop from the inferior as soon as the inferior comes to life. In response to this stop GDB ends up calling save_stop_reason (linux-nat.c), which ends up trying to read register from the inferior, to do this we end up calling target_ops::fetch_registers, which, for the x86-64 native target, calls amd64_linux_nat_target::fetch_registers. After this I eventually end up in i387_supply_fxsave, different x86 based targets will end in different functions to fetch registers, but it doesn't really matter which function we end up in, the problem is this line, which is repeated in many places: i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (arch); The problem here is that the ARCH in this line comes from the current inferior, which, as we discussed above, will be a RISC-V gdbarch, the tdep field will actually be of type riscv_gdbarch_tdep, not i386_gdbarch_tdep. After this cast we are relying on undefined behaviour, in my case I happen to trigger an assert, but this might not always be the case. The thing I tried that exposed this problem was of course, trying to start an executable of the wrong architecture on a native target. I don't think that the correct solution for this problem is to detect, at the point of cast, that the gdbarch_tdep object is of the wrong type, but, I did wonder, is there a way that we could protect ourselves from incorrectly casting the gdbarch_tdep object? I think that there is something we can do here, and this commit is the first step in that direction, though no actual check is added by this commit. This commit can be split into two parts: (1) In gdbarch.h and arch-utils.c. In these files I have modified gdbarch_tdep (the function) so that it now takes a template argument, like this: template<typename TDepType> static inline TDepType * gdbarch_tdep (struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep_1 (gdbarch); return static_cast<TDepType *> (tdep); } After this change we are no better protected, but the cast is now done within the gdbarch_tdep function rather than at the call sites, this leads to the second, much larger change in this commit, (2) Everywhere gdbarch_tdep is called, we make changes like this: - i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (arch); + i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch); There should be no functional change after this commit. In the next commit I will build on this change to add an assertion in gdbarch_tdep that checks we are casting to the correct type.
2022-07-07gdb: fix {rs6000_nat_target,aix_thread_target}::wait to not use inferior_ptidSimon Marchi1-4/+3
Trying to run a simple program (empty main) on AIX, I get: (gdb) run Starting program: /scratch/simark/build/gdb/a.out Child process unexpectedly missing: There are no child processes.. ../../src/binutils-gdb/gdb/inferior.c:304: internal-error: find_inferior_pid: Assertion `pid != 0' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ----- Backtrace ----- 0x10ef12a8 gdb_internal_backtrace_1() ../../src/binutils-gdb/gdb/bt-utils.c:122 0x10ef1470 gdb_internal_backtrace() ../../src/binutils-gdb/gdb/bt-utils.c:168 0x1004d368 internal_vproblem(internal_problem*, char const*, int, char const*, char*) ../../src/binutils-gdb/gdb/utils.c:396 0x1004d8a8 internal_verror(char const*, int, char const*, char*) ../../src/binutils-gdb/gdb/utils.c:476 0x1004c424 internal_error(char const*, int, char const*, ...) ../../src/binutils-gdb/gdbsupport/errors.cc:55 0x102ab344 find_inferior_pid(process_stratum_target*, int) ../../src/binutils-gdb/gdb/inferior.c:304 0x102ab4a4 find_inferior_ptid(process_stratum_target*, ptid_t) ../../src/binutils-gdb/gdb/inferior.c:318 0x1061bae8 find_thread_ptid(process_stratum_target*, ptid_t) ../../src/binutils-gdb/gdb/thread.c:519 0x10319e98 handle_inferior_event(execution_control_state*) ../../src/binutils-gdb/gdb/infrun.c:5532 0x10315544 fetch_inferior_event() ../../src/binutils-gdb/gdb/infrun.c:4221 0x10952e34 inferior_event_handler(inferior_event_type) ../../src/binutils-gdb/gdb/inf-loop.c:41 0x1032640c infrun_async_inferior_event_handler(void*) ../../src/binutils-gdb/gdb/infrun.c:9548 0x10673188 check_async_event_handlers() ../../src/binutils-gdb/gdb/async-event.c:335 0x1066fce4 gdb_do_one_event() ../../src/binutils-gdb/gdbsupport/event-loop.cc:214 0x10001a94 start_event_loop() ../../src/binutils-gdb/gdb/main.c:411 0x10001ca0 captured_command_loop() ../../src/binutils-gdb/gdb/main.c:471 0x10003d74 captured_main(void*) ../../src/binutils-gdb/gdb/main.c:1329 0x10003e48 gdb_main(captured_main_args*) ../../src/binutils-gdb/gdb/main.c:1344 0x10000744 main ../../src/binutils-gdb/gdb/gdb.c:32 --------------------- ../../src/binutils-gdb/gdb/inferior.c:304: internal-error: find_inferior_pid: Assertion `pid != 0' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) This is due to some bit-rot in the AIX port, still relying on the entry value of inferior_ptid in the wait methods. Problem #1 is in rs6000_nat_target::wait, here: /* Ignore terminated detached child processes. */ if (!WIFSTOPPED (status) && pid != inferior_ptid.pid ()) pid = -1; At this point, waitpid has returned an "exited" status for some pid, so pid is non-zero. Since inferior_ptid is set to null_ptid on entry, the pid returned by wait is not equal to `inferior_ptid.pid ()`, so we reset pid to -1 and go to waiting again. Since there are not more children to wait for, waitpid then returns -1 so we get here: if (pid == -1) { gdb_printf (gdb_stderr, _("Child process unexpectedly missing: %s.\n"), safe_strerror (save_errno)); /* Claim it exited with unknown signal. */ ourstatus->set_signalled (GDB_SIGNAL_UNKNOWN); return inferior_ptid; } We therefore return a "signalled" status with a null_ptid (again, inferior_ptid is null_ptid). This confuses infrun, because if the target returns a "signalled" status, it should be coupled with a ptid for an inferior that exists. So, the first step is to fix the snippets above to not use inferior_ptid. In the first snippet, use find_inferior_pid to see if we know the event process. If there is no inferior with that pid, we assume it's a detached child process to we ignore the event. That should be enough to fix the problem, because it should make it so we won't go into the second snippet. But still, fix the second snippet to return an "ignore" status. This is copied from inf_ptrace_target::wait, which is where rs6000_nat_target::wait appears to be copied from in the first place. These changes, are not sufficient, as the aix_thread_target, which sits on top of rs6000_nat_target, also relies on inferior_ptid. aix_thread_target::wait, by calling pd_update, assumes that rs6000_nat_target has set inferior_ptid to the appropriate value (the ptid of the event thread), but that's not the case. pd_update returns inferior_ptid - null_ptid - and therefore aix_thread_target::wait returns null_ptid too, and we still hit the assert shown above. Fix this by changing pd_activate, pd_update, sync_threadlists and get_signaled_thread to all avoid using inferior_ptid. Instead, they accept as a parameter the pid of the process we are working on. With this patch, I am able to run the program to completion: (gdb) r Starting program: /scratch/simark/build/gdb/a.out [Inferior 1 (process 11010794) exited normally] As well as break on main: (gdb) b main Breakpoint 1 at 0x1000036c (gdb) r Starting program: /scratch/simark/build/gdb/a.out Breakpoint 1, 0x1000036c in main () (gdb) c Continuing. [Inferior 1 (process 26083688) exited normally] Change-Id: I7c2613bbefe487d75fa1a0c0994423471d961ee9
2022-03-29Unify gdb printf functionsTom Tromey1-9/+9
Now that filtered and unfiltered output can be treated identically, we can unify the printf family of functions. This is done under the name "gdb_printf". Most of this patch was written by script.
2022-01-01Automatic Copyright Year update after running gdb/copyright.pyJoel Brobecker1-1/+1
This commit brings all the changes made by running gdb/copyright.py as per GDB's Start of New Year Procedure. For the avoidance of doubt, all changes in this commits were performed by the script.
2021-12-13gdb: make post_startup_inferior a virtual method on inf_ptrace_targetAndrew Burgess1-0/+5
While working on a later patch that required me to understand how GDB starts up inferiors, I was confused by the target_ops::post_startup_inferior method. The post_startup_inferior target function is only called from inf_ptrace_target::create_inferior. Part of the target class hierarchy looks like this: inf_child_target | '-- inf_ptrace_target | |-- linux_nat_target | |-- fbsd_nat_target | |-- nbsd_nat_target | |-- obsd_nat_target | '-- rs6000_nat_target Every sub-class of inf_ptrace_target, except rs6000_nat_target, implements ::post_startup_inferior. The rs6000_nat_target picks up the implementation of ::post_startup_inferior not from inf_ptrace_target, but from inf_child_target. No descendent of inf_child_target, outside the inf_ptrace_target sub-tree, implements ::post_startup_inferior, which isn't really surprising, as they would never see the method called (remember, the method is only called from inf_ptrace_target::create_inferior). What I find confusing is the role inf_child_target plays in implementing, what is really a helper function for just one of its descendents. In this commit I propose that we formally make ::post_startup_inferior a helper function of inf_ptrace_target. To do this I will remove the ::post_startup_inferior from the target_ops API, and instead make this a protected, pure virtual function on inf_ptrace_target. I'll remove the empty implementation of ::post_startup_inferior from the inf_child_target class, and add a new empty implementation to the rs6000_nat_target class. All the other descendents of inf_ptrace_target already provide an implementation of this method and so don't need to change beyond making the method protected within their class declarations. To me, this makes much more sense now. The helper function, which is only called from within the inf_ptrace_target class, is now a part of the inf_ptrace_target class. The only way in which this change is visible to a user is if the user turns on 'set debug target 1'. With this debug flag on, prior to this patch the user would see something like: -> native->post_startup_inferior (...) <- native->post_startup_inferior (2588939) After this patch these lines are no longer present, as the post_startup_inferior is no longer a top level target method. For me, this is an acceptable change.
2021-12-03gdb: change store_waitstatus to return a target_waitstatus by valueSimon Marchi1-1/+1
store_waitstatus is basically a translation function between a status integer and an equivalent target_waitstatus object. It would make sense for it to take the integer as a parameter and return the target_waitstatus by value. Do that, and rename to host_status_to_waitstatus. Users can then do: ws = host_status_to_waitstatus (status) which does the right thing, given the move constructor of target_waitstatus. Change-Id: I7a07d59d3dc19d3ed66929642f82f44f3e85d61b
2021-11-18gdb: move AIX_TEXT_SEGMENT_BASE to rs6000-aix-tdep.c, remove rs6000-tdep.hSimon Marchi1-1/+0
The contents of rs6000-tdep.h (AIX_TEXT_SEGMENT_BASE) is AIX-specific, so I thought that this file should be named rs6000-aix-tdep.h. But there's already a rs6000-aix-tdep.h, so then I though AIX_TEXT_SEGMENT_BASE should simply be moved there, and rs6000-tdep.h deleted. But then I realized that AIX_TEXT_SEGMENT_BASE is only used in rs6000-aix-tdep.c, so move it to the beginning of that file. Change-Id: Ia212c6fae202f31aedb46575821cd642beeda7a3
2021-11-18gdb: rename rs6000-nat.c to rs6000-aix-nat.cSimon Marchi1-0/+675
This file seems to be AIX-specific, according to its contents and configure.nat. Rename it to rs6000-aix-nat.c, to make that clear (and to follow the convention). Change-Id: Ib418dddc6b79b2e28f64431121742b5e87f5f4f5