emulator: some error reporting routine is refactored 25/23925/6
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Fri, 4 Jul 2014 10:08:42 +0000 (19:08 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Sun, 6 Jul 2014 05:43:39 +0000 (14:43 +0900)
maru_register_exit_msg() can accept variable arguments.
Remove maru_convert_path(), Add get_canonical_path().

Change-Id: I7975510cfb34a0bbb633df5a74ffce21922c0c92
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
Signed-off-by: Sooyoung Ha <yoosah.ha@samsung.com>
15 files changed:
blockdev.c
hw/9pfs/virtio-9p-device.c
hw/i386/pc.c
hw/i386/pc_sysfw.c
tizen/src/Makefile.objs
tizen/src/emulator.c
tizen/src/emulator_legacy.c
tizen/src/maru_err_table.c [deleted file]
tizen/src/maru_err_table.h [deleted file]
tizen/src/skin/maruskin_client.c
tizen/src/skin/maruskin_server.c
tizen/src/util/Makefile.objs
tizen/src/util/maru_err_table.c [new file with mode: 0644]
tizen/src/util/maru_err_table.h [new file with mode: 0644]
vl.c

index 0144f041139454e5738cde0e3fb8f78881c3400f..f8c63c902a72ee78a7c6a38d287faff5ab46ec43 100644 (file)
 #include "trace.h"
 #include "sysemu/arch_init.h"
 
+#ifdef CONFIG_MARU
+#include "tizen/src/util/maru_err_table.h"
+#endif
+
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
 
 static const char *const if_name[IF_COUNT] = {
@@ -288,11 +292,6 @@ static int parse_block_error_action(const char *buf, bool is_read, Error **errp)
     }
 }
 
-#ifdef CONFIG_MARU
-extern int start_simple_client(char* msg);
-extern char* maru_convert_path(char* msg, const char *path);
-#endif
-
 static bool check_throttle_config(ThrottleConfig *cfg, Error **errp)
 {
     if (throttle_conflicting(cfg)) {
@@ -513,14 +512,13 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
 
     if (ret < 0) {
 #ifdef CONFIG_MARU
-        const char _msg[] = "Failed to load disk file from the following path. Check if the file is corrupted or missing.\n\n";
-        char* err_msg = NULL;
+        char *path = get_canonical_path(file);
+        char *msg = g_strdup_printf("Failed to load disk file from the following path. Check if the file is corrupted or missing.\n\n%s", path);
 
-        err_msg = maru_convert_path((char*)_msg, file);
-        if (err_msg) {
-            start_simple_client(err_msg);
-            g_free(err_msg);
-        }
+        start_simple_client(msg);
+
+        g_free(path);
+        g_free(msg);
 #endif
 
         error_setg(errp, "could not open disk image %s: %s",
index 24ef87494481e4fdb8da84f72126bf7e9e933886..519b6e3c83ee8bda1c36c642b6ee9abb5ed416df 100644 (file)
@@ -21,8 +21,7 @@
 #include "virtio-9p-coth.h"
 
 #ifdef CONFIG_MARU
-#include "../tizen/src/maru_err_table.h"
-// extern char* maru_convert_path(char* msg, const char *path);
+#include "tizen/src/util/maru_err_table.h"
 #endif
 
 static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
@@ -108,13 +107,11 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
         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
-        const char _msg[] = "Failed to find the file sharing path. Check if the path is correct or not.\n\n";
-        char* err_msg = NULL;
-        err_msg = maru_convert_path((char*)_msg, s->ctx.fs_root);
-               maru_register_exit_msg(MARU_EXIT_UNKNOWN, err_msg);
-        if (err_msg) {
-            g_free(err_msg);
-        }
+        char *path = get_canonical_path(s->ctx.fs_root);
+        maru_register_exit_msg(MARU_EXIT_UNKNOWN, "Failed to find the file sharing path."
+                    " Check if the path is correct or not.\n\n%s", path);
+
+        g_free(path);
 #endif
         goto out;
     }
index f48baeea8e1797f00bd9d356da4c9c4e6a95d436..612bde2f2cdeb641651b73d414117c2c260fcd81 100644 (file)
@@ -60,7 +60,7 @@
 #include "acpi-build.h"
 
 #ifdef CONFIG_MARU
-#include "../../tizen/src/maru_err_table.h"
+#include "tizen/src/util/maru_err_table.h"
 #endif
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -734,13 +734,10 @@ static void load_linux(FWCfgState *fw_cfg,
                 kernel_filename, strerror(errno));
 
 #ifdef CONFIG_MARU
-        char *error_msg = NULL;
+        char *path = get_canonical_path(kernel_filename);
+        maru_register_exit_msg(MARU_EXIT_KERNEL_FILE_EXCEPTION, path);
 
-        error_msg = maru_convert_path(error_msg, kernel_filename);
-        maru_register_exit_msg(MARU_EXIT_KERNEL_FILE_EXCEPTION, error_msg);
-        if (error_msg) {
-            g_free(error_msg);
-        }
+        g_free(path);
 #endif
         exit(1);
     }
index 7819b216016f463a892b4916e50fc53e281a20d2..61e54ddc1013a566e0bd4aaebd182c36e7275833 100644 (file)
@@ -35,7 +35,7 @@
 #include "sysemu/kvm.h"
 
 #ifdef CONFIG_MARU
-#include "../../tizen/src/maru_err_table.h"
+#include "tizen/src/util/maru_err_table.h"
 #endif
 
 #define BIOS_FILENAME "bios.bin"
index 44bddfa55b504e6e888b77b9f94503062b31298f..ba3ff7859a2d563a09b6575426a2987c21971cbe 100644 (file)
@@ -3,14 +3,11 @@
 QEMU_CFLAGS += -I$(SRC_PATH)/tizen/src
 
 # emulator base
-obj-y += emulator.o emulator_legacy.o emulator_options.o emul_state.o maru_err_table.o
+obj-y += emulator.o emulator_legacy.o emulator_options.o emul_state.o
 
 # utils
 obj-y += util/
 
-# mloop event
-#obj-y += mloop_event.o
-
 # maru display
 obj-y += display/
 
index a659db802d5b2ae8ef39a745f46ed515e90823bb..2243b3ef4785fd0c12fd3e3489aaa96f024b6ebb 100644 (file)
@@ -40,7 +40,7 @@
 #include "emulator_options.h"
 #include "util/sdb_noti_server.h"
 #include "util/check_gl.h"
-#include "maru_err_table.h"
+#include "util/maru_err_table.h"
 #include "util/osutil.h"
 #include "util/sdb.h"
 #include "skin/maruskin_server.h"
index 85fa9d55e428f2332dab4cb9f1b16eef3b21f5cd..47b87de6b24479c33d38a842d8de1e53c95a1a24 100644 (file)
@@ -41,7 +41,7 @@
 #include "guest_debug.h"
 #include "hw/virtio/maru_virtio_touchscreen.h"
 #include "util/check_gl.h"
-#include "maru_err_table.h"
+#include "util/maru_err_table.h"
 #include "display/maru_display.h"
 #include "util/osutil.h"
 #include "util/sdb.h"
diff --git a/tizen/src/maru_err_table.c b/tizen/src/maru_err_table.c
deleted file mode 100644 (file)
index 01f6dd1..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * 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 "qemu-common.h"
-#include "maru_common.h"
-#include "maru_err_table.h"
-#include "debug_ch.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#ifdef CONFIG_WIN32
-#include <windows.h>
-#else
-#include <execinfo.h>
-#endif
-
-
-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 in qemu.",
-    /* 2 */ "Failed to load a kernel file the following path.\
-Check if the file is corrupted or missing.\n\n",
-    /* 3 */ "Failed to load a bios file in bios path that mentioned on document.\
-Check if the file is corrupted or missing.\n\n",
-    /* 4 */ "Skin process cannot be initialized. Skin server is not ready.",
-    /* 5 */ "Emulator has stopped working.\n\
-A problem caused the program to stop working correctly.",
-    /* add here.. */
-    ""
-};
-
-
-static int maru_exit_status = MARU_EXIT_NORMAL;
-static char maru_exit_msg[JAVA_MAX_COMMAND_LENGTH] = { 0, };
-
-#ifdef CONFIG_WIN32
-static LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter;
-#endif
-
-#ifdef CONFIG_LINUX
-static pthread_spinlock_t siglock;
-void maru_sighandler(int sig);
-#endif
-
-
-void maru_register_exit_msg(int maru_exit_index, char const *const additional_msg)
-{
-    int len = 0;
-
-    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_UNKNOWN) {
-        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 (additional_msg != NULL) {
-            len = strlen(_maru_string_table[maru_exit_status])
-                    + strlen(additional_msg) + 1;
-            if (len > JAVA_MAX_COMMAND_LENGTH) {
-                len = JAVA_MAX_COMMAND_LENGTH;
-            }
-
-            snprintf(maru_exit_msg, len, "%s%s",
-                    _maru_string_table[maru_exit_status], additional_msg);
-        } else {
-            len = strlen(_maru_string_table[maru_exit_status]) + 1;
-            if (len > JAVA_MAX_COMMAND_LENGTH) {
-                len = JAVA_MAX_COMMAND_LENGTH;
-            }
-
-            snprintf(maru_exit_msg, len,
-                    "%s", _maru_string_table[maru_exit_status]);
-        }
-    } else if (additional_msg != NULL) { /* MARU_EXIT_UNKNOWN */
-        len = strlen(additional_msg);
-        if (len >= JAVA_MAX_COMMAND_LENGTH) {
-            len = JAVA_MAX_COMMAND_LENGTH - 1;
-        }
-
-        pstrcpy(maru_exit_msg, len + 1, additional_msg);
-        maru_exit_msg[len] = '\0';
-    }
-
-    fprintf(stdout, "The error message is registered = %d : %s\n",
-        maru_exit_status, maru_exit_msg);
-}
-
-void maru_atexit(void)
-{
-
-    if (maru_exit_status != MARU_EXIT_NORMAL || strlen(maru_exit_msg) != 0) {
-        start_simple_client(maru_exit_msg);
-    }
-    INFO("normal exit called\n");
-    // dump backtrace log no matter what
-    maru_dump_backtrace(NULL, 0);
-}
-
-char *maru_convert_path(char *msg, const char *path)
-{
-    char *current_path = NULL;
-    char *err_msg = NULL;
-#ifdef _WIN32
-    char *dos_err_msg = NULL;
-#endif
-    int total_len = 0;
-    int msg_len = 0;
-    int cur_path_len = 0;
-    int path_len = 0;
-    int res = -1;
-
-    if (!path) {
-        path = "NULL";
-        res = 1;
-    }
-    else {
-        res = (int)g_path_is_absolute(path);
-    }
-    path_len = (strlen(path) + 1);
-    if (msg) {
-        msg_len = strlen(msg) + 1;
-    }
-
-    if (!res) {
-        current_path = (char *)g_get_current_dir();
-        cur_path_len = strlen(current_path) + strlen("/") + 1;
-        total_len += cur_path_len;
-    }
-    total_len += (path_len + msg_len);
-
-    err_msg = g_malloc0(total_len * sizeof(char));
-    if (!err_msg) {
-        fprintf(stderr, "failed to allocate a buffer for an error massage\n");
-        g_free(current_path);
-        return NULL;
-    }
-
-    if (msg) {
-        snprintf(err_msg, msg_len, "%s", msg);
-        total_len = msg_len - 1;
-    } else {
-        total_len = 0;
-    }
-
-    if (!res) {
-        snprintf(err_msg + total_len, cur_path_len, "%s%s", current_path, "/");
-        total_len += (cur_path_len - 1);
-    }
-    snprintf(err_msg + total_len, path_len, "%s", path);
-
-#ifdef _WIN32
-    {
-        int i;
-
-        dos_err_msg = g_strdup(err_msg);
-        if (!dos_err_msg) {
-            fprintf(stderr,
-                "failed to duplicate an error message from %p\n", err_msg);
-            g_free(current_path);
-            g_free(err_msg);
-            return NULL;
-        }
-
-        for (i = (total_len - 1); dos_err_msg[i]; i++) {
-            if (dos_err_msg[i] == '/') {
-                dos_err_msg[i] = '\\';
-            }
-        }
-        pstrcpy(err_msg, strlen(dos_err_msg) + 1, dos_err_msg);
-        g_free(dos_err_msg);
-    }
-#endif
-    g_free(current_path);
-
-    return err_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
-
-void maru_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 *)&currentFrame, 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
-}
-
-#ifdef CONFIG_WIN32
-static LONG maru_unhandled_exception_filter(PEXCEPTION_POINTERS pExceptionInfo){
-    char module_buf[1024];
-    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;
-    maru_dump_backtrace(pContext, 0);
-    _exit(0);
-    //return EXCEPTION_CONTINUE_SEARCH;
-}
-#endif
-
-#ifdef CONFIG_LINUX
-void maru_sighandler(int sig)
-{
-    pthread_spin_lock(&siglock);
-    ERR("Got signal %d\n", sig);
-    maru_dump_backtrace(NULL, 0);
-    pthread_spin_unlock(&siglock);
-    _exit(0);
-}
-#endif
-
-
-#ifndef CONFIG_DARWIN
-void maru_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
-}
-#endif
diff --git a/tizen/src/maru_err_table.h b/tizen/src/maru_err_table.h
deleted file mode 100644 (file)
index 8ad2bac..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 "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
-};
-
-
-void maru_register_exit_msg(int maru_exit_status, char const *const additional_msg);
-void maru_atexit(void);
-char *maru_convert_path(char *msg, const char *path);
-void maru_dump_backtrace(void *ptr, int depth);
-
-void maru_register_exception_handler(void);
-#endif /* __EMUL_ERR_TABLE_H__ */
index 243037a0a6e4c7d1ed02f377369139e1b28efa30..0c6fc22b22347dbfdef326aacf3a02a2e3ce9b82 100644 (file)
@@ -46,7 +46,7 @@
 
 #ifdef CONFIG_WIN32
 #include <windows.h>
-#include "maru_err_table.h"
+#include "util/maru_err_table.h"
 #endif
 
 MULTI_DEBUG_CHANNEL(qemu, skin_client);
index 0264db0e522bd3a401dba562ceaa125511dc1d81..5c94ada3c813e103f4bf534a32566f8e9f2c1a2d 100644 (file)
@@ -34,7 +34,7 @@
 #include "maruskin_server.h"
 #include "maruskin_operation.h"
 #include "display/maru_display.h"
-#include "maru_err_table.h"
+#include "util/maru_err_table.h"
 #include "ecs/ecs.h"
 #include "emul_state.h"
 
index 2234ec0adeff3a31e3dd60b1d6618ded4289783d..762e715f6e0b77682462eba29415925b6e934896 100644 (file)
@@ -20,4 +20,7 @@ obj-$(CONFIG_DARWIN) += check_gl_cgl.o
 # hotplug
 obj-y += maru_device_hotplug.o
 
+# error table
+obj-y += maru_err_table.o
+
 $(obj)/osutil.o: QEMU_CFLAGS += $(CURL_CFLAGS)
diff --git a/tizen/src/util/maru_err_table.c b/tizen/src/util/maru_err_table.c
new file mode 100644 (file)
index 0000000..62c834d
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * 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 "qemu-common.h"
+#include "maru_common.h"
+#include "maru_err_table.h"
+#include "debug_ch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#ifdef CONFIG_WIN32
+#include <windows.h>
+#else
+#include <execinfo.h>
+#endif
+
+
+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 in qemu.",
+    /* 2 */ "Failed to load a kernel file the following path."
+            " Check if the file is corrupted or missing.\n\n",
+    /* 3 */ "Failed to load a bios file in bios path that mentioned on document."
+            " Check if the file is corrupted or missing.\n\n",
+    /* 4 */ "Skin process cannot be initialized. Skin server is not ready.",
+    /* 5 */ "Emulator has stopped working.\n"
+            "A problem caused the program to stop working correctly.",
+    /* 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 *)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);
+}
+
+void maru_atexit(void)
+{
+
+    if (maru_exit_status != MARU_EXIT_NORMAL || maru_exit_msg) {
+        start_simple_client(maru_exit_msg);
+    }
+    g_free(maru_exit_msg);
+
+    INFO("normal exit called\n");
+    // dump backtrace log no matter what
+    maru_dump_backtrace(NULL, 0);
+}
+
+/* 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
+
+void maru_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 *)&currentFrame, 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
+}
+
+#ifdef CONFIG_WIN32
+static LONG maru_unhandled_exception_filter(PEXCEPTION_POINTERS pExceptionInfo){
+    char module_buf[1024];
+    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;
+    maru_dump_backtrace(pContext, 0);
+    _exit(0);
+    //return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
+#ifdef CONFIG_LINUX
+void maru_sighandler(int sig)
+{
+    pthread_spin_lock(&siglock);
+    ERR("Got signal %d\n", sig);
+    maru_dump_backtrace(NULL, 0);
+    pthread_spin_unlock(&siglock);
+    _exit(0);
+}
+#endif
+
+
+#ifndef CONFIG_DARWIN
+void maru_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
+}
+#endif
diff --git a/tizen/src/util/maru_err_table.h b/tizen/src/util/maru_err_table.h
new file mode 100644 (file)
index 0000000..f27dc91
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 maru_atexit(void);
+
+void maru_dump_backtrace(void *ptr, int depth);
+
+void maru_register_exception_handler(void);
+#endif /* __EMUL_ERR_TABLE_H__ */
diff --git a/vl.c b/vl.c
index 7c0d432da133878cd3bec3697d52ca96ac20db73..3cf5854d2b5abafed41193b5f0e49a76795b07ac 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -132,7 +132,7 @@ int qemu_main(int argc, char **argv, char **envp);
 #ifdef CONFIG_MARU
 #include "tizen/src/maru_common.h"
 #include "tizen/src/emulator.h"
-#include "tizen/src/maru_err_table.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"