diff options
author | Jan Kotas <jkotas@microsoft.com> | 2016-03-04 09:36:05 -0800 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2016-03-04 09:36:05 -0800 |
commit | 41d393fc361359b0143dc5ae62ae3a255e052d78 (patch) | |
tree | a6ba1e0ac5f7219ebf1bbf45128bd10efdc20633 | |
parent | f80c2fbb673dce9b049e4d02d0b8eadf998e9ea2 (diff) | |
parent | 35b5df6888f1574e6ef9313c6bc8522d1817573d (diff) | |
download | coreclr-41d393fc361359b0143dc5ae62ae3a255e052d78.tar.gz coreclr-41d393fc361359b0143dc5ae62ae3a255e052d78.tar.bz2 coreclr-41d393fc361359b0143dc5ae62ae3a255e052d78.zip |
Merge pull request #3502 from myungjoo/fix/3462_arm_linux_stack
ARM-Linux Fixes (Issue #3462)
-rw-r--r-- | src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp | 14 | ||||
-rw-r--r-- | src/pal/src/config.h.in | 2 | ||||
-rw-r--r-- | src/pal/src/configure.cmake | 24 | ||||
-rw-r--r-- | src/pal/src/exception/seh-unwind.cpp | 39 |
4 files changed, 64 insertions, 15 deletions
diff --git a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp index 1125dfb819..8d32a7d390 100644 --- a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp +++ b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp @@ -268,6 +268,20 @@ int ExecuteManagedAssembly( // Indicates failure int exitCode = -1; +#ifdef _ARM_ + // LIBUNWIND-ARM has a bug of side effect with DWARF mode + // Ref: https://github.com/dotnet/coreclr/issues/3462 + // This is why Fedora is disabling it by default as well. + // Assuming that we cannot enforce the user to set + // environmental variables for third party packages, + // we set the environmental variable of libunwind locally here. + + // Without this, any exception handling will fail, so let's do this + // as early as possible. + // 0x1: DWARF / 0x2: FRAME / 0x4: EXIDX + putenv("UNW_ARM_UNWIND_METHOD=6"); +#endif // _ARM_ + std::string coreClrDllPath(clrFilesAbsolutePath); coreClrDllPath.append("/"); coreClrDllPath.append(coreClrDll); diff --git a/src/pal/src/config.h.in b/src/pal/src/config.h.in index 68cb81ba67..784383f8dd 100644 --- a/src/pal/src/config.h.in +++ b/src/pal/src/config.h.in @@ -53,6 +53,8 @@ #cmakedefine01 HAS_SYSV_SEMAPHORES #cmakedefine01 HAS_PTHREAD_MUTEXES #cmakedefine01 HAVE_TTRACE +#cmakedefine HAVE_UNW_GET_SAVE_LOC +#cmakedefine HAVE_UNW_GET_ACCESSORS #cmakedefine01 HAVE_STAT_TIMESPEC #cmakedefine01 HAVE_STAT_NSEC diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake index be6114d48c..daa99622fe 100644 --- a/src/pal/src/configure.cmake +++ b/src/pal/src/configure.cmake @@ -73,8 +73,28 @@ check_function_exists(directio HAVE_DIRECTIO) check_function_exists(semget HAS_SYSV_SEMAPHORES) check_function_exists(pthread_mutex_init HAS_PTHREAD_MUTEXES) check_function_exists(ttrace HAVE_TTRACE) -check_function_exists(unw_get_save_loc HAVE_UNW_GET_SAVE_LOC) -check_function_exists(unw_get_accessors HAVE_UNW_GET_ACCESSORS) +set(CMAKE_REQUIRED_LIBRARIES unwind unwind-generic) +check_cxx_source_compiles(" +#include <libunwind.h> + +int main(int argc, char **argv) { + unw_cursor_t cursor; + unw_save_loc_t saveLoc; + int reg = UNW_REG_IP; + unw_get_save_loc(&cursor, reg, &saveLoc); + + return 0; +}" HAVE_UNW_GET_SAVE_LOC) +check_cxx_source_compiles(" +#include <libunwind.h> + +int main(int argc, char **argv) { + unw_addr_space_t as; + unw_get_accessors(as); + + return 0; +}" HAVE_UNW_GET_ACCESSORS) +set(CMAKE_REQUIRED_LIBRARIES) check_struct_has_member ("struct stat" st_atimespec "sys/types.h;sys/stat.h" HAVE_STAT_TIMESPEC) check_struct_has_member ("struct stat" st_atimensec "sys/types.h;sys/stat.h" HAVE_STAT_NSEC) diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp index 5d3b353494..333544379a 100644 --- a/src/pal/src/exception/seh-unwind.cpp +++ b/src/pal/src/exception/seh-unwind.cpp @@ -97,17 +97,29 @@ static void WinContextToUnwindCursor(CONTEXT *winContext, unw_cursor_t *cursor) unw_set_reg(cursor, UNW_X86_64_R14, winContext->R14); unw_set_reg(cursor, UNW_X86_64_R15, winContext->R15); #elif defined(_ARM_) - unw_set_reg(cursor, UNW_ARM_R13, winContext->Sp); - unw_set_reg(cursor, UNW_ARM_R14, winContext->Lr); - unw_set_reg(cursor, UNW_ARM_R15, winContext->Pc); - unw_set_reg(cursor, UNW_ARM_R4, winContext->R4); - unw_set_reg(cursor, UNW_ARM_R5, winContext->R5); - unw_set_reg(cursor, UNW_ARM_R6, winContext->R6); - unw_set_reg(cursor, UNW_ARM_R7, winContext->R7); - unw_set_reg(cursor, UNW_ARM_R8, winContext->R8); - unw_set_reg(cursor, UNW_ARM_R9, winContext->R9); - unw_set_reg(cursor, UNW_ARM_R10, winContext->R10); - unw_set_reg(cursor, UNW_ARM_R11, winContext->R11); + // Assuming that unw_set_reg() on cursor will point the cursor to the + // supposed stack frame is dangerous for libunwind-arm in Linux. + // It is because libunwind's unw_cursor_t has other data structure + // initialized by unw_init_local(), which are not updated by + // unw_set_reg(). + unw_context_t context; + context.regs[0] = 0; + context.regs[1] = 0; + context.regs[2] = 0; + context.regs[3] = 0; + context.regs[4] = winContext->R4; + context.regs[5] = winContext->R5; + context.regs[6] = winContext->R6; + context.regs[7] = winContext->R7; + context.regs[8] = winContext->R8; + context.regs[9] = winContext->R9; + context.regs[10] = winContext->R10; + context.regs[11] = winContext->R11; + context.regs[12] = 0; + context.regs[13] = winContext->Sp; + context.regs[14] = winContext->Lr; + context.regs[15] = winContext->Pc; + unw_init_local(cursor, &context); #endif } #endif @@ -124,9 +136,10 @@ static void UnwindContextToWinContext(unw_cursor_t *cursor, CONTEXT *winContext) unw_get_reg(cursor, UNW_X86_64_R14, (unw_word_t *) &winContext->R14); unw_get_reg(cursor, UNW_X86_64_R15, (unw_word_t *) &winContext->R15); #elif defined(_ARM_) - unw_get_reg(cursor, UNW_ARM_R13, (unw_word_t *) &winContext->Sp); + unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp); + unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc); + winContext->Pc &= ~0x1; unw_get_reg(cursor, UNW_ARM_R14, (unw_word_t *) &winContext->Lr); - unw_get_reg(cursor, UNW_ARM_R15, (unw_word_t *) &winContext->Pc); unw_get_reg(cursor, UNW_ARM_R4, (unw_word_t *) &winContext->R4); unw_get_reg(cursor, UNW_ARM_R5, (unw_word_t *) &winContext->R5); unw_get_reg(cursor, UNW_ARM_R6, (unw_word_t *) &winContext->R6); |