Changeset View
Changeset View
Standalone View
Standalone View
head/devel/gdb/files/kgdb/fbsd-kthr.c
Show First 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | kgdb_thr_add_procs(CORE_ADDR paddr, CORE_ADDR (*cpu_pcb_addr) (u_int)) | ||||
struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; | struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; | ||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | ||||
struct kthr *kt; | struct kthr *kt; | ||||
CORE_ADDR pcb, pnext, tdaddr, tdnext; | CORE_ADDR pcb, pnext, tdaddr, tdnext; | ||||
ULONGEST oncpu; | ULONGEST oncpu; | ||||
LONGEST pid, tid; | LONGEST pid, tid; | ||||
while (paddr != 0) { | while (paddr != 0) { | ||||
TRY { | try { | ||||
tdaddr = read_memory_typed_address (paddr + | tdaddr = read_memory_typed_address (paddr + | ||||
proc_off_p_threads, ptr_type); | proc_off_p_threads, ptr_type); | ||||
pid = read_memory_integer (paddr + proc_off_p_pid, 4, | pid = read_memory_integer (paddr + proc_off_p_pid, 4, | ||||
byte_order); | byte_order); | ||||
pnext = read_memory_typed_address (paddr + | pnext = read_memory_typed_address (paddr + | ||||
proc_off_p_list, ptr_type); | proc_off_p_list, ptr_type); | ||||
} CATCH(e, RETURN_MASK_ERROR) { | } catch (const gdb_exception_error &e) { | ||||
break; | break; | ||||
} END_CATCH | } | ||||
while (tdaddr != 0) { | while (tdaddr != 0) { | ||||
TRY { | try { | ||||
tid = read_memory_integer (tdaddr + | tid = read_memory_integer (tdaddr + | ||||
thread_off_td_tid, 4, byte_order); | thread_off_td_tid, 4, byte_order); | ||||
oncpu = read_memory_unsigned_integer (tdaddr + | oncpu = read_memory_unsigned_integer (tdaddr + | ||||
thread_off_td_oncpu, thread_oncpu_size, | thread_off_td_oncpu, thread_oncpu_size, | ||||
byte_order); | byte_order); | ||||
pcb = read_memory_typed_address (tdaddr + | pcb = read_memory_typed_address (tdaddr + | ||||
thread_off_td_pcb, ptr_type); | thread_off_td_pcb, ptr_type); | ||||
tdnext = read_memory_typed_address (tdaddr + | tdnext = read_memory_typed_address (tdaddr + | ||||
thread_off_td_plist, ptr_type); | thread_off_td_plist, ptr_type); | ||||
} CATCH(e, RETURN_MASK_ERROR) { | } catch (const gdb_exception_error &e) { | ||||
break; | break; | ||||
} END_CATCH | } | ||||
kt = XNEW (struct kthr); | kt = XNEW (struct kthr); | ||||
if (last == NULL) | if (last == NULL) | ||||
first = last = kt; | first = last = kt; | ||||
else | else | ||||
last->next = kt; | last->next = kt; | ||||
kt->next = NULL; | kt->next = NULL; | ||||
kt->kaddr = tdaddr; | kt->kaddr = tdaddr; | ||||
if (tid == dumptid) | if (tid == dumptid) | ||||
Show All 26 Lines | while (first != NULL) { | ||||
first = kt->next; | first = kt->next; | ||||
free(kt); | free(kt); | ||||
} | } | ||||
last = NULL; | last = NULL; | ||||
addr = kgdb_lookup("allproc"); | addr = kgdb_lookup("allproc"); | ||||
if (addr == 0) | if (addr == 0) | ||||
return (NULL); | return (NULL); | ||||
TRY { | try { | ||||
paddr = read_memory_typed_address (addr, ptr_type); | paddr = read_memory_typed_address (addr, ptr_type); | ||||
} CATCH(e, RETURN_MASK_ERROR) { | } catch (const gdb_exception_error &e) { | ||||
return (NULL); | return (NULL); | ||||
} END_CATCH | } | ||||
dumppcb = kgdb_lookup("dumppcb"); | dumppcb = kgdb_lookup("dumppcb"); | ||||
if (dumppcb == 0) | if (dumppcb == 0) | ||||
return (NULL); | return (NULL); | ||||
TRY { | try { | ||||
dumptid = parse_and_eval_long("dumptid"); | dumptid = parse_and_eval_long("dumptid"); | ||||
} CATCH(e, RETURN_MASK_ERROR) { | } catch (const gdb_exception_error &e) { | ||||
dumptid = -1; | dumptid = -1; | ||||
} END_CATCH | } | ||||
TRY { | try { | ||||
mp_maxid = parse_and_eval_long("mp_maxid"); | mp_maxid = parse_and_eval_long("mp_maxid"); | ||||
} CATCH(e, RETURN_MASK_ERROR) { | } catch (const gdb_exception_error &e) { | ||||
mp_maxid = 0; | mp_maxid = 0; | ||||
} END_CATCH | } | ||||
stopped_cpus = kgdb_lookup("stopped_cpus"); | stopped_cpus = kgdb_lookup("stopped_cpus"); | ||||
/* | /* | ||||
* Newer kernels export a set of global variables with the offsets | * Newer kernels export a set of global variables with the offsets | ||||
* of certain members in struct proc and struct thread. For older | * of certain members in struct proc and struct thread. For older | ||||
* kernels, try to extract these offsets using debug symbols. If | * kernels, try to extract these offsets using debug symbols. If | ||||
* that fails, use native values. | * that fails, use native values. | ||||
*/ | */ | ||||
TRY { | try { | ||||
proc_off_p_pid = parse_and_eval_long("proc_off_p_pid"); | proc_off_p_pid = parse_and_eval_long("proc_off_p_pid"); | ||||
proc_off_p_comm = parse_and_eval_long("proc_off_p_comm"); | proc_off_p_comm = parse_and_eval_long("proc_off_p_comm"); | ||||
proc_off_p_list = parse_and_eval_long("proc_off_p_list"); | proc_off_p_list = parse_and_eval_long("proc_off_p_list"); | ||||
proc_off_p_threads = parse_and_eval_long("proc_off_p_threads"); | proc_off_p_threads = parse_and_eval_long("proc_off_p_threads"); | ||||
thread_off_td_tid = parse_and_eval_long("thread_off_td_tid"); | thread_off_td_tid = parse_and_eval_long("thread_off_td_tid"); | ||||
thread_off_td_name = parse_and_eval_long("thread_off_td_name"); | thread_off_td_name = parse_and_eval_long("thread_off_td_name"); | ||||
thread_off_td_oncpu = parse_and_eval_long("thread_off_td_oncpu"); | thread_off_td_oncpu = parse_and_eval_long("thread_off_td_oncpu"); | ||||
thread_off_td_pcb = parse_and_eval_long("thread_off_td_pcb"); | thread_off_td_pcb = parse_and_eval_long("thread_off_td_pcb"); | ||||
thread_off_td_plist = parse_and_eval_long("thread_off_td_plist"); | thread_off_td_plist = parse_and_eval_long("thread_off_td_plist"); | ||||
thread_oncpu_size = 4; | thread_oncpu_size = 4; | ||||
} CATCH(e, RETURN_MASK_ERROR) { | } catch (const gdb_exception_error &e) { | ||||
TRY { | try { | ||||
proc_off_p_pid = parse_and_eval_address( | struct symbol *proc_sym = | ||||
"&((struct proc *)0)->p_pid"); | lookup_symbol_in_language ("struct proc", NULL, | ||||
proc_off_p_comm = parse_and_eval_address( | STRUCT_DOMAIN, language_c, NULL).symbol; | ||||
"&((struct proc *)0)->p_comm"); | if (proc_sym == NULL) | ||||
proc_off_p_list = parse_and_eval_address( | error (_("Unable to find struct proc symbol")); | ||||
"&((struct proc *)0)->p_list"); | |||||
proc_off_p_threads = parse_and_eval_address( | proc_off_p_pid = | ||||
"&((struct proc *)0)->p_threads"); | lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_pid", | ||||
thread_off_td_tid = parse_and_eval_address( | 0).offset / 8; | ||||
"&((struct thread *)0)->td_tid"); | proc_off_p_comm = | ||||
thread_off_td_name = parse_and_eval_address( | lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_comm", | ||||
"&((struct thread *)0)->td_name"); | 0).offset / 8; | ||||
thread_off_td_oncpu = parse_and_eval_address( | proc_off_p_list = | ||||
"&((struct thread *)0)->td_oncpu"); | lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_list", | ||||
thread_off_td_pcb = parse_and_eval_address( | 0).offset / 8; | ||||
"&((struct thread *)0)->td_pcb"); | proc_off_p_threads = | ||||
thread_off_td_plist = parse_and_eval_address( | lookup_struct_elt (SYMBOL_TYPE (proc_sym), | ||||
"&((struct thread *)0)->td_plist"); | "p_threads", 0).offset / 8; | ||||
thread_oncpu_size = parse_and_eval_long( | |||||
"sizeof(((struct thread *)0)->td_oncpu)"); | struct symbol *thread_sym = | ||||
} CATCH(e2, RETURN_MASK_ERROR) { | lookup_symbol_in_language ("struct thread", NULL, | ||||
STRUCT_DOMAIN, language_c, NULL).symbol; | |||||
if (thread_sym == NULL) | |||||
error (_("Unable to find struct thread symbol")); | |||||
thread_off_td_tid = | |||||
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_tid", | |||||
0).offset / 8; | |||||
thread_off_td_name = | |||||
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_name", | |||||
0).offset / 8; | |||||
thread_off_td_pcb = | |||||
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_pcb", | |||||
0).offset / 8; | |||||
thread_off_td_plist = | |||||
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_plist", | |||||
0).offset / 8; | |||||
struct_elt td_oncpu = | |||||
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_oncpu", | |||||
0); | |||||
thread_off_td_oncpu = td_oncpu.offset / 8; | |||||
thread_oncpu_size = FIELD_BITSIZE(*td_oncpu.field) / 8; | |||||
} catch (const gdb_exception_error &e2) { | |||||
proc_off_p_pid = offsetof(struct proc, p_pid); | proc_off_p_pid = offsetof(struct proc, p_pid); | ||||
proc_off_p_comm = offsetof(struct proc, p_comm); | proc_off_p_comm = offsetof(struct proc, p_comm); | ||||
proc_off_p_list = offsetof(struct proc, p_list); | proc_off_p_list = offsetof(struct proc, p_list); | ||||
proc_off_p_threads = offsetof(struct proc, p_threads); | proc_off_p_threads = offsetof(struct proc, p_threads); | ||||
thread_off_td_tid = offsetof(struct thread, td_tid); | thread_off_td_tid = offsetof(struct thread, td_tid); | ||||
thread_off_td_name = offsetof(struct thread, td_name); | thread_off_td_name = offsetof(struct thread, td_name); | ||||
thread_off_td_oncpu = offsetof(struct thread, td_oncpu); | thread_off_td_oncpu = offsetof(struct thread, td_oncpu); | ||||
thread_off_td_pcb = offsetof(struct thread, td_pcb); | thread_off_td_pcb = offsetof(struct thread, td_pcb); | ||||
thread_off_td_plist = offsetof(struct thread, td_plist); | thread_off_td_plist = offsetof(struct thread, td_plist); | ||||
thread_oncpu_size = | thread_oncpu_size = | ||||
sizeof(((struct thread *)0)->td_oncpu); | sizeof(((struct thread *)0)->td_oncpu); | ||||
} END_CATCH | } | ||||
} END_CATCH | } | ||||
kgdb_thr_add_procs(paddr, cpu_pcb_addr); | kgdb_thr_add_procs(paddr, cpu_pcb_addr); | ||||
addr = kgdb_lookup("zombproc"); | addr = kgdb_lookup("zombproc"); | ||||
if (addr != 0) { | if (addr != 0) { | ||||
TRY { | try { | ||||
paddr = read_memory_typed_address (addr, ptr_type); | paddr = read_memory_typed_address (addr, ptr_type); | ||||
kgdb_thr_add_procs(paddr, cpu_pcb_addr); | kgdb_thr_add_procs(paddr, cpu_pcb_addr); | ||||
} CATCH(e, RETURN_MASK_ERROR) { | } catch (const gdb_exception_error &e) { | ||||
} END_CATCH | |||||
} | } | ||||
} | |||||
curkthr = kgdb_thr_lookup_tid(dumptid); | curkthr = kgdb_thr_lookup_tid(dumptid); | ||||
if (curkthr == NULL) | if (curkthr == NULL) | ||||
curkthr = first; | curkthr = first; | ||||
return (first); | return (first); | ||||
} | } | ||||
struct kthr * | struct kthr * | ||||
kgdb_thr_lookup_tid(int tid) | kgdb_thr_lookup_tid(int tid) | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | kgdb_thr_extra_thread_info(int tid) | ||||
char td_name[MAXCOMLEN + 1]; | char td_name[MAXCOMLEN + 1]; | ||||
struct kthr *kt; | struct kthr *kt; | ||||
static char buf[64]; | static char buf[64]; | ||||
kt = kgdb_thr_lookup_tid(tid); | kt = kgdb_thr_lookup_tid(tid); | ||||
if (kt == NULL) | if (kt == NULL) | ||||
return (NULL); | return (NULL); | ||||
snprintf(buf, sizeof(buf), "PID=%d", kt->pid); | snprintf(buf, sizeof(buf), "PID=%d", kt->pid); | ||||
TRY { | try { | ||||
read_memory_string (kt->paddr + proc_off_p_comm, comm, | read_memory_string (kt->paddr + proc_off_p_comm, comm, | ||||
sizeof(comm)); | sizeof(comm)); | ||||
strlcat(buf, ": ", sizeof(buf)); | strlcat(buf, ": ", sizeof(buf)); | ||||
strlcat(buf, comm, sizeof(buf)); | strlcat(buf, comm, sizeof(buf)); | ||||
read_memory_string (kt->kaddr + thread_off_td_name, td_name, | read_memory_string (kt->kaddr + thread_off_td_name, td_name, | ||||
sizeof(td_name)); | sizeof(td_name)); | ||||
if (strcmp(comm, td_name) != 0) { | if (strcmp(comm, td_name) != 0) { | ||||
strlcat(buf, "/", sizeof(buf)); | strlcat(buf, "/", sizeof(buf)); | ||||
strlcat(buf, td_name, sizeof(buf)); | strlcat(buf, td_name, sizeof(buf)); | ||||
} | } | ||||
} CATCH(e, RETURN_MASK_ERROR) { | } catch (const gdb_exception_error &e) { | ||||
} END_CATCH | } | ||||
return (buf); | return (buf); | ||||
} | } |