Summary: | vex x86->IR: unhandled instruction bytes: 0x36 0x8A 0x18 0x22 (and many other examples) | ||
---|---|---|---|
Product: | [Developer tools] valgrind | Reporter: | Richard Nelson <cowboy+bugzilla> |
Component: | vex | Assignee: | Julian Seward <jseward> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | austinenglish, sebastian |
Priority: | NOR | ||
Version: | 3.10 SVN | ||
Target Milestone: | --- | ||
Platform: | Debian unstable | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: |
[PATCH 1/2] Initialize x86 system GDT on first use.
[PATCH 2/2] VEX: Recognize the SS segment prefix on x86. |
Description
Richard Nelson
2015-02-13 23:22:39 UTC
The current development version of Wine is also affected by this problem, see: http://source.winehq.org/git/wine.git/blob/HEAD:/tools/winebuild/relay.c#l873 Not sure about the app for which the bug was originally opened, but at least in this case it would also be fine to completely ignore the SS prefix, it is only required for "unusual" Windows applications. Unfortunately the SIGILL signal kills Wine immediately, which makes it impossible to run for the test suite (without hacking either Wine or Valgrind). To solve this problem we have basically the following options: * Just ignore SS prefixes for now, probably show a warning. Julian Seward said that he is not really happy with this idea. ;) * Try to find some rule which can be used to decide if we can ignore the SS prefix. Unfortunately there is no really good rule. One possible solution would be to check if SS==DS, something like http://ix.io/gK2, but it is of course not completely correct. The whole way how Valgrind handles segment registers looks a bit hacky, because "no prefix" doesn't mean that segment registers are not used. All the implicit segment register usage still seems to be missing in the implementation. Test code for SS==DS and SS!=DS can be found here: http://ix.io/gKy, make sure to compile with -m32. * Correctly handle the SS prefix when explicitly specified. This would probably be the most consistent solution. Implicit handling is of course still missing, but thats a separate and much more complicated task, which also involves all other segment registers. http://ix.io/gKt shows an example how it could be implemented. This patch also contains a "fix" for a different bug, Valgrind doesn't initialize the system entries of the GDT table, which results in a segmentation fault (test code http://ix.io/gKw, compile with -m32). I leave it up to the Valgrind experts which of these solutions is preferred. Best regards, Sebastian To give a bit more info (and for myself in the future ;). This is still present in development wine (wine-1.9.24-105-g1d3b944) and valgrind (valgrind-3.13.0.SVN, #define VGSVN "16171", #define VEXSVN "3285"). It's not reproducible with every wine unit tests. The first case I found was dlls/advapi32/tests/service.c. For info on running wine under valgrind, see: https://wiki.winehq.org/Wine_and_Valgrind my scripts/suppression files are at: https://github.com/austin987/wine_misc/tree/master/valgrind but in short: # get wine/wine_misc repos $ cd wine-valgrind $ ln -s /path/to/wine_misc/valgrind tools/valgrind $ ./configure && make -j8 $ vi tools/valgrind/vg-wrapper.sh # edit paths to wine/valgrind, if needed $ . tools/valgrind/vg-wrapper.sh $ ./wine start /min notepad $ cd dlls/advapi32/tests $ make service.ok # BUG If the bug is present, you should see: ../../../tools/runtest -q -P wine -T ../../.. -M advapi32.dll -p advapi32_test.exe.so service && touch service.ok preloader: Warning: failed to reserve range 00110000-68000000 preloader: Warning: failed to reserve range 7f000000-82000000 err:rpc:I_RpcGetBuffer no binding err:seh:segv_handler Got unexpected trap 0 wine: Unhandled illegal instruction at address 0x7bc280f5 (thread 006d), starting debugger... preloader: Warning: failed to reserve range 00110000-68000000 preloader: Warning: failed to reserve range 7f000000-82000000 the key lines being: err:seh:segv_handler Got unexpected trap 0 wine: Unhandled illegal instruction at address 0x7bc280f5 (thread 006d), starting debugger... at that point, it will hang indefinitely. With a patch from Sebastian (for Wine): diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 59dca6c..a8cdb96 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -2076,6 +2076,15 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) return; } + if (!get_trap_code(context) && + siginfo->si_addr == (void *)EIP_sig(context) && + *(char *)EIP_sig(context) == 0x36) + { + FIXME("---> working around Valgrind SIGILL exception\n"); + EIP_sig(context)++; + return; + } + /* check for page fault inside the thread stack */ if (get_trap_code(context) == TRAP_x86_PAGEFLT && (char *)siginfo->si_addr >= (char *)NtCurrentTeb()->DeallocationStack && the tests will pass and not hang. Created attachment 103551 [details]
[PATCH 1/2] Initialize x86 system GDT on first use.
Thanks Julian for taking a look at the proposed patches. This series is an improved version of method 3, which initializes the system GDT on first use. Feedback welcome!
Testcase (crashes without the patch):
--- snip ---
/* gcc -m32 -o test test.c */
int main (int argc, char *argv[])
{
asm(".byte 0x3E\n" \
"movl (%esp),%eax\n");
return 0;
}
--- snip ---
Please note that this issue is unrelated to the SS segment problem.
Created attachment 103552 [details]
[PATCH 2/2] VEX: Recognize the SS segment prefix on x86.
> Created attachment 103551 [details] > [PATCH 1/2] Initialize x86 system GDT on first use. Committed, valgrind r16204. > Created attachment 103552 [details] > [PATCH 2/2] VEX: Recognize the SS segment prefix on x86. Committed, vex r3299. Thanks for the patches! Richard .. 2 years later .. can we close this now? |