vdexExtractor: Linux: compact_dex_converter fails with "Illegal instruction (core dumped)"

Hello,

When trying to convert cdex to dex, compact_dex_converter fails:

$ bin/compact_dex_converterd services_classes.cdex 
Opened 'services_classes.cdex', DEX version '001'
Illegal instruction (core dumped)

You asked if I would use valgrind to run it, and to my surprise it works when run through valgrind:

$ valgrind bin/compact_dex_converterd services_classes.cdex 
==6242== Memcheck, a memory error detector
==6242== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6242== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==6242== Command: bin/compact_dex_converterd services_classes.cdex
==6242== 
--6242-- Warning: DWARF2 CFI reader: unhandled DW_OP_ opcode 0x13
--6242-- Warning: DWARF2 CFI reader: unhandled DW_OP_ opcode 0x13
Opened 'services_classes.cdex', DEX version '001'
compact_dex_converterd I 09-07 08:17:15  6242  6242 compact_dex_converter_main.cc:172] StandardDex file successfully extracted to services_classes.cdex.new
==6242== 
==6242== HEAP SUMMARY:
==6242==     in use at exit: 264 bytes in 7 blocks
==6242==   total heap usage: 1,377,216 allocs, 1,377,209 frees, 115,375,932 bytes allocated
==6242== 
==6242== LEAK SUMMARY:
==6242==    definitely lost: 0 bytes in 0 blocks
==6242==    indirectly lost: 0 bytes in 0 blocks
==6242==      possibly lost: 0 bytes in 0 blocks
==6242==    still reachable: 264 bytes in 7 blocks
==6242==         suppressed: 0 bytes in 0 blocks
==6242== Rerun with --leak-check=full to see details of leaked memory
==6242== 
==6242== For counts of detected and suppressed errors, rerun with: -v
==6242== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Now I am really confused

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 18 (3 by maintainers)

Most upvoted comments

@superr Last try, built compact_dex_converter with amdfam10 optimization flags compact_dex_converter_amdfam10.zip

@superr Ok, i don’t know what cpu you use, but it seems that you can add -march and-mtune flags to linuxCflags in x86_linux_host.go. Set them to core2 and built new binary, maybe it will work. Have no more ideas how to fix this. compact_dex_converter_core2.zip

You can try to change compilation flags. But i’m not sure flags from what files used for host build. I recommend start from “/build/soog/cc/config” there you can find “x86_linux_host.go” open it and try to change

	// Extended cflags
	linuxX86Cflags = []string{
		"-msse3",
		"-mfpmath=sse",
		"-m32",
		"-march=prescott",
		"-D_FILE_OFFSET_BITS=64",
		"-D_LARGEFILE_SOURCE=1",
	}

you can try remove this

		"-march=prescott",
		"-msse3",
		"-mfpmath=sse",

if this won’t help you can open “global.go” and change commonGlobalCflags, for example “-O2” to “-O1”

@superr Open Android.bp and find:

art_cc_binary {
    name: "compact_dex_converter",
    defaults: ["compact_dex_converter_defaults"],
    shared_libs: [
        "libart",
        "libart-dexlayout",
        "libdexfile",
    ],
}

art_cc_binary {
    name: "compact_dex_converterd",
    defaults: [
        "art_debug_defaults",
        "compact_dex_converter_defaults",
    ],
    shared_libs: [
        "libartd",
        "libartd-dexlayout",
        "libdexfiled",
    ],
}

and change to:

art_cc_binary {
    name: "compact_dex_converter",
    defaults: ["compact_dex_converter_defaults"],
    shared_libs: [
        "libartbase",
        "libart",
        "libart-dexlayout",
        "libdexfile",
    ],
}

art_cc_binary {
    name: "compact_dex_converterd",
    defaults: [
        "art_debug_defaults",
        "compact_dex_converter_defaults",
    ],
    shared_libs: [
        "libartbased",
        "libartd",
        "libartd-dexlayout",
        "libdexfiled",
    ],
}

@superr

--- a/compact_dex_converter_main.cc	2018-09-11 09:14:21.928715800 +0300
+++ b/compact_dex_converter_main.cc	2018-09-03 23:56:40.856742000 +0300
@@ -36,7 +36,7 @@
 #include "base/os.h"
 #include "base/unix_file/fd_file.h"
 #include "dex/dex_file_loader.h"
-#include "mem_map.h"
+#include "base/mem_map.h"
 #include "runtime.h"
 
 namespace art {
@@ -67,19 +67,22 @@
 
   // We cannot use the ArtDexFileLoader since it only supports openning CompactDex
   // files from Vdex containers.
-  std::string error;
+  DexFileLoaderErrorCode error_code;
+  std::string error_msg;
   const bool kVerifyChecksum = false;
   const bool kVerify = true;  // Input file should always verify
   const DexFileLoader dex_file_loader;
   std::vector<std::unique_ptr<const DexFile>> dex_files;
   if (!dex_file_loader.OpenAll(reinterpret_cast<const uint8_t*>(content.data()),
                                content.size(),
                                file_name,
                                kVerify,
                                kVerifyChecksum,
-                               &error,
+                               &error_code,
+                               &error_msg,
                                &dex_files)) {
-    LOG(ERROR) << "Input Dex file open failed: " << error;
+    LOG(ERROR) << "Input Dex file open failed: " << error_msg;
     return 1;
   }
 
@@ -112,8 +115,8 @@
                                  dex_files[0].get(),
                                  0,
                                  &dex_container,
-                                 &error)) {
-    LOG(ERROR) << "Unable to process CompactDex file: " << error;
+                                 &error_msg)) {
+    LOG(ERROR) << "Unable to process CompactDex file: " << error_msg;
     return 1;
   }
 
@@ -132,9 +135,9 @@
                                       /*oat_dex_file*/ nullptr,
                                       /*verify*/ verify_output_file,
                                       /*verify_checksum*/ false,
-                                      &error);
+                                      &error_msg);
   if (new_dex_file == nullptr) {
-    LOG(ERROR) << "Unable to open dex file from memory: " << error;
+    LOG(ERROR) << "Unable to open dex file from memory: " << error_msg;
     return 1;
   }
 
@@ -251,3 +254,4 @@
 
   return art::DexlayoutDriver(argc, argv);
 }

@superr it seems that the libc++.so that I have compiled and shared is not compatible with your system due to some CPU missing features (most probably an old model not supporting all new instruction emitted from newer compiler version).

The reason that it works when running from within valgrind, is because valgrind places its own hooks to instrument allocations (including the one that contains the illegal instruction) and thus the original implementation is never invoked (SIGILL is not triggered).

Unfortunately I cannot do much from my side. However, you can try forking the necessary AOSP repos, apply the compact_dex_converter patch in the ART git repo and build yourself. Hopefully, when compiling libc++ the compiler will handle the older CPU issue.