User can see all errors reported by error_report().
Removed most emulator specified codes.
Renamed some source files.
Removed redudant header includes.
Change-Id: I61f92f4e32763eaa1e3ed20c77259dd8b034d497
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
#include "qom/object.h"
#include "hw/boards.h"
#include "sysemu/hax.h"
-
-#ifdef CONFIG_MARU
-#include "tizen/src/util/maru_err_table.h"
-#endif
+#include "qemu/error-report.h"
int tcg_tb_size;
static bool tcg_allowed = true;
if (!accel_initialised) {
if (!init_failed) {
- fprintf(stderr, "No accelerator found!\n");
+// CONFIG_MARU MODIFICATION
+// fprintf(stderr, "No accelerator found!\n");
+ error_report("No accelerator found!\n");
}
-#ifdef CONFIG_MARU
- maru_register_exit_msg(MARU_EXIT_UNKNOWN, NO_ACCELERATOR_FOUND);
-#endif
exit(1);
}
#include "sysemu/arch_init.h"
#ifdef CONFIG_MARU
-#include "tizen/src/util/maru_err_table.h"
+#include "tizen/src/util/exported_strings.h"
#endif
static const char *const if_name[IF_COUNT] = {
assert(bs == blk_bs(blk));
if (ret < 0) {
-#ifdef CONFIG_MARU
- char *path = get_canonical_path(file);
- char *msg = g_strdup_printf("%s%s%s", FAILED_TO_LOAD_DISK, CHECK_FILE_VALID, path);
-
- start_simple_client(msg);
-
- g_free(path);
- g_free(msg);
-#endif
-
error_setg(errp, "could not open disk image %s: %s",
file ?: blk_name(blk), error_get_pretty(error));
error_free(error);
#include "virtio-9p-coth.h"
#include "hw/virtio/virtio-access.h"
-#ifdef CONFIG_MARU
-#include "tizen/src/util/maru_err_table.h"
-#endif
-
static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
{
features |= 1 << VIRTIO_9P_MOUNT_TAG;
if (s->ops->init(&s->ctx) < 0) {
error_setg(errp, "Virtio-9p Failed to initialize fs-driver with id:%s"
" and export path:%s", s->fsconf.fsdev_id, s->ctx.fs_root);
-#ifdef CONFIG_MARU
- gchar *canonical_path = get_canonical_path(s->ctx.fs_root);
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- "Virtio-9p Failed to initialize fs-driver with id: %s"
- " and export path: %s", s->fsconf.fsdev_id, canonical_path);
- g_free(canonical_path);
-#endif
goto out;
}
if (v9fs_init_worker_threads() < 0) {
}
if (s->ops->lstat(&s->ctx, &path, &stat)) {
error_setg(errp, "share path %s does not exist", fse->path);
-#ifdef CONFIG_MARU
- gchar *canonical_path = get_canonical_path(fse->path);
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- "share path %s does not exist", canonical_path);
- g_free(canonical_path);
-#endif
goto out;
} else if (!S_ISDIR(stat.st_mode)) {
error_setg(errp, "share path %s is not a directory", fse->path);
-#ifdef CONFIG_MARU
- gchar *canonical_path = get_canonical_path(fse->path);
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- "share path %s is not a directory", canonical_path);
- g_free(canonical_path);
-#endif
goto out;
}
#include "qapi/visitor.h"
#include "qapi-visit.h"
-#ifdef CONFIG_MARU
-#include "tizen/src/util/maru_err_table.h"
-#endif
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ
if (!f || !(kernel_size = get_file_size(f)) ||
fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) !=
MIN(ARRAY_SIZE(header), kernel_size)) {
- fprintf(stderr, "qemu: could not load kernel '%s': %s\n",
+// CONFIG_MARU MODIFICATION
+// fprintf(stderr, "qemu: could not load kernel '%s': %s\n",
+// kernel_filename, strerror(errno));
+ error_report("qemu: could not load kernel '%s': %s\n",
kernel_filename, strerror(errno));
-#ifdef CONFIG_MARU
- char *path = get_canonical_path(kernel_filename);
- maru_register_exit_msg(MARU_EXIT_KERNEL_FILE_EXCEPTION, path);
-
g_free(path);
-#endif
exit(1);
}
#include "hw/block/flash.h"
#include "sysemu/kvm.h"
-#ifdef CONFIG_MARU
-#include "tizen/src/util/maru_err_table.h"
-#endif
-
#define BIOS_FILENAME "bios.bin"
typedef struct PcSysFwDevice {
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
if (ret != 0) {
bios_error:
- fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
-#ifdef CONFIG_MARU
- maru_register_exit_msg(MARU_EXIT_BIOS_FILE_EXCEPTION, bios_name);
-#endif
+// CONFIG_MARU MODIFICATION
+// fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
+ error_report("qemu: could not load PC BIOS '%s'\n", bios_name);
exit(1);
}
if (filename) {
const char *error_get_progname(void);
extern bool enable_timestamp_msg;
+#ifdef CONFIG_MARU
+#include "qemu/queue.h"
+
+typedef struct ErrorReporter ErrorReporter;
+
+struct ErrorReporter
+{
+ void (*report)(const char *fmt, va_list ap);
+ QLIST_ENTRY(ErrorReporter) node;
+};
+
+void add_error_reporter(ErrorReporter *new_reporter);
+#endif
+
#endif
#include <png.h>
#include "qemu/main-loop.h"
+#include "qemu/error-report.h"
+
#include "maru_display.h"
#include "emul_state.h"
#include "maru_display_processing.h"
#include "hw/pci/maru_brightness.h"
#include "skin/maruskin_server.h"
-#include "util/maru_err_table.h"
#include "debug_ch.h"
#include "eventcast/encode_fb.h"
ERR("shmget failed\n");
perror("maru_vga: ");
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- (char*) "Cannot launch this VM.\n"
+ error_report("Cannot launch this VM."
"Failed to get identifier of the shared memory segment.");
exit(1);
}
ERR("shmat failed\n");
perror("maru_vga: ");
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- (char*) "Cannot launch this VM.\n"
+ error_report("Cannot launch this VM. "
"Failed to attach the shared memory segment.");
exit(1);
}
#include "skin/maruskin_operation.h"
#include "skin/maruskin_server.h"
-#include "util/maru_device_hotplug.h"
+#include "util/device_hotplug.h"
#include "util/hds.h"
#include "emul_state.h"
#include "ecs.h"
#include "hw/virtio/maru_virtio_jack.h"
#include "hw/virtio/maru_virtio_power.h"
-#include "util/maru_device_hotplug.h"
+#include "util/device_hotplug.h"
#include "util/hds.h"
#include "emul_state.h"
#include "ecs.h"
#include "ecs_sdcard.h"
#include "ecs.h"
#include "util/osutil.h"
-#include "util/maru_device_hotplug.h"
+#include "util/device_hotplug.h"
#include "debug_ch.h"
#include "emul_state.h"
#include "emul_state.h"
#include "emulator_options.h"
#include "util/check_gl.h"
-#include "util/maru_err_table.h"
+#include "util/error_handler.h"
#include "util/osutil.h"
#include "util/sdb.h"
#include "skin/maruskin_server.h"
#include "util/new_debug_ch.h"
#include "ecs/ecs.h"
-#include "util/maru_device_hotplug.h"
+#include "util/device_hotplug.h"
+#include "util/exported_strings.h"
#ifdef CONFIG_SDL
#include <SDL.h>
/* the next line checks for debugging and etc.. */
if (get_emul_skin_enable()) {
if (0 > start_skin_client(skin_argc, skin_argv)) {
- maru_register_exit_msg(MARU_EXIT_SKIN_SERVER_FAILED, NULL);
- exit(-1);
+ error_report(FAILED_TO_INITIALIZE_SKIN);
+ exit(1);
}
}
}
reset_variables();
LOG_INFO("Exit emulator...\n");
-
- handle_error_at_exit();
}
static Notifier emulator_exit = { .notify = emulator_notify_exit };
#if defined (CONFIG_LINUX)
int main(int argc, char *argv[], char **envp)
{
- register_exception_handler();
+ init_error_handler();
return emulator_main(argc, argv, envp);
}
#else
int main(int argc, char *argv[])
{
- register_exception_handler();
+ init_error_handler();
return emulator_main(argc, argv, NULL);
}
#endif
#include "emul_state.h"
#include "hw/virtio/maru_virtio_touchscreen.h"
#include "util/check_gl.h"
-#include "util/maru_err_table.h"
+#include "util/error_handler.h"
#include "display/maru_display.h"
#include "util/osutil.h"
#include "util/sdb.h"
extract_qemu_info(_qemu_argc, _qemu_argv);
INFO("Emulator start !!!\n");
- atexit(handle_error_at_exit);
emulator_add_exit_notifier(&emulator_exit);
extract_skin_info(_skin_argc, _skin_argv);
#ifdef CONFIG_WIN32
#include <windows.h>
-#include "util/maru_err_table.h"
+#include "qemu/error-report.h"
#endif
MULTI_DEBUG_CHANNEL(qemu, skinclient);
&pi))
{
ERR("Unable to generate process! error %u\n", GetLastError());
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- "CreateProcess function failed. Unable to generate process.");
+ error_report("CreateProcess function failed. "
+ "Unable to generate process.");
exit(1);
}
#ifndef MARUSKIN_CLIENT_H_
#define MARUSKIN_CLIENT_H_
-#include "tizen/src/util/maru_util_strings.h"
+#include "tizen/src/util/exported_strings.h"
int start_skin_client(int argc, char* argv[]);
int start_simple_client(char* msg);
#include "maruskin_server.h"
#include "display/maru_display.h"
#include "hw/maru_pm.h"
-#include "util/maru_device_hotplug.h"
+#include "util/device_hotplug.h"
#include "ecs/ecs.h"
#include "hw/virtio/maru_virtio_evdi.h"
#include "hw/virtio/maru_virtio_rotary.h"
#include "maruskin_server.h"
#include "maruskin_operation.h"
#include "display/maru_display.h"
-#include "util/maru_err_table.h"
#include "ecs/ecs.h"
#include "emul_state.h"
+#include "util/exported_strings.h"
#ifdef CONFIG_WIN32
#include <windows.h>
ERR("!!! Fail to operate with heartbeat from skin client. Shutdown QEMU !!!\n");
ERR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
- maru_register_exit_msg(MARU_EXIT_HB_TIME_EXPIRED, NULL);
+ error_report(EMULATOR_HAS_STOPPED "\n");
shutdown_qemu_gracefully(TIMEOUT_FOR_SHUTDOWN);
}
obj-$(CONFIG_DARWIN) += check_gl_cgl.o
# hotplug
-obj-y += maru_device_hotplug.o
+obj-y += device_hotplug.o
-# error table
-obj-y += maru_err_table.o
+# error handler
+obj-y += error_handler.o
# debug channel
obj-y += new_debug_ch.o
--- /dev/null
+/*
+ * Maru device hotplug
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "qemu/main-loop.h"
+#include "qemu/config-file.h"
+#include "hw/qdev.h"
+#include "qemu/event_notifier.h"
+
+#include "emulator.h"
+#include "emul_state.h"
+#include "device_hotplug.h"
+#include "ecs/ecs.h"
+#include "hds.h"
+#include "ecs/ecs_sdcard.h"
+
+#define HOST_KEYBOARD_DRIVER "virtio-keyboard-pci"
+#define HOST_KEYBOARD_DEFAULT_ID "HOSTKBD0"
+
+#define FS_MOUNT_TAG "fileshare"
+
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, hotplug);
+
+struct maru_device_hotplug {
+ EventNotifier notifier;
+
+ char *opaque;
+ int command;
+
+ // FIXME: Should we query device every time ??
+ bool host_keyboard_attached;
+ bool sdcard_attached;
+};
+
+static struct maru_device_hotplug *state;
+
+static bool do_host_keyboard_attach(void)
+{
+ QDict *qdict = qdict_new();
+ qdict_put(qdict, "driver", qstring_from_str(HOST_KEYBOARD_DRIVER));
+ qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID));
+
+ if (do_device_add(default_mon, qdict, NULL)) {
+ QDECREF(qdict);
+ // TODO error reporting
+ return false;
+ }
+
+ QDECREF(qdict);
+
+ state->host_keyboard_attached = true;
+
+ return true;
+}
+
+static bool do_host_keyboard_detach(void)
+{
+ QDict *qdict = qdict_new();
+ qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID));
+
+ if (qmp_marshal_input_device_del(default_mon, qdict, NULL)) {
+ QDECREF(qdict);
+ // TODO error reporting
+ return false;
+ }
+
+ QDECREF(qdict);
+
+ state->host_keyboard_attached = false;
+
+ return true;
+}
+
+static bool do_sdcard_attach(const char * const file)
+{
+ QDict *qdict = qdict_new();
+ QDict *qdict_file = qdict_new();
+ QDict *qdict_options = qdict_new();
+ gchar *sdcard_img = g_path_get_basename(file);
+ gchar *sdcard_device_id = g_strdup_printf("device_id_%s", sdcard_img);
+ gchar *sdcard_drive_id = g_strdup_printf("drive_id_%s", sdcard_img);
+
+ g_free(sdcard_img);
+
+ qdict_put(qdict_file, "driver", qstring_from_str("file"));
+ qdict_put(qdict_file, "filename", qstring_from_str(file));
+ qdict_put(qdict_options, "file", qdict_file);
+ qdict_put(qdict_options, "driver", qstring_from_str("qcow2"));
+ qdict_put(qdict_options, "id", qstring_from_str(sdcard_device_id));
+ qdict_put(qdict, "options", qdict_options);
+
+ qmp_marshal_input_blockdev_add(default_mon, qdict, NULL);
+
+ QDECREF(qdict);
+
+ qdict = qdict_new();
+ qdict_put(qdict, "driver", qstring_from_str(SDCARD_DRIVER));
+ qdict_put(qdict, "drive", qstring_from_str(sdcard_device_id));
+ /* set sdcard id as sdcard image file name */
+ qdict_put(qdict, "id", qstring_from_str(sdcard_drive_id));
+
+ if (do_device_add(default_mon, qdict, NULL)) {
+ QDECREF(qdict);
+ LOG_WARNING("failed to attach sdcard: %s", file);
+ g_free(sdcard_device_id);
+ g_free(sdcard_drive_id);
+ return false;
+ }
+
+ QDECREF(qdict);
+ g_free(sdcard_device_id);
+ g_free(sdcard_drive_id);
+ state->sdcard_attached = true;
+ return true;
+}
+
+static bool do_sdcard_detach(const char * const file)
+{
+ QDict *qdict = qdict_new();
+ gchar *sdcard_drive_id = g_strdup_printf("drive_id_%s", g_path_get_basename(file));
+ qdict_put(qdict, "id", qstring_from_str(sdcard_drive_id));
+
+ if (qmp_marshal_input_device_del(cur_mon, qdict, NULL)) {
+ QDECREF(qdict);
+ g_free(sdcard_drive_id);
+ LOG_WARNING("failed to detach sdcard: %s", file);
+ return false;
+ }
+
+ QDECREF(qdict);
+ state->sdcard_attached = false;
+ g_free(sdcard_drive_id);
+ return true;
+}
+
+static bool do_hds_attach(const char * const id)
+{
+ QemuOpts *fsdev;
+ int ret;
+ QDict *qdict;
+ char* host;
+ int len = 0;
+ char* guest = NULL;
+ char emuld_data [OUT_BUF_SIZE];
+
+ fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
+ id, 0, NULL);
+ if (!fsdev) {
+ return false;
+ }
+
+ LOG_INFO("do_hds_attach - id: %s\n", id);
+
+ host = get_host_path_by_id((char*)id);
+ if (host == NULL) {
+ LOG_SEVERE("host path is null\n");
+ return false;
+ }
+
+ qemu_opt_set(fsdev, "fsdriver", "local");
+ qemu_opt_set(fsdev, "path", host);
+ qemu_opt_set(fsdev, "security_model", "none");
+
+ ret = qemu_fsdev_add(fsdev);
+ if (ret != 0) {
+ return false;
+ }
+
+ qdict = qdict_new();
+ qdict_put(qdict, "driver", qstring_from_str("virtio-9p-pci"));
+ qdict_put(qdict, "fsdev", qstring_from_str(id));
+ qdict_put(qdict, "mount_tag", qstring_from_str(id));
+ qdict_put(qdict, "id", qstring_from_str(id));
+
+ if (do_device_add(default_mon, qdict, NULL)) {
+ QDECREF(qdict);
+ return false;
+ }
+
+ set_hds_attached(id, true);
+
+ QDECREF(qdict);
+
+ // send mount message to emuld
+
+ guest = get_guest_path_by_id((char*)id);
+ if (guest == NULL) {
+ LOG_SEVERE("guest path is null\n");
+ return false;
+ }
+
+ len = snprintf(emuld_data, sizeof(emuld_data), "%s\n%s\n", id, guest);
+ LOG_INFO("send emuld to mount: %s", emuld_data);
+ send_msg_to_guest(MSG_TYPE_HDS, MSG_GROUP_HDS, HDS_ACTION_MOUNT, emuld_data, len + 1);
+
+ return true;
+}
+
+static bool do_hds_detach(const char * const id)
+{
+ QDict *qdict = qdict_new();
+ qemu_fsdev_remove(id);
+
+ qdict_put(qdict, "id", qstring_from_str(id));
+
+ if (qmp_marshal_input_device_del(cur_mon, qdict, NULL)) {
+ QDECREF(qdict);
+ return false;
+ }
+
+ QDECREF(qdict);
+
+ remove_hds_list(id);
+
+ return true;
+}
+
+void do_hotplug(int command, void *opaque, size_t size)
+{
+ if (opaque != NULL && size > 0) {
+ state->opaque = g_malloc(size);
+ memcpy(state->opaque, opaque, size);
+ }
+ state->command = command;
+
+ event_notifier_set(&state->notifier);
+}
+
+static void device_hotplug_handler(EventNotifier *e)
+{
+ event_notifier_test_and_clear(e);
+
+ switch(state->command) {
+ case ATTACH_HOST_KEYBOARD:
+ do_host_keyboard_attach();
+ break;
+ case DETACH_HOST_KEYBOARD:
+ do_host_keyboard_detach();
+ break;
+ case ATTACH_SDCARD:
+ do_sdcard_attach(state->opaque);
+ break;
+ case DETACH_SDCARD:
+ do_sdcard_detach(state->opaque);
+ break;
+ case ATTACH_HDS:
+ do_hds_attach(state->opaque);
+ break;
+ case DETACH_HDS:
+ do_hds_detach(state->opaque);
+ break;
+ default:
+ break;
+ }
+
+ if (state->opaque != NULL) {
+ g_free(state->opaque);
+ state->opaque = NULL;
+ }
+}
+
+static void deinit_maru_device_hotplug(Notifier *notifier, void *data)
+{
+ event_notifier_cleanup(&state->notifier);
+
+ g_free(state);
+}
+
+static Notifier maru_device_hotplug_exit = { .notify = deinit_maru_device_hotplug };
+
+void init_device_hotplug(void)
+{
+ state = g_malloc0(sizeof(struct maru_device_hotplug));
+
+ event_notifier_init(&state->notifier, 0);
+ event_notifier_set_handler(&state->notifier, device_hotplug_handler);
+
+ emulator_add_exit_notifier(&maru_device_hotplug_exit);
+}
+
+bool is_host_keyboard_attached(void)
+{
+ return state->host_keyboard_attached;
+}
+
+bool is_sdcard_attached(void)
+{
+ //TODO: support checking multi sdcard attached
+ return state->sdcard_attached;
+}
--- /dev/null
+/*
+ * Maru device hotplug
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef _MARU_DEVICE_HOTPLUG_H_
+#define _MARU_DEVICE_HOTPLUG_H_
+
+enum command {
+ ATTACH_HOST_KEYBOARD,
+ DETACH_HOST_KEYBOARD,
+ ATTACH_SDCARD,
+ DETACH_SDCARD,
+ ATTACH_HDS,
+ DETACH_HDS,
+};
+
+void init_device_hotplug(void);
+
+void do_hotplug(int command, void *opaque, size_t size);
+
+bool is_host_keyboard_attached(void);
+bool is_sdcard_attached(void);
+
+#endif // _MARU_DEVICE_HOTPLUG_H_
--- /dev/null
+/*
+ * Error handler
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#include "qemu-common.h"
+
+#ifdef CONFIG_WIN32
+#include <windows.h>
+#else
+#include <execinfo.h>
+#endif
+
+#include "qemu/error-report.h"
+
+#include "error_handler.h"
+#include "emulator_common.h"
+#include "emulator.h"
+
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, backtrace);
+
+// deprecated
+/* This table must match the enum definition */
+static char _maru_string_table[][JAVA_MAX_COMMAND_LENGTH] = {
+ /* 0 */ "",
+ /* 1 */ FAILED_TO_ALLOCATE_MEMORY,
+ /* 2 */ FAILED_TO_LOAD_KERNEL CHECK_FILE_VALID,
+ /* 3 */ FAILED_TO_LOAD_BIOS CHECK_FILE_VALID,
+ /* 4 */ FAILED_TO_INITIALIZE_SKIN,
+ /* 5 */ EMULATOR_HAS_STOPPED,
+ /* add here.. */
+ ""
+};
+
+static int maru_exit_status = MARU_EXIT_NORMAL;
+static char *maru_exit_msg;
+
+#ifdef CONFIG_WIN32
+static LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter;
+#endif
+
+#ifdef CONFIG_LINUX
+static pthread_spinlock_t siglock;
+void maru_sighandler(int sig);
+#endif
+
+// deprecated
+char *get_canonical_path(char const *const path)
+{
+ if ((int)g_path_is_absolute(path)) {
+ return (char *)g_strdup(path);
+ }
+
+ char *canonical_path;
+
+#ifndef _WIN32
+ char *current_dir = g_get_current_dir();
+ canonical_path = g_strdup_printf("%s/%s", current_dir, path);
+ g_free(current_dir);
+#else
+ canonical_path = g_malloc(MAX_PATH);
+ GetFullPathName(path, MAX_PATH, canonical_path, NULL);
+#endif
+
+ return canonical_path;
+}
+
+// deprecated
+// Use error_report() instead
+void register_exit_message(int status, char const *format, ...)
+{
+ va_list args;
+
+ if (status >= MARU_EXIT_NORMAL) {
+ fprintf(stderr, "Invalid error message index = %d\n",
+ status);
+ return;
+ }
+ if (maru_exit_status != MARU_EXIT_NORMAL) {
+ fprintf(stderr, "The error message is already registered = %d\n",
+ maru_exit_status);
+ return;
+ }
+
+ maru_exit_status = status;
+
+ if (maru_exit_status == MARU_EXIT_HB_TIME_EXPIRED) {
+ fprintf(stderr, "Skin client could not connect to Skin server."
+ " The time of internal heartbeat has expired.\n");
+ }
+
+ if (!format) {
+ format = "";
+ }
+
+ va_start(args, format);
+ char *additional = g_strdup_vprintf(format, args);
+ va_end(args);
+ maru_exit_msg = g_strdup_printf("%s%s", _maru_string_table[maru_exit_status],
+ additional);
+ g_free(additional);
+
+ if (strlen(maru_exit_msg) >= JAVA_MAX_COMMAND_LENGTH) {
+ maru_exit_msg[JAVA_MAX_COMMAND_LENGTH - 1] = '\0';
+ }
+
+ fprintf(stdout, "The error message is registered = %d : %s\n",
+ maru_exit_status, maru_exit_msg);
+}
+
+/* Print 'backtrace' */
+#ifdef _WIN32
+struct frame_layout {
+ void *pNext;
+ void *pReturnAddr;
+};
+
+static char *get_filename_from_path(char *path_buf)
+{
+ char *ret_slash;
+ char *ret_rslash;
+
+ ret_slash = strrchr(path_buf, '/');
+ ret_rslash = strrchr(path_buf, '\\');
+
+ if (ret_slash || ret_rslash) {
+ if (ret_slash > ret_rslash) {
+ return ret_slash + 1;
+ } else{
+ return ret_rslash + 1;
+ }
+ }
+
+ return path_buf;
+}
+
+
+static HMODULE get_module_handle(DWORD dwAddress)
+{
+ MEMORY_BASIC_INFORMATION Buffer;
+ return VirtualQuery((LPCVOID) dwAddress, &Buffer, sizeof(Buffer))
+ ? (HMODULE) Buffer.AllocationBase : (HMODULE) 0;
+}
+#endif
+
+static void dump_backtrace(void *ptr, int depth)
+{
+#ifdef _WIN32
+ int nCount;
+ void *pTopFrame;
+ struct frame_layout currentFrame;
+ struct frame_layout *pCurrentFrame;
+
+ char module_buf[1024];
+ HMODULE hModule;
+
+ PCONTEXT pContext = ptr;
+ if (!pContext) {
+ __asm__ __volatile__ ("movl %%ebp, %0" : "=m" (pTopFrame));
+ } else {
+ pTopFrame = (void *)((PCONTEXT)pContext)->Ebp;
+ }
+
+ if (pTopFrame == NULL) {
+ INFO("ebp is null, skip this for now\n");
+ return ;
+ }
+
+ nCount = 0;
+ currentFrame.pNext = ((struct frame_layout *)pTopFrame)->pNext;
+ currentFrame.pReturnAddr = ((struct frame_layout *)pTopFrame)->pReturnAddr;
+ pCurrentFrame = (struct frame_layout *)pTopFrame;
+
+ ERR("\nBacktrace Dump Start :\n");
+ if (pContext) {
+ memset(module_buf, 0, sizeof(module_buf));
+ hModule = get_module_handle((DWORD)((PCONTEXT)pContext)->Eip);
+ if (hModule) {
+ if (!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))) {
+ memset(module_buf, 0, sizeof(module_buf));
+ }
+ }
+ ERR("[%02d]Addr = 0x%p : %s\n", nCount, ((PCONTEXT)pContext)->Eip, get_filename_from_path(module_buf));
+ nCount++;
+ }
+
+ while (1) {
+ if (((void *)pCurrentFrame < pTopFrame)
+ || ((void *)pCurrentFrame >= (void *)0xC0000000)) {
+ break;
+ }
+
+ memset(module_buf, 0, sizeof(module_buf));
+ hModule = get_module_handle((DWORD)currentFrame.pReturnAddr);
+ if (hModule) {
+ if (!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))) {
+ memset(module_buf, 0, sizeof(module_buf));
+ }
+ }
+ ERR("[%02d]Addr = 0x%p : %s\n", nCount, currentFrame.pReturnAddr, get_filename_from_path(module_buf));
+
+ if (!ReadProcessMemory(GetCurrentProcess(), currentFrame.pNext,
+ (void *)¤tFrame, sizeof(struct frame_layout), NULL)) {
+ break;
+ }
+ pCurrentFrame = (struct frame_layout *)pCurrentFrame->pNext;
+
+ if (depth) {
+ if (!--depth) {
+ break;
+ }
+ }
+ nCount++;
+ }
+#else
+ void *trace[1024];
+ int ndepth = backtrace(trace, 1024);
+ ERR("Backtrace depth is %d.\n", ndepth);
+
+ backtrace_symbols_fd(trace, ndepth, fileno(stderr));
+#endif
+}
+
+static void handle_error_at_exit(void)
+{
+
+ // deprecated
+ if (maru_exit_status != MARU_EXIT_NORMAL || maru_exit_msg) {
+ start_simple_client(maru_exit_msg);
+ }
+ g_free(maru_exit_msg);
+
+ // dump backtrace log no matter what
+ INFO("Stack backtrace for tracing...\n");
+ INFO("This is not an error.\n");
+ dump_backtrace(NULL, 0);
+}
+
+#ifdef CONFIG_WIN32
+static WINAPI LONG maru_unhandled_exception_filter(LPEXCEPTION_POINTERS pExceptionInfo){
+ char module_buf[1024];
+
+ // print system information again
+ print_system_info();
+
+ DWORD dwException = pExceptionInfo->ExceptionRecord->ExceptionCode;
+ ERR("%d\n ", (int)dwException);
+
+ PEXCEPTION_RECORD pExceptionRecord;
+ HMODULE hModule;
+ PCONTEXT pContext;
+
+ pExceptionRecord = pExceptionInfo->ExceptionRecord;
+
+ memset(module_buf, 0, sizeof(module_buf));
+ hModule = get_module_handle((DWORD)pExceptionRecord->ExceptionAddress);
+ if(hModule){
+ if(!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))){
+ memset(module_buf, 0, sizeof(module_buf));
+ }
+ }
+
+ ERR("Exception [%X] occured at %s:0x%08x\n",
+ pExceptionRecord->ExceptionCode,
+ get_filename_from_path(module_buf),
+ pExceptionRecord->ExceptionAddress
+ );
+
+ pContext = pExceptionInfo->ContextRecord;
+ dump_backtrace(pContext, 0);
+ _exit(0);
+ //return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
+#ifdef CONFIG_LINUX
+void maru_sighandler(int sig)
+{
+ ERR("Got signal %d\n", sig);
+ // print system information again
+ print_system_info();
+
+ pthread_spin_lock(&siglock);
+ dump_backtrace(NULL, 0);
+ pthread_spin_unlock(&siglock);
+ _exit(0);
+}
+#endif
+
+
+#ifndef CONFIG_DARWIN
+static void register_exception_handler(void)
+{
+ #ifdef CONFIG_WIN32
+ prevExceptionFilter = SetUnhandledExceptionFilter(maru_unhandled_exception_filter);
+ #else // LINUX
+ void *trace[1];
+ struct sigaction sa;
+
+ // make dummy call to explicitly load glibc library
+ backtrace(trace, 1);
+
+ pthread_spin_init(&siglock,0);
+ sa.sa_handler = (void*) maru_sighandler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+ sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
+ sigaction(SIGABRT, &sa, NULL);
+ // main thread only
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ #endif
+}
+#else // CONFIG_DARWIN
+static void register_exception_handler(void)
+{
+ // TODO: Exception handling on darwin
+}
+#endif
+
+#define MAX_MESSAGE_LEN 2048
+static size_t message_len;
+static char message[MAX_MESSAGE_LEN];
+
+static void report(const char *fmt, va_list ap)
+{
+ char *new_message = g_strdup_vprintf(fmt, ap);
+ message_len = g_strlcat(message, new_message, MAX_MESSAGE_LEN);
+ g_free(new_message);
+
+ // We are wating for '\n'
+ if (message[message_len - 1] == '\n') {
+ fprintf(stderr, "%s", message);
+ start_simple_client(message);
+ message[0] = '\0';
+ message_len = 0;
+ }
+}
+
+static ErrorReporter error_reporter =
+ { .report = report };
+
+void init_error_handler(void) {
+ register_exception_handler();
+ add_error_reporter(&error_reporter);
+
+ atexit(handle_error_at_exit);
+}
--- /dev/null
+/*
+ * Error handler
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+
+#ifndef __ERROR_HANDLER_H__
+#define __ERROR_HANDLER_H__
+
+#include "tizen/src/skin/maruskin_client.h"
+
+// deprecated
+/* TODO: define macro for fair of definition */
+/* This enum must match the table definition */
+enum {
+ /* 0 */ MARU_EXIT_UNKNOWN = 0,
+ /* 1 */ MARU_EXIT_MEMORY_EXCEPTION,
+ /* 2 */ MARU_EXIT_KERNEL_FILE_EXCEPTION,
+ /* 3 */ MARU_EXIT_BIOS_FILE_EXCEPTION,
+ /* 4 */ MARU_EXIT_SKIN_SERVER_FAILED,
+ /* 5 */ MARU_EXIT_HB_TIME_EXPIRED,
+ /* add here.. */
+ MARU_EXIT_NORMAL
+};
+
+void init_error_handler(void);
+// deprecated
+void register_exit_message(int status, char const *format, ...);
+// deprecated
+char *get_canonical_path(char const *const path);
+
+#endif /* __ERROR_HANDLER_H__ */
--- /dev/null
+/*
+ * The strings for the emulator messages
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Sooyoung Ha <yoosah.ha@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Sangho Park <sangho.p@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+
+#ifndef __MARU_UTIL_STRINGS_H__
+#define __MARU_UTIL_STRINGS_H__
+
+#define FAILED_TO_ALLOCATE_MEMORY "Failed to allocate memory in qemu."
+#define FAILED_TO_LOAD_KERNEL "Failed to load a kernel file the following path."
+#define FAILED_TO_LOAD_BIOS "Failed to load a bios file in bios path that mentioned on document."
+#define FAILED_TO_LOAD_DISK "Failed to load disk file from the following path."
+#define CHECK_FILE_VALID " Check if the file is corrupted or missing.\n\n"
+#define FAILED_TO_INITIALIZE_SKIN "Skin process cannot be initialized. Skin server is not ready."
+#define FAILED_TO_INSTALL_EXTRAPACKAGE_1 "Extra package installation is failed.\n"
+#define FAILED_TO_INSTALL_EXTRAPACKAGE_2 " must be installed MANUALLY!"
+#define EMULATOR_HAS_STOPPED "Emulator has stopped working.\nA problem caused the program to stop working correctly."
+#define NO_ACCELERATOR_FOUND "No accelerator found."
+
+#endif /* __MARU_UTIL_STRINGS_H__ */
+++ /dev/null
-/*
- * Maru device hotplug
- *
- * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#include "qemu/main-loop.h"
-#include "qemu/config-file.h"
-#include "hw/qdev.h"
-#include "qemu/event_notifier.h"
-
-#include "emulator.h"
-#include "emul_state.h"
-#include "maru_device_hotplug.h"
-#include "ecs/ecs.h"
-#include "hds.h"
-#include "ecs/ecs_sdcard.h"
-
-#define HOST_KEYBOARD_DRIVER "virtio-keyboard-pci"
-#define HOST_KEYBOARD_DEFAULT_ID "HOSTKBD0"
-
-#define FS_MOUNT_TAG "fileshare"
-
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, hotplug);
-
-struct maru_device_hotplug {
- EventNotifier notifier;
-
- char *opaque;
- int command;
-
- // FIXME: Should we query device every time ??
- bool host_keyboard_attached;
- bool sdcard_attached;
-};
-
-static struct maru_device_hotplug *state;
-
-static bool do_host_keyboard_attach(void)
-{
- QDict *qdict = qdict_new();
- qdict_put(qdict, "driver", qstring_from_str(HOST_KEYBOARD_DRIVER));
- qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID));
-
- if (do_device_add(default_mon, qdict, NULL)) {
- QDECREF(qdict);
- // TODO error reporting
- return false;
- }
-
- QDECREF(qdict);
-
- state->host_keyboard_attached = true;
-
- return true;
-}
-
-static bool do_host_keyboard_detach(void)
-{
- QDict *qdict = qdict_new();
- qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID));
-
- if (qmp_marshal_input_device_del(default_mon, qdict, NULL)) {
- QDECREF(qdict);
- // TODO error reporting
- return false;
- }
-
- QDECREF(qdict);
-
- state->host_keyboard_attached = false;
-
- return true;
-}
-
-static bool do_sdcard_attach(const char * const file)
-{
- QDict *qdict = qdict_new();
- QDict *qdict_file = qdict_new();
- QDict *qdict_options = qdict_new();
- gchar *sdcard_img = g_path_get_basename(file);
- gchar *sdcard_device_id = g_strdup_printf("device_id_%s", sdcard_img);
- gchar *sdcard_drive_id = g_strdup_printf("drive_id_%s", sdcard_img);
-
- g_free(sdcard_img);
-
- qdict_put(qdict_file, "driver", qstring_from_str("file"));
- qdict_put(qdict_file, "filename", qstring_from_str(file));
- qdict_put(qdict_options, "file", qdict_file);
- qdict_put(qdict_options, "driver", qstring_from_str("qcow2"));
- qdict_put(qdict_options, "id", qstring_from_str(sdcard_device_id));
- qdict_put(qdict, "options", qdict_options);
-
- qmp_marshal_input_blockdev_add(default_mon, qdict, NULL);
-
- QDECREF(qdict);
-
- qdict = qdict_new();
- qdict_put(qdict, "driver", qstring_from_str(SDCARD_DRIVER));
- qdict_put(qdict, "drive", qstring_from_str(sdcard_device_id));
- /* set sdcard id as sdcard image file name */
- qdict_put(qdict, "id", qstring_from_str(sdcard_drive_id));
-
- if (do_device_add(default_mon, qdict, NULL)) {
- QDECREF(qdict);
- LOG_WARNING("failed to attach sdcard: %s", file);
- g_free(sdcard_device_id);
- g_free(sdcard_drive_id);
- return false;
- }
-
- QDECREF(qdict);
- g_free(sdcard_device_id);
- g_free(sdcard_drive_id);
- state->sdcard_attached = true;
- return true;
-}
-
-static bool do_sdcard_detach(const char * const file)
-{
- QDict *qdict = qdict_new();
- gchar *sdcard_drive_id = g_strdup_printf("drive_id_%s", g_path_get_basename(file));
- qdict_put(qdict, "id", qstring_from_str(sdcard_drive_id));
-
- if (qmp_marshal_input_device_del(cur_mon, qdict, NULL)) {
- QDECREF(qdict);
- g_free(sdcard_drive_id);
- LOG_WARNING("failed to detach sdcard: %s", file);
- return false;
- }
-
- QDECREF(qdict);
- state->sdcard_attached = false;
- g_free(sdcard_drive_id);
- return true;
-}
-
-static bool do_hds_attach(const char * const id)
-{
- QemuOpts *fsdev;
- int ret;
- QDict *qdict;
- char* host;
- int len = 0;
- char* guest = NULL;
- char emuld_data [OUT_BUF_SIZE];
-
- fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
- id, 0, NULL);
- if (!fsdev) {
- return false;
- }
-
- LOG_INFO("do_hds_attach - id: %s\n", id);
-
- host = get_host_path_by_id((char*)id);
- if (host == NULL) {
- LOG_SEVERE("host path is null\n");
- return false;
- }
-
- qemu_opt_set(fsdev, "fsdriver", "local");
- qemu_opt_set(fsdev, "path", host);
- qemu_opt_set(fsdev, "security_model", "none");
-
- ret = qemu_fsdev_add(fsdev);
- if (ret != 0) {
- return false;
- }
-
- qdict = qdict_new();
- qdict_put(qdict, "driver", qstring_from_str("virtio-9p-pci"));
- qdict_put(qdict, "fsdev", qstring_from_str(id));
- qdict_put(qdict, "mount_tag", qstring_from_str(id));
- qdict_put(qdict, "id", qstring_from_str(id));
-
- if (do_device_add(default_mon, qdict, NULL)) {
- QDECREF(qdict);
- return false;
- }
-
- set_hds_attached(id, true);
-
- QDECREF(qdict);
-
- // send mount message to emuld
-
- guest = get_guest_path_by_id((char*)id);
- if (guest == NULL) {
- LOG_SEVERE("guest path is null\n");
- return false;
- }
-
- len = snprintf(emuld_data, sizeof(emuld_data), "%s\n%s\n", id, guest);
- LOG_INFO("send emuld to mount: %s", emuld_data);
- send_msg_to_guest(MSG_TYPE_HDS, MSG_GROUP_HDS, HDS_ACTION_MOUNT, emuld_data, len + 1);
-
- return true;
-}
-
-static bool do_hds_detach(const char * const id)
-{
- QDict *qdict = qdict_new();
- qemu_fsdev_remove(id);
-
- qdict_put(qdict, "id", qstring_from_str(id));
-
- if (qmp_marshal_input_device_del(cur_mon, qdict, NULL)) {
- QDECREF(qdict);
- return false;
- }
-
- QDECREF(qdict);
-
- remove_hds_list(id);
-
- return true;
-}
-
-void do_hotplug(int command, void *opaque, size_t size)
-{
- if (opaque != NULL && size > 0) {
- state->opaque = g_malloc(size);
- memcpy(state->opaque, opaque, size);
- }
- state->command = command;
-
- event_notifier_set(&state->notifier);
-}
-
-static void device_hotplug_handler(EventNotifier *e)
-{
- event_notifier_test_and_clear(e);
-
- switch(state->command) {
- case ATTACH_HOST_KEYBOARD:
- do_host_keyboard_attach();
- break;
- case DETACH_HOST_KEYBOARD:
- do_host_keyboard_detach();
- break;
- case ATTACH_SDCARD:
- do_sdcard_attach(state->opaque);
- break;
- case DETACH_SDCARD:
- do_sdcard_detach(state->opaque);
- break;
- case ATTACH_HDS:
- do_hds_attach(state->opaque);
- break;
- case DETACH_HDS:
- do_hds_detach(state->opaque);
- break;
- default:
- break;
- }
-
- if (state->opaque != NULL) {
- g_free(state->opaque);
- state->opaque = NULL;
- }
-}
-
-static void deinit_maru_device_hotplug(Notifier *notifier, void *data)
-{
- event_notifier_cleanup(&state->notifier);
-
- g_free(state);
-}
-
-static Notifier maru_device_hotplug_exit = { .notify = deinit_maru_device_hotplug };
-
-void init_device_hotplug(void)
-{
- state = g_malloc0(sizeof(struct maru_device_hotplug));
-
- event_notifier_init(&state->notifier, 0);
- event_notifier_set_handler(&state->notifier, device_hotplug_handler);
-
- emulator_add_exit_notifier(&maru_device_hotplug_exit);
-}
-
-bool is_host_keyboard_attached(void)
-{
- return state->host_keyboard_attached;
-}
-
-bool is_sdcard_attached(void)
-{
- //TODO: support checking multi sdcard attached
- return state->sdcard_attached;
-}
+++ /dev/null
-/*
- * Maru device hotplug
- *
- * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#ifndef _MARU_DEVICE_HOTPLUG_H_
-#define _MARU_DEVICE_HOTPLUG_H_
-
-enum command {
- ATTACH_HOST_KEYBOARD,
- DETACH_HOST_KEYBOARD,
- ATTACH_SDCARD,
- DETACH_SDCARD,
- ATTACH_HDS,
- DETACH_HDS,
-};
-
-void init_device_hotplug(void);
-
-void do_hotplug(int command, void *opaque, size_t size);
-
-bool is_host_keyboard_attached(void);
-bool is_sdcard_attached(void);
-
-#endif // _MARU_DEVICE_HOTPLUG_H_
+++ /dev/null
-/*
- * Error message
- *
- * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#ifdef CONFIG_WIN32
-#include <windows.h>
-#else
-#include <execinfo.h>
-#endif
-
-#include "qemu-common.h"
-
-#include "emulator_common.h"
-#include "emulator.h"
-#include "maru_err_table.h"
-
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, backtrace);
-
-/* This table must match the enum definition */
-static char _maru_string_table[][JAVA_MAX_COMMAND_LENGTH] = {
- /* 0 */ "",
- /* 1 */ FAILED_TO_ALLOCATE_MEMORY,
- /* 2 */ FAILED_TO_LOAD_KERNEL CHECK_FILE_VALID,
- /* 3 */ FAILED_TO_LOAD_BIOS CHECK_FILE_VALID,
- /* 4 */ FAILED_TO_INITIAL_SKIN,
- /* 5 */ EMULATOR_HAS_STOPPED,
- /* add here.. */
- ""
-};
-
-
-static int maru_exit_status = MARU_EXIT_NORMAL;
-static char *maru_exit_msg;
-
-#ifdef CONFIG_WIN32
-static LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter;
-#endif
-
-#ifdef CONFIG_LINUX
-static pthread_spinlock_t siglock;
-void maru_sighandler(int sig);
-#endif
-
-char *get_canonical_path(char const *const path)
-{
- if ((int)g_path_is_absolute(path)) {
- return (char *)g_strdup(path);
- }
-
- char *canonical_path;
-
-#ifndef _WIN32
- char *current_dir = g_get_current_dir();
- canonical_path = g_strdup_printf("%s/%s", current_dir, path);
- g_free(current_dir);
-#else
- canonical_path = g_malloc(MAX_PATH);
- GetFullPathName(path, MAX_PATH, canonical_path, NULL);
-#endif
-
- return canonical_path;
-}
-
-void maru_register_exit_msg(int maru_exit_index, char const *format, ...)
-{
- va_list args;
-
- if (maru_exit_index >= MARU_EXIT_NORMAL) {
- fprintf(stderr, "Invalid error message index = %d\n",
- maru_exit_index);
- return;
- }
- if (maru_exit_status != MARU_EXIT_NORMAL) {
- fprintf(stderr, "The error message is already registered = %d\n",
- maru_exit_status);
- return;
- }
-
- maru_exit_status = maru_exit_index;
-
- if (maru_exit_status == MARU_EXIT_HB_TIME_EXPIRED) {
- fprintf(stderr, "Skin client could not connect to Skin server."
- " The time of internal heartbeat has expired.\n");
- }
-
- if (!format) {
- format = "";
- }
-
- va_start(args, format);
- char *additional = g_strdup_vprintf(format, args);
- va_end(args);
- maru_exit_msg = g_strdup_printf("%s%s", _maru_string_table[maru_exit_status],
- additional);
- g_free(additional);
-
- if (strlen(maru_exit_msg) >= JAVA_MAX_COMMAND_LENGTH) {
- maru_exit_msg[JAVA_MAX_COMMAND_LENGTH - 1] = '\0';
- }
-
- fprintf(stdout, "The error message is registered = %d : %s\n",
- maru_exit_status, maru_exit_msg);
-}
-
-/* Print 'backtrace' */
-#ifdef _WIN32
-struct frame_layout {
- void *pNext;
- void *pReturnAddr;
-};
-
-static char *aqua_get_filename_from_path(char *path_buf)
-{
- char *ret_slash;
- char *ret_rslash;
-
- ret_slash = strrchr(path_buf, '/');
- ret_rslash = strrchr(path_buf, '\\');
-
- if (ret_slash || ret_rslash) {
- if (ret_slash > ret_rslash) {
- return ret_slash + 1;
- } else{
- return ret_rslash + 1;
- }
- }
-
- return path_buf;
-}
-
-
-static HMODULE aqua_get_module_handle(DWORD dwAddress)
-{
- MEMORY_BASIC_INFORMATION Buffer;
- return VirtualQuery((LPCVOID) dwAddress, &Buffer, sizeof(Buffer))
- ? (HMODULE) Buffer.AllocationBase : (HMODULE) 0;
-}
-#endif
-
-static void dump_backtrace(void *ptr, int depth)
-{
-#ifdef _WIN32
- int nCount;
- void *pTopFrame;
- struct frame_layout currentFrame;
- struct frame_layout *pCurrentFrame;
-
- char module_buf[1024];
- HMODULE hModule;
-
- PCONTEXT pContext = ptr;
- if (!pContext) {
- __asm__ __volatile__ ("movl %%ebp, %0" : "=m" (pTopFrame));
- } else {
- pTopFrame = (void *)((PCONTEXT)pContext)->Ebp;
- }
-
- if (pTopFrame == NULL) {
- INFO("ebp is null, skip this for now\n");
- return ;
- }
-
- nCount = 0;
- currentFrame.pNext = ((struct frame_layout *)pTopFrame)->pNext;
- currentFrame.pReturnAddr = ((struct frame_layout *)pTopFrame)->pReturnAddr;
- pCurrentFrame = (struct frame_layout *)pTopFrame;
-
- ERR("\nBacktrace Dump Start :\n");
- if (pContext) {
- memset(module_buf, 0, sizeof(module_buf));
- hModule = aqua_get_module_handle((DWORD)((PCONTEXT)pContext)->Eip);
- if (hModule) {
- if (!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))) {
- memset(module_buf, 0, sizeof(module_buf));
- }
- }
- ERR("[%02d]Addr = 0x%p : %s\n", nCount, ((PCONTEXT)pContext)->Eip, aqua_get_filename_from_path(module_buf));
- nCount++;
- }
-
- while (1) {
- if (((void *)pCurrentFrame < pTopFrame)
- || ((void *)pCurrentFrame >= (void *)0xC0000000)) {
- break;
- }
-
- memset(module_buf, 0, sizeof(module_buf));
- hModule = aqua_get_module_handle((DWORD)currentFrame.pReturnAddr);
- if (hModule) {
- if (!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))) {
- memset(module_buf, 0, sizeof(module_buf));
- }
- }
- ERR("[%02d]Addr = 0x%p : %s\n", nCount, currentFrame.pReturnAddr, aqua_get_filename_from_path(module_buf));
-
- if (!ReadProcessMemory(GetCurrentProcess(), currentFrame.pNext,
- (void *)¤tFrame, sizeof(struct frame_layout), NULL)) {
- break;
- }
- pCurrentFrame = (struct frame_layout *)pCurrentFrame->pNext;
-
- if (depth) {
- if (!--depth) {
- break;
- }
- }
- nCount++;
- }
-#else
- void *trace[1024];
- int ndepth = backtrace(trace, 1024);
- ERR("Backtrace depth is %d.\n", ndepth);
-
- backtrace_symbols_fd(trace, ndepth, fileno(stderr));
-#endif
-}
-
-void handle_error_at_exit(void)
-{
-
- if (maru_exit_status != MARU_EXIT_NORMAL || maru_exit_msg) {
- start_simple_client(maru_exit_msg);
- }
- g_free(maru_exit_msg);
-
- // dump backtrace log no matter what
- INFO("This is not a error.\n");
- INFO("Stack backtrace for tracing...\n");
- dump_backtrace(NULL, 0);
-}
-
-#ifdef CONFIG_WIN32
-static WINAPI LONG maru_unhandled_exception_filter(LPEXCEPTION_POINTERS pExceptionInfo){
- char module_buf[1024];
-
- // print system information again
- print_system_info();
-
- DWORD dwException = pExceptionInfo->ExceptionRecord->ExceptionCode;
- ERR("%d\n ", (int)dwException);
-
- PEXCEPTION_RECORD pExceptionRecord;
- HMODULE hModule;
- PCONTEXT pContext;
-
- pExceptionRecord = pExceptionInfo->ExceptionRecord;
-
- memset(module_buf, 0, sizeof(module_buf));
- hModule = aqua_get_module_handle((DWORD)pExceptionRecord->ExceptionAddress);
- if(hModule){
- if(!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))){
- memset(module_buf, 0, sizeof(module_buf));
- }
- }
-
- ERR("Exception [%X] occured at %s:0x%08x\n",
- pExceptionRecord->ExceptionCode,
- aqua_get_filename_from_path(module_buf),
- pExceptionRecord->ExceptionAddress
- );
-
- pContext = pExceptionInfo->ContextRecord;
- dump_backtrace(pContext, 0);
- _exit(0);
- //return EXCEPTION_CONTINUE_SEARCH;
-}
-#endif
-
-#ifdef CONFIG_LINUX
-void maru_sighandler(int sig)
-{
- // print system information again
- print_system_info();
-
- pthread_spin_lock(&siglock);
- ERR("Got signal %d\n", sig);
- dump_backtrace(NULL, 0);
- pthread_spin_unlock(&siglock);
- _exit(0);
-}
-#endif
-
-
-#ifndef CONFIG_DARWIN
-void register_exception_handler(void)
-{
- #ifdef CONFIG_WIN32
- prevExceptionFilter = SetUnhandledExceptionFilter(maru_unhandled_exception_filter);
- #else // LINUX
- void *trace[1];
- struct sigaction sa;
-
- // make dummy call to explicitly load glibc library
- backtrace(trace, 1);
-
- pthread_spin_init(&siglock,0);
- sa.sa_handler = (void*) maru_sighandler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART;
- sigaction(SIGSEGV, &sa, NULL);
- sigaction(SIGBUS, &sa, NULL);
- sigaction(SIGILL, &sa, NULL);
- sigaction(SIGFPE, &sa, NULL);
- sigaction(SIGABRT, &sa, NULL);
- // main thread only
- sigaction(SIGTERM, &sa, NULL);
- sigaction(SIGINT, &sa, NULL);
- #endif
-}
-#else // CONFIG_DARWIN
-void register_exception_handler(void)
-{
- // TODO: Exception handling on darwin
-}
-#endif
+++ /dev/null
-/*
- * Error message
- *
- * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#ifndef __EMUL_ERR_TABLE_H__
-#define __EMUL_ERR_TABLE_H__
-
-#include "tizen/src/skin/maruskin_client.h"
-
-/* TODO: define macro for fair of definition */
-/* This enum must match the table definition */
-enum {
- /* 0 */ MARU_EXIT_UNKNOWN = 0,
- /* 1 */ MARU_EXIT_MEMORY_EXCEPTION,
- /* 2 */ MARU_EXIT_KERNEL_FILE_EXCEPTION,
- /* 3 */ MARU_EXIT_BIOS_FILE_EXCEPTION,
- /* 4 */ MARU_EXIT_SKIN_SERVER_FAILED,
- /* 5 */ MARU_EXIT_HB_TIME_EXPIRED,
- /* add here.. */
- MARU_EXIT_NORMAL
-};
-
-
-char *get_canonical_path(char const *const path);
-void maru_register_exit_msg(int maru_exit_status, char const *format, ...);
-void register_exception_handler(void);
-void handle_error_at_exit(void);
-
-#endif /* __EMUL_ERR_TABLE_H__ */
+++ /dev/null
-/*
- * The strings for the emulator messages
- *
- * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * Sooyoung Ha <yoosah.ha@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * Sangho Park <sangho.p@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#ifndef __MARU_UTIL_STRINGS_H__
-#define __MARU_UTIL_STRINGS_H__
-
-#define FAILED_TO_ALLOCATE_MEMORY "Failed to allocate memory in qemu."
-#define FAILED_TO_LOAD_KERNEL "Failed to load a kernel file the following path."
-#define FAILED_TO_LOAD_BIOS "Failed to load a bios file in bios path that mentioned on document."
-#define FAILED_TO_LOAD_DISK "Failed to load disk file from the following path."
-#define CHECK_FILE_VALID " Check if the file is corrupted or missing.\n\n"
-#define FAILED_TO_INITIAL_SKIN "Skin process cannot be initialized. Skin server is not ready."
-#define FAILED_TO_INSTALL_EXTRAPACKAGE_1 "Extra package installation is failed.\n"
-#define FAILED_TO_INSTALL_EXTRAPACKAGE_2 " must be installed MANUALLY!"
-#define EMULATOR_HAS_STOPPED "Emulator has stopped working.\nA problem caused the program to stop working correctly."
-#define NO_ACCELERATOR_FOUND "No accelerator found."
-
-#endif /* __MARU_UTIL_STRINGS_H__ */
#include "emulator.h"
#include "emul_state.h"
#include "debug_ch.h"
-#include "maru_err_table.h"
#include "sdb.h"
#include "emulator_options.h"
*/
#include <png.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
+#include <linux/version.h>
+#include <sys/utsname.h>
+#include <sys/sysinfo.h>
+
+#include "qemu/error-report.h"
+
#include "osutil.h"
#include "emulator.h"
#include "emul_state.h"
-#include "debug_ch.h"
-#include "maru_err_table.h"
#include "sdb.h"
#include "emulator_options.h"
#error
#endif
-#include <string.h>
-#include <unistd.h>
-#include <sys/shm.h>
-#include <sys/ipc.h>
-#include <linux/version.h>
-#include <sys/utsname.h>
-#include <sys/sysinfo.h>
-
+#include "debug_ch.h"
MULTI_DEBUG_CHANNEL(emulator, osutil);
static int g_shmid;
val = shmctl(shm_id, IPC_STAT, &shm_info);
if (val != -1) {
- INFO("count of process that use shared memory : %d\n",
+ INFO("count of process that use shared memory: %d\n",
shm_info.shm_nattch);
if ((shm_info.shm_nattch > 0) &&
g_strcmp0(get_drive_image_file(), (char *)shm_addr) == 0) {
continue;
}
shmdt(shm_addr);
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- "Can not execute this VM.\n"
- "The same name is running now.");
- exit(0);
+ error_report("Can not execute this VM. "
+ "The same name is running now.");
+ exit(1);
} else {
shmdt(shm_addr);
}
#include "osutil.h"
#include "emulator.h"
#include "emul_state.h"
-#include "maru_err_table.h"
#include "sdb.h"
#include "emulator_options.h"
#endif
#include <windows.h>
+#include "qemu/error-report.h"
#include "debug_ch.h"
MULTI_DEBUG_CHANNEL (emulator, osutil);
}
if (strcmp(pBuf, get_drive_image_file()) == 0) {
- maru_register_exit_msg(MARU_EXIT_UNKNOWN,
- "Can not execute this VM.\n"
+ error_report("Can not execute this VM. "
"The same name is running now.");
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
#include <stdio.h>
#include "monitor/monitor.h"
+#ifdef CONFIG_MARU
+static QLIST_HEAD(, ErrorReporter) error_reporters =
+ QLIST_HEAD_INITIALIZER(error_reporters);
+
+void add_error_reporter(ErrorReporter *new_reporter)
+{
+ QLIST_INSERT_HEAD(&error_reporters, new_reporter, node);
+}
+
+static void report_to_clients(const char *fmt, va_list ap)
+{
+ ErrorReporter *reporter;
+ QLIST_FOREACH(reporter, &error_reporters, node) {
+ if (reporter->report) {
+ (*(reporter->report))(fmt, ap);
+ }
+ }
+}
+#endif
+
/*
* Print to current monitor if we have one, else to stderr.
* TODO should return int, so callers can calculate width, but that
monitor_vprintf(cur_mon, fmt, ap);
} else {
vfprintf(stderr, fmt, ap);
+#ifdef CONFIG_MARU
+ report_to_clients(fmt, ap);
+#endif
}
}
#ifdef CONFIG_MARU
#include "tizen/src/emulator.h"
-#include "tizen/src/util/maru_err_table.h"
#include "tizen/src/emul_state.h"
#include "tizen/src/display/maru_display.h"
#include "tizen/src/skin/maruskin_operation.h"
display = DT_MARU_QT_ONSCREEN;
}
# else
- fprintf(stderr, "maru_qt is disabled\n");
+ error_report("maru_qt is disabled.\n");
- maru_register_exit_msg(MARU_EXIT_UNKNOWN, "maru_qt is disabled");
exit(1);
# endif
#endif /* CONFIG_MARU */
for(;;) {
if (!popt->name) {
error_report("invalid option");
-#ifdef CONFIG_MARU
- maru_register_exit_msg(MARU_EXIT_UNKNOWN, "invalid option.");
-#endif
exit(1);
}
if (!strcmp(popt->name, r + 1))
if (popt->flags & HAS_ARG) {
if (optind >= argc) {
error_report("requires an argument");
-#ifdef CONFIG_MARU
- maru_register_exit_msg(MARU_EXIT_UNKNOWN, "requires an argument.");
-#endif
exit(1);
}
optarg = argv[optind++];