My program is using Google Chromium's V8 Javascript interpreter. The code is just this: #include "v8_wrapper/v8.h" v8::Persistent<v8::ObjectTemplate> v8_global; int main(int argc, char* argv[]) { v8::Handle<v8::Context> root_ctx = v8::Context::New(NULL, v8_global); return 0; } (Though of course it requires building Chromium first.) When running it in Valgrind, I get: vex: priv/guest_amd64_toIR.c:14600 (disInstr_AMD64_WRK): Assertion `sz == 2 || sz == 4' failed. vex storage: T total 1552747360 bytes allocated vex storage: P total 816 bytes allocated valgrind: the 'impossible' happened: LibVEX called failure_exit(). ==24395== at 0x3802C2EC: report_and_quit (m_libcassert.c:145) ==24395== by 0x3802C3C4: panic (m_libcassert.c:227) ==24395== by 0x3802C432: vgPlain_core_panic_at (m_libcassert.c:232) ==24395== by 0x3802C451: vgPlain_core_panic (m_libcassert.c:237) ==24395== by 0x38044A12: failure_exit (m_translate.c:674) ==24395== by 0x380B6948: vex_assert_fail (main_util.c:220) ==24395== by 0x38121836: disInstr_AMD64_WRK (guest_amd64_toIR.c:14600) ==24395== by 0x38123B1B: disInstr_AMD64 (guest_amd64_toIR.c:16116) ==24395== by 0x380C4ABA: bb_to_IR (guest_generic_bb_to_IR.c:229) ==24395== by 0x380B5168: LibVEX_Translate (main_main.c:420) ==24395== by 0x380427C2: vgPlain_translate (m_translate.c:1517) ==24395== by 0x38065088: vgPlain_scheduler (scheduler.c:844) ==24395== by 0x3808E0F0: run_a_thread_NORETURN (syswrap-linux.c:91) sched status: running_tid=1 Thread 1: status = VgTs_Runnable ==24395== at 0x40DC937: ??? ==24395== by 0x53D6FB: v8::internal::Invoke(bool, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Object***, bool*) (execution.cc:102) ==24395== by 0x53DC2F: v8::internal::Execution::Call(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Object***, bool*) (execution.cc:129) ==24395== by 0x524458: v8::internal::Genesis::CompileScriptCached(v8::internal::Vector<char const>, v8::internal::Handle<v8::internal::String>, v8::internal::SourceCodeCache*, v8::Extension*, bool) (bootstrapper.cc:913) ==24395== by 0x524875: v8::internal::Genesis::CompileNative(v8::internal::Vector<char const>, v8::internal::Handle<v8::internal::String>) (bootstrapper.cc:865) ==24395== by 0x5249EB: v8::internal::Genesis::CompileBuiltin(int) (bootstrapper.cc:855) ==24395== by 0x525205: v8::internal::Genesis::InstallNatives() (bootstrapper.cc:1113) ==24395== by 0x52579F: v8::internal::Genesis::Genesis(v8::internal::Handle<v8::internal::Object>, v8::Handle<v8::ObjectTemplate>, v8::ExtensionConfiguration*) (bootstrapper.cc:1554) ==24395== by 0x525883: v8::internal::Bootstrapper::CreateEnvironment(v8::internal::Handle<v8::internal::Object>, v8::Handle<v8::ObjectTemplate>, v8::ExtensionConfiguration*) (bootstrapper.cc:347) ==24395== by 0x512171: v8::Context::New(v8::ExtensionConfiguration*, v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Value>) (api.cc:2695) ==24395== by 0x509EA9: main (server.cc:6) My system info: $ uname -a Linux dima-ubuntu 2.6.28-11-generic #42-Ubuntu SMP Fri Apr 17 01:58:03 UTC 2009 x86_64 GNU/Linux
Also, when the assertion fires, the value of "sz" is 8.
Heh... I changed the assert statement to: vassert(sz == 2 || sz == 4 || sz == 8); and everything seems to work just fine.
The patch works for me, too! Please commit... To reproduce with a prebuilt binary: wget http://kegel.com/chromium/bug_210481.tar.bz2 tar -xjvf bug_210481.tar.bz2 valgrind out/Debug/net_unittests --gtest_filter=ProxyResolverV8Test.LoadLog
So basically V8 is adding a REX prefix to the POP instruction that isn't needed because POP defaults to 64 bit.
Tom, why has this spung back to life after a year? Did you fall across some other instance of it recently?
A friend of mine was trying to track down a problem in some code that was using V8 and when I suggested using valgrind he ran into this error so I had a look at it and found this bug.
A quick check doesn't show any way that the V8 x64 assembler can generate a pop with a REX.W prefix. It does generate REX bytes, but not with the REX.W bit set. I haven't found the exact opcode that triggers valgrind in the example yet. Is this a current version of V8? That said, it seems valgrind allows sz == 8 on opcodes 0x58..0x5f (pop to register), but not on opcode 0x8f (pop to memory). Since the REX.W prefix is harmless, I would think it should at most give a warning, not a fatal error.
I've checked with my friend and he was using the version of V8 that ships with Ubuntu Maverick, which was apparently libv8-2.2.18.
That explains the problem. V8 changed the x64 assembler in revision 4928 to no longer use REX.W in some cases where it makes no difference (including pop). The change should have gone to the stable branch in version 2.2.20.
Fixed, vex r2079.