mirror of https://gitlab.com/nakst/essence
introduce Flag.PAUSE_ON_USERLAND_CRASH for easier debugging; fix list view selection index with sorted fixed items
This commit is contained in:
parent
83aa4a3d65
commit
86bbaa7a59
|
@ -321,9 +321,7 @@ void UpdateDisplay(Instance *instance, int index) {
|
|||
}
|
||||
|
||||
int ListViewProcessesCallback(EsElement *element, EsMessage *message) {
|
||||
if (message->type == ES_MSG_LIST_VIEW_IS_SELECTED) {
|
||||
message->selectItem.isSelected = processes[message->selectItem.index].data.pid == selectedPID;
|
||||
} else if (message->type == ES_MSG_LIST_VIEW_SELECT && message->selectItem.isSelected) {
|
||||
if (message->type == ES_MSG_LIST_VIEW_SELECT && message->selectItem.isSelected) {
|
||||
selectedPID = processes[message->selectItem.index].data.pid;
|
||||
EsCommandSetDisabled(&element->instance->commandTerminateProcess, selectedPID < 0 || !FindProcessByPID(processes, selectedPID));
|
||||
} else {
|
||||
|
@ -353,6 +351,8 @@ void TerminateProcess(Instance *instance, EsElement *, EsCommand *) {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO What should happen if the user tries to terminate the desktop process?
|
||||
|
||||
EsHandle handle = EsProcessOpen(selectedPID);
|
||||
|
||||
if (handle) {
|
||||
|
|
|
@ -167,6 +167,14 @@ void InitialiseInstance(EsInstance *instance) {
|
|||
|
||||
EsPanel *panel = EsPanelCreate(instance->window, ES_CELL_FILL, &stylePanel);
|
||||
|
||||
EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash (memory error)"), [] (EsInstance *, EsElement *, EsCommand *) {
|
||||
EsMemoryZero((void *) 0, 1);
|
||||
});
|
||||
|
||||
EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash (system call error)"), [] (EsInstance *, EsElement *, EsCommand *) {
|
||||
EsEventSet(1);
|
||||
});
|
||||
|
||||
EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Timing"), [] (EsInstance *, EsElement *element, EsCommand *) {
|
||||
EsDateComponents start, end;
|
||||
|
||||
|
|
|
@ -459,6 +459,16 @@ extern "C" void InterruptHandler(InterruptContext *context) {
|
|||
currentThread->process->cExecutableName,
|
||||
context->rip, context->rsp, context->errorCode, context->cr2);
|
||||
|
||||
#ifdef PAUSE_ON_USERLAND_CRASH
|
||||
if (context->rip) {
|
||||
currentThread->process->pausedFromCrash = true;
|
||||
// x86_64 for "jmp $".
|
||||
((uint8_t *) context->rip)[0] = 0xEB;
|
||||
((uint8_t *) context->rip)[1] = 0xFE;
|
||||
goto resolved;
|
||||
}
|
||||
#endif
|
||||
|
||||
EsPrint("Attempting to make a stack trace...\n");
|
||||
|
||||
{
|
||||
|
|
|
@ -260,6 +260,16 @@ const void *const apiTable[] = {
|
|||
#include <bin/generated_code/api_array.h>
|
||||
};
|
||||
|
||||
#ifdef PAUSE_ON_USERLAND_CRASH
|
||||
ES_EXTERN_C uintptr_t APISyscallCheckForCrash(uintptr_t argument0, uintptr_t argument1, uintptr_t argument2, uintptr_t unused, uintptr_t argument3, uintptr_t argument4) {
|
||||
uintptr_t returnValue = _APISyscall(argument0, argument1, argument2, unused, argument3, argument4);
|
||||
EsProcessState state;
|
||||
_APISyscall(ES_SYSCALL_PROCESS_GET_STATE, ES_CURRENT_PROCESS, (uintptr_t) &state, 0, 0, 0);
|
||||
while (state.flags & ES_PROCESS_STATE_PAUSED_FROM_CRASH);
|
||||
return returnValue;
|
||||
}
|
||||
#endif
|
||||
|
||||
MountPoint *NodeAddMountPoint(const char *prefix, size_t prefixBytes, EsHandle base, bool queryInformation) {
|
||||
MountPoint mountPoint = {};
|
||||
EsAssert(prefixBytes < sizeof(mountPoint.prefix));
|
||||
|
|
|
@ -963,7 +963,13 @@ struct EsListView : EsElement {
|
|||
}
|
||||
|
||||
m.type = ES_MSG_LIST_VIEW_SELECT;
|
||||
fixedItemSelection = m.selectItem.index;
|
||||
|
||||
if (flags & ES_LIST_VIEW_FIXED_ITEMS) {
|
||||
fixedItemSelection = m.selectItem.index;
|
||||
EsAssert((uintptr_t) m.selectItem.index < fixedItems.Length());
|
||||
m.selectItem.index = fixedItemIndices[m.selectItem.index];
|
||||
}
|
||||
|
||||
EsMessageSend(this, &m);
|
||||
|
||||
ignore:;
|
||||
|
|
|
@ -273,10 +273,11 @@ define ES_SCANCODE_WWW_STOP (0x10F)
|
|||
define ES_SCANCODE_WWW_REFRESH (0x110)
|
||||
define ES_SCANCODE_WWW_STARRED (0x111)
|
||||
|
||||
define ES_PROCESS_STATE_ALL_THREADS_TERMINATED (1)
|
||||
define ES_PROCESS_STATE_TERMINATING (2)
|
||||
define ES_PROCESS_STATE_CRASHED (4)
|
||||
define ES_PROCESS_STATE_PINGED (8)
|
||||
define ES_PROCESS_STATE_ALL_THREADS_TERMINATED (1 << 0)
|
||||
define ES_PROCESS_STATE_TERMINATING (1 << 1)
|
||||
define ES_PROCESS_STATE_CRASHED (1 << 2)
|
||||
private define ES_PROCESS_STATE_PINGED (1 << 3)
|
||||
private define ES_PROCESS_STATE_PAUSED_FROM_CRASH (1 << 4)
|
||||
|
||||
define ES_FLAGS_DEFAULT (0)
|
||||
define ES_SUCCESS (-1)
|
||||
|
|
|
@ -169,8 +169,14 @@ struct ES_INSTANCE_TYPE;
|
|||
#ifndef KERNEL
|
||||
#ifdef ES_API
|
||||
ES_EXTERN_C uintptr_t _APISyscall(uintptr_t argument0, uintptr_t argument1, uintptr_t argument2, uintptr_t unused, uintptr_t argument3, uintptr_t argument4);
|
||||
#ifdef PAUSE_ON_USERLAND_CRASH
|
||||
ES_EXTERN_C uintptr_t APISyscallCheckForCrash(uintptr_t argument0, uintptr_t argument1, uintptr_t argument2, uintptr_t unused, uintptr_t argument3, uintptr_t argument4);
|
||||
#define EsSyscall(a, b, c, d, e) APISyscallCheckForCrash((a), (b), (c), 0, (d), (e))
|
||||
#define _EsSyscall APISyscallCheckForCrash
|
||||
#else
|
||||
#define EsSyscall(a, b, c, d, e) _APISyscall((a), (b), (c), 0, (d), (e))
|
||||
#define _EsSyscall _APISyscall
|
||||
#endif
|
||||
#else
|
||||
#define EsSyscall(a, b, c, d, e) _EsSyscall((a), (b), (c), 0, (d), (e))
|
||||
#endif
|
||||
|
|
|
@ -169,6 +169,11 @@ struct Process {
|
|||
KMutex crashMutex;
|
||||
EsCrashReason crashReason;
|
||||
bool crashed;
|
||||
#ifdef PAUSE_ON_USERLAND_CRASH
|
||||
// To allow for better remote debugging if PAUSE_ON_USERLAND_CRASH is defined,
|
||||
// when a process crashes it will return to where the crash occurred and enter an infinite loop.
|
||||
bool pausedFromCrash;
|
||||
#endif
|
||||
|
||||
// Termination:
|
||||
bool allThreadsTerminated;
|
||||
|
|
|
@ -1220,6 +1220,9 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PROCESS_GET_STATE) {
|
|||
state.flags = (process->allThreadsTerminated ? ES_PROCESS_STATE_ALL_THREADS_TERMINATED : 0)
|
||||
| (process->preventNewThreads ? ES_PROCESS_STATE_TERMINATING : 0)
|
||||
| (process->crashed ? ES_PROCESS_STATE_CRASHED : 0)
|
||||
#ifdef PAUSE_ON_USERLAND_CRASH
|
||||
| (process->pausedFromCrash ? ES_PROCESS_STATE_PAUSED_FROM_CRASH : 0)
|
||||
#endif
|
||||
| (process->messageQueue.pinged ? ES_PROCESS_STATE_PINGED : 0);
|
||||
|
||||
SYSCALL_WRITE(argument1, &state, sizeof(EsProcessState));
|
||||
|
@ -1781,7 +1784,11 @@ uintptr_t DoSyscall(EsSyscallType index, uintptr_t argument0, uintptr_t argument
|
|||
reason.duringSystemCall = index;
|
||||
KernelLog(LOG_ERROR, "Syscall", "syscall failure",
|
||||
"Process crashed during system call [%x, %x, %x, %x, %x]\n", index, argument0, argument1, argument2, argument3);
|
||||
#ifdef PAUSE_ON_USERLAND_CRASH
|
||||
currentProcess->pausedFromCrash = true;
|
||||
#else
|
||||
ProcessCrash(currentProcess, &reason);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -295,6 +295,7 @@ Option options[] = {
|
|||
{ "Flag.COM_OUTPUT", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Flag.POST_PANIC_DEBUGGING", OPTION_TYPE_BOOL, { .b = false } },
|
||||
{ "Flag.START_DEBUG_OUTPUT", OPTION_TYPE_BOOL, { .b = false } },
|
||||
{ "Flag.PAUSE_ON_USERLAND_CRASH", OPTION_TYPE_BOOL, { .b = false } },
|
||||
{ "Dependency.ACPICA", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Dependency.stb_image", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Dependency.stb_image_write", OPTION_TYPE_BOOL, { .b = true } },
|
||||
|
|
Loading…
Reference in New Issue