Skip to content

Commit

Permalink
synchronise cpu context changes between crash/gdb
Browse files Browse the repository at this point in the history
Currently, both crash context and gdb's current thread context were
pretty independent, and could be different, for example, crash commands
might be working on thread 6 (CPU 5), but GDB passthroughs will be
working on thread 2 (CPU 1).

This was not a problem earlier since interaction of crash and gdb was
not depending on current context for most part. But with more
interactions, this patch should solve any issues due to mismatch in
context in crash/gdb.

Synchronise 'thread' command in gdb with 'set -c' command in crash.
1. crash -> gdb synchronisation:
   Everytime crash's context changes, a helper is called to switch to
   the thread on that CPU in gdb. The function has been implemented in
   crash_target.c, since gdb functions are accessible inside
   'crash_target.c', and the thread ID to CPU ID mapping is also done
   by the crash_target, during initially registering the threads with
   gdb. With this implementation, GDB's default thread initially also
   changes to the crashing thread, so a switch to crashing thread
   manually isn't required anymore

2. gdb -> crash synchronisation:
   gdb has been patched to call 'set_cpu' whenever user switches to any
   thread.

Cc: Sourabh Jain <[email protected]>
Cc: Hari Bathini <[email protected]>
Cc: Mahesh J Salgaonkar <[email protected]>
Cc: Naveen N. Rao <[email protected]>
Cc: Lianbo Jiang <[email protected]>
Cc: HAGIO KAZUHITO(萩尾 一仁) <[email protected]>
Cc: Tao Liu <[email protected]>
Signed-off-by: Aditya Gupta <[email protected]>
  • Loading branch information
adi-g15-ibm committed Mar 4, 2024
1 parent fecf1c0 commit e058560
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 2 deletions.
24 changes: 24 additions & 0 deletions crash_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ extern "C" int gdb_readmem_callback(unsigned long, void *, int, int);
extern "C" int crash_get_nr_cpus(void);
extern "C" int crash_get_cpu_reg (int cpu, int regno, const char *regname,
int regsize, void *val);
extern "C" int gdb_change_cpu_context (unsigned int cpu);
extern "C" int set_cpu (int cpu);


/* The crash target. */
Expand Down Expand Up @@ -133,3 +135,25 @@ crash_target_init (void)
/* Now, set up the frame cache. */
reinit_frame_cache ();
}

/*
* Change gdb's thread context to the thread on given CPU
**/
extern "C" int
gdb_change_cpu_context(unsigned int cpu)
{
ptid_t ptid = ptid_t(CRASH_INFERIOR_PID, 0, cpu);
inferior *inf = current_inferior ();
thread_info *tp = find_thread_ptid (inf, ptid);

if (tp == nullptr)
return FALSE;

/* Making sure that crash's context is same */
set_cpu(cpu);

/* Switch to the thread */
switch_to_thread(tp);
return TRUE;
}

3 changes: 3 additions & 0 deletions defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -8173,4 +8173,7 @@ enum ppc64_regnum {
PPC64_VRSAVE_REGNU = 139
};

/* crash_target.c */
extern int gdb_change_cpu_context (unsigned int cpu);

#endif /* !GDB_COMMON */
30 changes: 30 additions & 0 deletions gdb-10.2.patch
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

tar xvzmf gdb-10.2.tar.gz \
gdb-10.2/gdb/symtab.c \
gdb-10.2/gdb/thread.c \
gdb-10.2/gdb/printcmd.c \
gdb-10.2/gdb/symfile.c \
gdb-10.2/gdb/Makefile.in \
Expand Down Expand Up @@ -16057,3 +16058,32 @@ exit 0
m10200-dis.c
m10200-opc.c
m10300-dis.c
--- gdb-10.2/gdb/thread.c.orig
+++ gdb-10.2/gdb/thread.c
@@ -58,6 +58,11 @@ static int highest_thread_num;
/* The current/selected thread. */
static thread_info *current_thread_;

+#ifdef CRASH_MERGE
+/* Function to set cpu, defined by crash-utility */
+extern "C" void set_cpu (int);
+#endif
+
/* RAII type used to increase / decrease the refcount of each thread
in a given list of threads. */

@@ -1896,7 +1901,13 @@ thread_command (const char *tidstr, int from_tty)
{
ptid_t previous_ptid = inferior_ptid;

- thread_select (tidstr, parse_thread_id (tidstr, NULL));
+ struct thread_info* thread_id = parse_thread_id (tidstr, NULL);
+
+#ifdef CRASH_MERGE
+ set_cpu(thread_id->ptid.tid());
+#endif
+
+ thread_select (tidstr, thread_id);

/* Print if the thread has not changed, otherwise an event will
be sent. */
8 changes: 7 additions & 1 deletion kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -6527,7 +6527,13 @@ set_cpu(int cpu)
if (hide_offline_cpu(cpu))
error(FATAL, "invalid cpu number: cpu %d is OFFLINE\n", cpu);

if ((task = get_active_task(cpu)))
task = get_active_task(cpu);

/* Check if context is already set to given cpu */
if (task == CURRENT_TASK())
return;

if (task)
set_context(task, NO_PID);
else
error(FATAL, "cannot determine active task on cpu %ld\n", cpu);
Expand Down
4 changes: 3 additions & 1 deletion task.c
Original file line number Diff line number Diff line change
Expand Up @@ -5301,7 +5301,9 @@ set_context(ulong task, ulong pid)

if (found) {
CURRENT_CONTEXT() = tc;
return TRUE;

/* change the selected thread in gdb, according to current context */
return gdb_change_cpu_context(tc->processor);
} else {
if (task)
error(INFO, "cannot set context for task: %lx\n", task);
Expand Down

0 comments on commit e058560

Please sign in to comment.