Just An Application

September 29, 2014

Building The Android Runtime (ART) For Mac OS X: Part Six — Once More With Feeling

Removing the dex2oat and dex2oatd executables from the directory

    out/host/darwin-x86/bin

and the object files from

    out/host/darwin-x86/obj/EXECUTABLES/dex2oat_intermediates

and

    out/host/darwin-x86/obj/EXECUTABLES/dex2oatd_intermediates

and restarting the build results in dex2oat getting rebuilt as a 32-bit executable.

As expected, at the point dex2oat is first invoked in the build it no longer spins, instead, and not as expected, it crashes.

    ...

    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299] *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299] Fatal signal 10 (SIGBUS), code 2 (BUS_ADRERR) fault addr 0x2fb0ed6
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299] OS: Darwin 13.4.0 (x86_64)
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299] Cmdline: out/host/darwin-x86/bin/dex2oatd ...
    
    ...
    
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299] Thread: 72220 "<unknown>"
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299] Registers:
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299]     eax: 0x7eadf38a    ebx: 0x7da400e4    ecx: 0x00000076    edx: 0x00000b10
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299]     edi: 0x00000012    esi: 0x02fb0ed6    ebp: 0xbff54578    esp: 0xbff5456c
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299]     eip: 0x002db0e1                    eflags: 0x00010202 [ IF ]
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299]      cs: 0x0000001b     ds: 0x00000023     es: 0x00000023     fs: 0x0000001f
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299]      gs: 0x0000000f     ss: 0x00000023
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299] Backtrace:
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:299]
    dex2oatd F 24874 72220 art/runtime/runtime_linux.cc:313] Fault message:
    make: *** [out/host/darwin-x86/framework/x86_64/core.art] Error 1

Following the way of the printf once more reveals that the crash occurs in this function

File: $(ANDROID_SRC)/art/runtime/mem_map.cc

    ...
    
    static bool ContainedWithinExistingMap(uintptr_t begin,
                                           uintptr_t end,
                                           std::string* error_msg) {
      std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
      if (map.get() == nullptr) {
        *error_msg = StringPrintf("Failed to build process map");
        return false;
      }
      for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
        if ((begin >= it->start && begin < it->end)  // start of new within old
            && (end > it->start && end <= it->end)) {  // end of new within old
          return true;
        }
      }
      std::string maps;
      ReadFileToString("/proc/self/maps", &maps);
      *error_msg = StringPrintf("Requested region 0x%08" PRIxPTR "-0x%08" PRIxPTR " does not overlap "
                                "any existing map:\n%s\n",
                                begin, end, maps.c_str());
      return false;
    }
    
    ...

While this is clearly a very Mac OS X unfriendly function, it crashes a bit before the point where it might attempt to read the non-existent ‘file’

    /proc/self/maps

In fact it crashes at the point at which the for loop initialization is doing

      BacktraceMap::const_iterator it = map->begin();

The problem looks as though it might involve death by some combination of temporary variable/assignment operator/copy constructor C++ voodoo and the compiler getting horribly confused or something.

Various attempts at re-factoring to induce some non-crashing combination of temporary variable/assignment operator/copy constructor C++ voodoo all failed, so I tried this

    ...
    
    static bool ContainedWithinExistingMap(uintptr_t begin,
                                           uintptr_t end,
                                           std::string* error_msg) {
      std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
      if (map.get() == nullptr) {
        *error_msg = StringPrintf("Failed to build process map");
        return false;
      }
    
      const backtrace_map_t* entry = map->Find(begin);
    
      if ((entry != NULL) && (end <= entry->end)) {
        return true;
      }

      std::string maps;
      ReadFileToString("/proc/self/maps", &maps);
      *error_msg = StringPrintf("Requested region 0x%08" PRIxPTR "-0x%08" PRIxPTR " does not overlap "
                                "any existing map:\n%s\n",
                                begin, end, maps.c_str());
      return false;
    }
    
    ...

which works.

Quite why it works I don’t know, since the BacktraceMap::Find method is defined like this

File: $(ANDROID_SRC)/system/core/libbacktrace/BacktraceMap.cpp

    ...
    
    const backtrace_map_t* BacktraceMap::Find(uintptr_t addr) {
      for (BacktraceMap::const_iterator it = begin();
           it != end(); ++it) {
        if (addr >= it->start && addr < it->end) {
          return &*it;
        }
      }
      return NULL;
    }
    
    ...

It too is using an iterator in exactly the same way. It just doesn’t crash when it does so.


Copyright (c) 2014 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: