2016-09-24 35 views
6

Mam funkcję, która wygląda mniej więcej tak -valgrind: Nierozpoznany instrukcja pod adresem 0x5111715

std::string func() 
{ 
    std::string result; 

    ... 

    auto seed = std::random_device()(); 
    std::mt19937 gen(seed); 
    std::uniform_int_distribution<> dis(0, 61); 

    ... 
    return result; 
} 

który kompiluje grzywny całej gamy kompilatory i ich wersji, ale nadal nie przejdzie testu Valgrind na Ubuntu. Wyraźnie wspomniałem o ubuntu, ponieważ pomyślnie przechodzi on na moim komputerze, na którym zainstalowano Arch Linux.

Obie instalacje valgrind zgłaszają swoją wersję jako valgrind-3.11.0, a jedyną różnicą jest instalacja Arch Linux na moim komputerze bez wirtualizacji, podczas gdy testy Ubuntu zostały przeprowadzone na serwerach DO/CI, które prawdopodobnie są w ramach pewnego rodzaju wirtualizacji. Ale czy to ma znaczenie?


Oto log na metę valgrind -

--- stderr --- 
==13849== Memcheck, a memory error detector 
==13849== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==13849== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==13849== Command: file/path/here 
==13849== 
vex amd64->IR: unhandled instruction bytes: 0xF 0xC7 0xF0 0x89 0x6 0xF 0x42 0xC1 
vex amd64->IR: REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0 
vex amd64->IR: VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=0F 
vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0 
==13849== valgrind: Unrecognised instruction at address 0x5111715. 
==13849== at 0x5111715: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22) 
==13849== by 0x51118B1: std::random_device::_M_getval() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22) 
==13849== by 0x4809FB: std::random_device::operator()() (random.h:1612) 
==13849== by 0x47F0C2: isaac::deviceList::genId[abi:cxx11](unsigned int) (deviceList.cpp:21) 
==13849== by 0x47F2A7: isaac::deviceList::place(isaac::deviceType, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator>) (deviceList.cpp:38) 
==13849== by 0x40D06E: DeviceList_place_Test::TestBody() (test.cpp:194) 
==13849== by 0x45D5A7: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2078) 
==13849== by 0x4588D2: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2114) 
==13849== by 0x43EBB3: testing::Test::Run() (gtest.cc:2151) 
==13849== by 0x43F3F5: testing::TestInfo::Run() (gtest.cc:2326) 
==13849== by 0x43FA52: testing::TestCase::Run() (gtest.cc:2444) 
==13849== by 0x446911: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:4315) 
==13849== Your program just tried to execute an instruction that Valgrind 
==13849== did not recognise. There are two possible reasons for this. 
==13849== 1. Your program has a bug and erroneously jumped to a non-code 
==13849== location. If you are running Memcheck and you just saw a 
==13849== warning about a bad jump, it's probably your program's fault. 
==13849== 2. The instruction is legitimate but Valgrind doesn't handle it, 
==13849== i.e. it's Valgrind's fault. If you think this is the case or 
==13849== you are not sure, please let us know and we'll try to fix it. 
==13849== Either way, Valgrind will now raise a SIGILL signal which will 
==13849== probably kill your program. 
==13849== 
==13849== Process terminating with default action of signal 4 (SIGILL): dumping core 
==13849== Illegal opcode at address 0x5111715 
==13849== at 0x5111715: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22) 
==13849== by 0x51118B1: std::random_device::_M_getval() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22) 
==13849== by 0x4809FB: std::random_device::operator()() (random.h:1612) 
==13849== by 0x47F0C2: isaac::deviceList::genId[abi:cxx11](unsigned int) (deviceList.cpp:21) 
==13849== by 0x47F2A7: isaac::deviceList::place(isaac::deviceType, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator>) (deviceList.cpp:38) 
==13849== by 0x40D06E: DeviceList_place_Test::TestBody() (test.cpp:194) 
==13849== by 0x45D5A7: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2078) 
==13849== by 0x4588D2: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2114) 
==13849== by 0x43EBB3: testing::Test::Run() (gtest.cc:2151) 
==13849== by 0x43F3F5: testing::TestInfo::Run() (gtest.cc:2326) 
==13849== by 0x43FA52: testing::TestCase::Run() (gtest.cc:2444) 
==13849== by 0x446911: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:4315) 
==13849== 
==13849== HEAP SUMMARY: 
==13849==  in use at exit: 84,300 bytes in 108 blocks 
==13849== total heap usage: 622 allocs, 514 frees, 530,112 bytes allocated 
==13849== 
==13849== LEAK SUMMARY: 
==13849== definitely lost: 0 bytes in 0 blocks 
==13849== indirectly lost: 0 bytes in 0 blocks 
==13849==  possibly lost: 0 bytes in 0 blocks 
==13849== still reachable: 84,300 bytes in 108 blocks 
==13849==   suppressed: 0 bytes in 0 blocks 
==13849== Rerun with --leak-check=full to see details of leaked memory 
==13849== 
==13849== For counts of detected and suppressed errors, rerun with: -v 
==13849== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
------- 

EDIT - Ja również próbowałem ręcznie budowania valgrind z oficjalnego źródła i instalowania go, jednak wciąż produkuje ten sam błąd.

+1

Jakie flagi kompilatora użyłeś na komputerze z Ubuntu? Oczywiście kompilator generuje niedozwoloną instrukcję. Jaki jest wynik działania '/ proc/cpuinfo' na komputerze Ubuntu? –

+0

@MartinNyolt obie kompilacje mają te same flagi, ubuntu '/ proc/cpuinfo' - https://gist.github.com/agauniyal/c8d57b106097a16296b259b86fc93368 –

+1

Ale * co * flagi dokładnie? Pomagam ci dowiedzieć się * dlaczego * Twój kompilator generuje nielegalną instrukcję. Czy debugowałeś kod i sprawdzałeś * jaką * instrukcję próbuje wykonać? Czy błąd występuje tylko podczas valgrind, czy też masz SIGILL również podczas normalnej egzekucji? –

Odpowiedz

3

Wygląda na to, że twój system Ubuntu ma bibliotekę liczb losowych, która używa instrukcji (kod operacji 0x0f 0xc7), której twoja wersja Valgrind nie rozpoznaje. Twój system Arch ewidentnie używa innej implementacji, która nie korzysta z tej instrukcji.

Być może uda się obejść ten problem, ponownie kompilując procesor przed mostem Ivy Bridge.

+0

ponowne kompilowanie jak przy kompilacji w moim systemie, następnie pobieranie tego binarnego na CI buduje i działa na nim valgrind? –

+1

Wygląda na to, że instrukcja znajduje się w bibliotece libstdC++, więc prawdopodobnie trzeba będzie ją ponownie skompilować.Możesz także sprawdzić, czy jest to znany problem z valgrindem i sprawdzić, czy są jakieś łaty, aby to naprawić. –

+0

hmm, nie mogę zamiast tego utworzyć statycznego linku do niego? Ponowna kompilacja biblioteki libstdC++ nie wydaje mi się zadaniem dziennym: p –

7

Zobacz https://bugs.kde.org/show_bug.cgi?id=353370.

Pobieranie/kompilowanie ostatniej wersji svn powinno rozwiązać ten problem.

Jeśli nie, zgłoś to na bugzilla, ponieważ wkrótce pojawi się wersja 3.12. Dzięki

+1

Zapomniałem komentować, ale to rozwiązało mój problem :) –