mirror of https://gitlab.com/nakst/essence
capture memory dump on test timeout
This commit is contained in:
parent
d49ca458e2
commit
b3d2028aa4
102
util/build.c
102
util/build.c
|
@ -16,11 +16,10 @@
|
|||
#error Unknown target.
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define CROSS_COMPILER_INDEX (11)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -35,6 +34,10 @@
|
|||
#include <pthread.h>
|
||||
#include <sys/wait.h>
|
||||
#include <spawn.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include "../shared/crc.h"
|
||||
|
||||
#define API_TESTS_FOR_RUNNER
|
||||
|
@ -51,8 +54,9 @@ bool coloredOutput;
|
|||
bool encounteredErrors;
|
||||
bool interactiveMode;
|
||||
bool canBuildLuigi;
|
||||
int emulatorTimeout;
|
||||
bool emulatorDidTimeout;
|
||||
volatile int emulatorTimeout;
|
||||
volatile bool emulatorDidTimeout;
|
||||
sem_t emulatorSemaphore;
|
||||
FILE *systemLog;
|
||||
char compilerPath[4096];
|
||||
int argc;
|
||||
|
@ -426,6 +430,59 @@ void Build(int optimise, bool compile) {
|
|||
(double) (endTime.tv_sec - startTime.tv_sec) + (double) (endTime.tv_nsec - startTime.tv_nsec) / 1000000000);
|
||||
}
|
||||
|
||||
void *TimeoutThread(void *) {
|
||||
emulatorDidTimeout = false;
|
||||
|
||||
struct timespec endTime;
|
||||
clock_gettime(CLOCK_REALTIME, &endTime);
|
||||
endTime.tv_sec += emulatorTimeout;
|
||||
|
||||
while (sem_timedwait(&emulatorSemaphore, &endTime)) {
|
||||
if (errno == ETIMEDOUT) {
|
||||
emulatorDidTimeout = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (emulatorDidTimeout) {
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1) perror("socket");
|
||||
struct sockaddr socketName = { AF_UNIX, "qemumon" };
|
||||
if (connect(fd, &socketName, sizeof(socketName) + 8) == -1) perror("connect");
|
||||
|
||||
const char *command1 = "dump-guest-memory -p bin/mem.dat\n";
|
||||
const char *command2 = "quit\n";
|
||||
|
||||
char input[100];
|
||||
int inputBytes;
|
||||
|
||||
inputBytes = recv(fd, input, sizeof(input) - 1, 0);
|
||||
if (inputBytes == -1) perror("recv");
|
||||
else printf("got \"%.*s\"\n", inputBytes, input);
|
||||
|
||||
if (send(fd, command1, strlen(command1), 0) == -1) perror("send");
|
||||
|
||||
sleep(20);
|
||||
|
||||
inputBytes = recv(fd, input, sizeof(input) - 1, 0);
|
||||
if (inputBytes == -1) perror("recv");
|
||||
else printf("got \"%.*s\"\n", inputBytes, input);
|
||||
|
||||
if (send(fd, command2, strlen(command2), 0) == -1) perror("send");
|
||||
|
||||
while (true) {
|
||||
int inputBytes = recv(fd, input, sizeof(input) - 1, 0);
|
||||
if (inputBytes == -1) perror("recv");
|
||||
else if (inputBytes == 0) break;
|
||||
else printf("got \"%.*s\"\n", inputBytes, input);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define LOG_VERBOSE (0)
|
||||
#define LOG_NORMAL (1)
|
||||
#define LOG_NONE (2)
|
||||
|
@ -443,14 +500,6 @@ void Run(int emulator, int log, int debug) {
|
|||
switch (emulator) {
|
||||
case EMULATOR_QEMU_NO_GUI: /* fallthrough */
|
||||
case EMULATOR_QEMU: {
|
||||
char timeoutFlags[256];
|
||||
|
||||
if (emulatorTimeout) {
|
||||
snprintf(timeoutFlags, sizeof(timeoutFlags), "timeout %ds ", emulatorTimeout);
|
||||
} else {
|
||||
timeoutFlags[0] = 0;
|
||||
}
|
||||
|
||||
const char *biosFlags = "";
|
||||
const char *drivePrefix = "-drive file=bin/drive";
|
||||
|
||||
|
@ -542,20 +591,33 @@ void Run(int emulator, int log, int debug) {
|
|||
|
||||
const char *displayFlags = emulator == EMULATOR_QEMU_NO_GUI ? " -display none " : "";
|
||||
|
||||
int exitCode = CallSystemF("%s %s %s " QEMU_EXECUTABLE " %s%s %s -m %d %s -smp cores=%d -cpu Haswell "
|
||||
char timeoutFlags[256];
|
||||
pthread_t timeoutThread;
|
||||
|
||||
if (emulatorTimeout) {
|
||||
sem_init(&emulatorSemaphore, 0, 0);
|
||||
snprintf(timeoutFlags, sizeof(timeoutFlags), "-monitor unix:qemumon,server,nowait ");
|
||||
pthread_create(&timeoutThread, NULL, TimeoutThread, NULL);
|
||||
} else {
|
||||
timeoutFlags[0] = 0;
|
||||
}
|
||||
|
||||
int exitCode = CallSystemF("%s %s " QEMU_EXECUTABLE " %s%s %s -m %d %s -smp cores=%d -cpu Haswell "
|
||||
" -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0,id=mykeyboard -device usb-mouse,bus=xhci.0,id=mymouse "
|
||||
" -netdev user,id=u1 -device e1000,netdev=u1 -object filter-dump,id=f1,netdev=u1,file=bin/Logs/net.dat "
|
||||
" %s %s %s %s %s %s %s %s ",
|
||||
timeoutFlags, audioFlags, IsOptionEnabled("Emulator.RunWithSudo") ? "sudo " : "", drivePrefix, driveFlags, cdromFlags,
|
||||
" %s %s %s %s %s %s %s %s %s ",
|
||||
audioFlags, IsOptionEnabled("Emulator.RunWithSudo") ? "sudo " : "", drivePrefix, driveFlags, cdromFlags,
|
||||
atoi(GetOptionString("Emulator.MemoryMB")),
|
||||
debug ? (debug == DEBUG_NONE ? "-enable-kvm" : "-s -S") : "-s",
|
||||
cpuCores, audioFlags2, logFlags, usbFlags, usbFlags2, secondaryDriveFlags, biosFlags, serialFlags, displayFlags);
|
||||
cpuCores, audioFlags2, usbFlags, usbFlags2, secondaryDriveFlags, biosFlags, serialFlags, displayFlags, timeoutFlags, logFlags);
|
||||
|
||||
bool printStartupErrorMessage = exitCode != 0;
|
||||
|
||||
if (emulatorTimeout) {
|
||||
emulatorDidTimeout = (exitCode >> 8) == 124;
|
||||
sem_post(&emulatorSemaphore);
|
||||
pthread_join(timeoutThread, NULL);
|
||||
if (emulatorDidTimeout) printStartupErrorMessage = false;
|
||||
sem_destroy(&emulatorSemaphore);
|
||||
}
|
||||
|
||||
if (printStartupErrorMessage) {
|
||||
|
@ -1264,7 +1326,7 @@ void GetSource(const char *parameters, const char *checksum) {
|
|||
}
|
||||
|
||||
void RunTests(int singleTest) {
|
||||
// TODO Capture (and compress) emulator memory dump if a test causes a KernelPanic or EsPanic.
|
||||
// TODO Capture emulator memory dump if a test causes a EsPanic.
|
||||
// TODO Using SMP/KVM if available in the optimised test runs.
|
||||
|
||||
int successCount = 0, failureCount = 0;
|
||||
|
@ -1289,6 +1351,7 @@ void RunTests(int singleTest) {
|
|||
if (optimisations) BuildAndRun(OPTIMISE_FULL, true, DEBUG_LATER, EMULATOR_QEMU_NO_GUI, LOG_NORMAL);
|
||||
else BuildAndRun(OPTIMISE_OFF, true, DEBUG_LATER, EMULATOR_QEMU_NO_GUI, LOG_NORMAL);
|
||||
emulatorTimeout = 0;
|
||||
if (emulatorDidTimeout) CallSystemF("mv bin/mem.dat bin/Logs/mem_%d_%d.dat", optimisations, index);
|
||||
if (emulatorDidTimeout) encounteredErrors = false;
|
||||
if (encounteredErrors) { fprintf(stderr, "Compile errors, stopping tests.\n"); goto stopTests; }
|
||||
char *log = (char *) LoadFile("bin/Logs/qemu_serial1.txt", NULL);
|
||||
|
@ -1310,6 +1373,7 @@ void RunTests(int singleTest) {
|
|||
stopTests:;
|
||||
fprintf(stderr, ColorHighlight "%d/%d tests succeeded." ColorNormal "\n", successCount, successCount + failureCount);
|
||||
fclose(testFailures);
|
||||
unlink("root/Essence/Settings/API Tests/test.dat");
|
||||
if (failureCount && automatedBuild) exit(1);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue