The "where" or "sc" command now switches the page directory to the specified thread
to be able to follow the stack trace into userland. No symbols there, yet, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14697 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -83,13 +83,15 @@ void x86_write_msr(uint32 register, uint64 value);
|
|||||||
void x86_set_task_gate(int32 n, int32 segment);
|
void x86_set_task_gate(int32 n, int32 segment);
|
||||||
struct tss *x86_get_main_tss(void);
|
struct tss *x86_get_main_tss(void);
|
||||||
|
|
||||||
|
|
||||||
#define read_ebp(value) \
|
#define read_ebp(value) \
|
||||||
__asm__("movl %%ebp,%0" : "=r" (value))
|
__asm__("movl %%ebp,%0" : "=r" (value))
|
||||||
|
|
||||||
#define read_cr3(value) \
|
#define read_cr3(value) \
|
||||||
__asm__("movl %%cr3,%0" : "=r" (value))
|
__asm__("movl %%cr3,%0" : "=r" (value))
|
||||||
|
|
||||||
|
#define write_cr3(value) \
|
||||||
|
__asm__("movl %0,%%cr3" : : "r" (value))
|
||||||
|
|
||||||
#define read_dr3(value) \
|
#define read_dr3(value) \
|
||||||
__asm__("movl %%dr3,%0" : "=r" (value))
|
__asm__("movl %%dr3,%0" : "=r" (value))
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ extern "C" {
|
|||||||
void x86_push_iframe(struct iframe_stack *stack, struct iframe *frame);
|
void x86_push_iframe(struct iframe_stack *stack, struct iframe *frame);
|
||||||
void x86_pop_iframe(struct iframe_stack *stack);
|
void x86_pop_iframe(struct iframe_stack *stack);
|
||||||
struct iframe *i386_get_user_iframe(void);
|
struct iframe *i386_get_user_iframe(void);
|
||||||
|
void *x86_next_page_directory(struct thread *from, struct thread *to);
|
||||||
|
|
||||||
void i386_return_from_signal();
|
void i386_return_from_signal();
|
||||||
void i386_end_return_from_signal();
|
void i386_end_return_from_signal();
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ stack_trace(int argc, char **argv)
|
|||||||
uint32 previousLocations[NUM_PREVIOUS_LOCATIONS];
|
uint32 previousLocations[NUM_PREVIOUS_LOCATIONS];
|
||||||
struct iframe_stack *frameStack;
|
struct iframe_stack *frameStack;
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
|
addr_t oldPageDirectory = 0;
|
||||||
uint32 ebp;
|
uint32 ebp;
|
||||||
int32 i, num = 0, last = 0;
|
int32 i, num = 0, last = 0;
|
||||||
|
|
||||||
@@ -90,6 +91,18 @@ stack_trace(int argc, char **argv)
|
|||||||
|
|
||||||
// read %ebp from the thread's stack stored by a pushad
|
// read %ebp from the thread's stack stored by a pushad
|
||||||
ebp = thread->arch_info.current_stack.esp[2];
|
ebp = thread->arch_info.current_stack.esp[2];
|
||||||
|
|
||||||
|
if (id != thread_get_current_thread_id()) {
|
||||||
|
// switch to the page directory of the new thread to be
|
||||||
|
// able to follow the stack trace into userland
|
||||||
|
addr_t newPageDirectory = (addr_t)x86_next_page_directory(
|
||||||
|
thread_get_current_thread(), thread);
|
||||||
|
|
||||||
|
if (newPageDirectory != 0) {
|
||||||
|
read_cr3(oldPageDirectory);
|
||||||
|
write_cr3(newPageDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't have a thread pointer early in the boot process
|
// We don't have a thread pointer early in the boot process
|
||||||
@@ -185,6 +198,11 @@ stack_trace(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldPageDirectory != 0) {
|
||||||
|
// switch back to the previous page directory to no cause any troubles
|
||||||
|
write_cr3(oldPageDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,29 @@ i386_get_user_iframe(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void *
|
||||||
|
x86_next_page_directory(struct thread *from, struct thread *to)
|
||||||
|
{
|
||||||
|
if (from->team->aspace != NULL && to->team->aspace != NULL) {
|
||||||
|
// they are both uspace threads
|
||||||
|
if (from->team == to->team) {
|
||||||
|
// dont change the pgdir, same address space
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// switching to a new address space
|
||||||
|
return i386_translation_map_get_pgdir(&to->team->aspace->translation_map);
|
||||||
|
} else if (from->team->aspace == NULL && to->team->aspace == NULL) {
|
||||||
|
// they must both be kspace threads
|
||||||
|
return NULL;
|
||||||
|
} else if (to->team->aspace == NULL) {
|
||||||
|
// the one we're switching to is kspace
|
||||||
|
return i386_translation_map_get_pgdir(&to->team->kaspace->translation_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i386_translation_map_get_pgdir(&to->team->aspace->translation_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
set_fs_register(uint32 segment)
|
set_fs_register(uint32 segment)
|
||||||
{
|
{
|
||||||
@@ -225,9 +248,9 @@ arch_thread_switch_kstack_and_call(struct thread *t, addr_t new_kstack, void (*f
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
|
arch_thread_context_switch(struct thread *from, struct thread *to)
|
||||||
{
|
{
|
||||||
void *new_pgdir;
|
addr_t newPageDirectory;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int i;
|
int i;
|
||||||
@@ -242,42 +265,25 @@ arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
|
|||||||
for (i = 0; i < 11; i++)
|
for (i = 0; i < 11; i++)
|
||||||
dprintf("*esp[%d] (0x%x) = 0x%x\n", i, ((unsigned int *)new_at->esp + i), *((unsigned int *)new_at->esp + i));
|
dprintf("*esp[%d] (0x%x) = 0x%x\n", i, ((unsigned int *)new_at->esp + i), *((unsigned int *)new_at->esp + i));
|
||||||
#endif
|
#endif
|
||||||
i386_set_tss_and_kstack(t_to->kernel_stack_base + KERNEL_STACK_SIZE);
|
i386_set_tss_and_kstack(to->kernel_stack_base + KERNEL_STACK_SIZE);
|
||||||
|
|
||||||
// set TLS GDT entry to the current thread - since this action is
|
// set TLS GDT entry to the current thread - since this action is
|
||||||
// dependent on the current CPU, we have to do it here
|
// dependent on the current CPU, we have to do it here
|
||||||
if (t_to->user_local_storage != NULL)
|
if (to->user_local_storage != NULL)
|
||||||
set_tls_context(t_to);
|
set_tls_context(to);
|
||||||
|
|
||||||
if (t_from->team->aspace != NULL && t_to->team->aspace != NULL) {
|
newPageDirectory = (addr_t)x86_next_page_directory(from, to);
|
||||||
// they are both uspace threads
|
|
||||||
if (t_from->team == t_to->team) {
|
|
||||||
// dont change the pgdir, same address space
|
|
||||||
new_pgdir = NULL;
|
|
||||||
} else {
|
|
||||||
// switching to a new address space
|
|
||||||
new_pgdir = i386_translation_map_get_pgdir(&t_to->team->aspace->translation_map);
|
|
||||||
}
|
|
||||||
} else if (t_from->team->aspace == NULL && t_to->team->aspace == NULL) {
|
|
||||||
// they must both be kspace threads
|
|
||||||
new_pgdir = NULL;
|
|
||||||
} else if (t_to->team->aspace == NULL) {
|
|
||||||
// the one we're switching to is kspace
|
|
||||||
new_pgdir = i386_translation_map_get_pgdir(&t_to->team->kaspace->translation_map);
|
|
||||||
} else {
|
|
||||||
new_pgdir = i386_translation_map_get_pgdir(&t_to->team->aspace->translation_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((uint32)new_pgdir % B_PAGE_SIZE) != 0)
|
if ((newPageDirectory % B_PAGE_SIZE) != 0)
|
||||||
panic("arch_thread_context_switch: bad pgdir 0x%lx\n", new_pgdir);
|
panic("arch_thread_context_switch: bad pgdir 0x%lx\n", newPageDirectory);
|
||||||
|
|
||||||
// reinit debugging; necessary, if the thread was preempted after
|
// reinit debugging; necessary, if the thread was preempted after
|
||||||
// initializing debugging before returning to userland
|
// initializing debugging before returning to userland
|
||||||
if (t_to->team->aspace != NULL)
|
if (to->team->aspace != NULL)
|
||||||
i386_reinit_user_debug_after_context_switch(t_to);
|
i386_reinit_user_debug_after_context_switch(to);
|
||||||
|
|
||||||
i386_fsave_swap(t_from->arch_info.fpu_state, t_to->arch_info.fpu_state);
|
i386_fsave_swap(from->arch_info.fpu_state, to->arch_info.fpu_state);
|
||||||
i386_context_switch(&t_from->arch_info, &t_to->arch_info, (addr_t)new_pgdir);
|
i386_context_switch(&from->arch_info, &to->arch_info, newPageDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user