diff --git a/compiler/elf_writer_debug.cc b/compiler/elf_writer_debug.cc
index 6fe05a4..39233ce 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -188,12 +188,6 @@
                         std::vector<uint8_t>* debug_line) {
   const std::vector<OatWriter::DebugInfo>& method_infos = oat_writer->GetMethodDebugInfo();
   const InstructionSet isa = compiler->GetInstructionSet();
-  uint32_t cunit_low_pc = static_cast<uint32_t>(-1);
-  uint32_t cunit_high_pc = 0;
-  for (auto method_info : method_infos) {
-    cunit_low_pc = std::min(cunit_low_pc, method_info.low_pc_);
-    cunit_high_pc = std::max(cunit_high_pc, method_info.high_pc_);
-  }
 
   // Find all addresses (low_pc) which contain deduped methods.
   // The first instance of method is not marked deduped_, but the rest is.
@@ -204,173 +198,187 @@
     }
   }
 
+  // Group the methods into compilation units based on source file.
+  std::vector<std::vector<const OatWriter::DebugInfo*>> compilation_units;
+  const char* last_source_file = nullptr;
+  for (const auto& mi : method_infos) {
+    // Attribute given instruction range only to single method.
+    // Otherwise the debugger might get really confused.
+    if (!mi.deduped_) {
+      auto& dex_class_def = mi.dex_file_->GetClassDef(mi.class_def_index_);
+      const char* source_file = mi.dex_file_->GetSourceFile(dex_class_def);
+      if (compilation_units.empty() || source_file != last_source_file) {
+        compilation_units.push_back(std::vector<const OatWriter::DebugInfo*>());
+      }
+      compilation_units.back().push_back(&mi);
+      last_source_file = source_file;
+    }
+  }
+
   // Write .debug_info section.
-  size_t debug_abbrev_offset = debug_abbrev->size();
-  DebugInfoEntryWriter<> info(false /* 32 bit */, debug_abbrev);
-  info.StartTag(DW_TAG_compile_unit, DW_CHILDREN_yes);
-  info.WriteStrp(DW_AT_producer, "Android dex2oat", debug_str);
-  info.WriteData1(DW_AT_language, DW_LANG_Java);
-  info.WriteAddr(DW_AT_low_pc, cunit_low_pc + text_section_offset);
-  info.WriteAddr(DW_AT_high_pc, cunit_high_pc + text_section_offset);
-  info.WriteData4(DW_AT_stmt_list, debug_line->size());
-  for (auto method_info : method_infos) {
-    std::string method_name = PrettyMethod(method_info.dex_method_index_,
-                                           *method_info.dex_file_, true);
-    if (deduped_addresses.find(method_info.low_pc_) != deduped_addresses.end()) {
-      method_name += " [DEDUPED]";
-    }
-    info.StartTag(DW_TAG_subprogram, DW_CHILDREN_no);
-    info.WriteStrp(DW_AT_name, method_name.data(), debug_str);
-    info.WriteAddr(DW_AT_low_pc, method_info.low_pc_ + text_section_offset);
-    info.WriteAddr(DW_AT_high_pc, method_info.high_pc_ + text_section_offset);
-    info.EndTag();  // DW_TAG_subprogram
-  }
-  info.EndTag();  // DW_TAG_compile_unit
-  auto* debug_info_patches = oat_writer->GetAbsolutePatchLocationsFor(".debug_info");
-  WriteDebugInfoCU(debug_abbrev_offset, info, debug_info, debug_info_patches);
-
-  // TODO: in gdb info functions <regexp> - reports Java functions, but
-  // source file is <unknown> because .debug_line is formed as one
-  // compilation unit. To fix this it is possible to generate
-  // a separate compilation unit for every distinct Java source.
-  // Each of the these compilation units can have several non-adjacent
-  // method ranges.
-
-  // Write .debug_line section.
-  std::vector<FileEntry> files;
-  std::unordered_map<std::string, size_t> files_map;
-  std::vector<std::string> directories;
-  std::unordered_map<std::string, size_t> directories_map;
-  int code_factor_bits_ = 0;
-  int dwarf_isa = -1;
-  switch (isa) {
-    case kArm:  // arm actually means thumb2.
-    case kThumb2:
-      code_factor_bits_ = 1;  // 16-bit instuctions
-      dwarf_isa = 1;  // DW_ISA_ARM_thumb.
-      break;
-    case kArm64:
-    case kMips:
-    case kMips64:
-      code_factor_bits_ = 2;  // 32-bit instructions
-      break;
-    case kNone:
-    case kX86:
-    case kX86_64:
-      break;
-  }
-  DebugLineOpCodeWriter<> opcodes(false /* 32bit */, code_factor_bits_);
-  opcodes.SetAddress(text_section_offset + cunit_low_pc);
-  if (dwarf_isa != -1) {
-    opcodes.SetISA(dwarf_isa);
-  }
-  for (const OatWriter::DebugInfo& mi : method_infos) {
-    // Addresses in the line table should be unique and increasing.
-    if (mi.deduped_) {
-      continue;
+  for (const auto& compilation_unit : compilation_units) {
+    uint32_t cunit_low_pc = 0xFFFFFFFFU;
+    uint32_t cunit_high_pc = 0;
+    for (auto method_info : compilation_unit) {
+      cunit_low_pc = std::min(cunit_low_pc, method_info->low_pc_);
+      cunit_high_pc = std::max(cunit_high_pc, method_info->high_pc_);
     }
 
-    struct DebugInfoCallbacks {
-      static bool NewPosition(void* ctx, uint32_t address, uint32_t line) {
-        auto* context = reinterpret_cast<DebugInfoCallbacks*>(ctx);
-        context->dex2line_.push_back({address, static_cast<int32_t>(line)});
-        return false;
+    size_t debug_abbrev_offset = debug_abbrev->size();
+    DebugInfoEntryWriter<> info(false /* 32 bit */, debug_abbrev);
+    info.StartTag(DW_TAG_compile_unit, DW_CHILDREN_yes);
+    info.WriteStrp(DW_AT_producer, "Android dex2oat", debug_str);
+    info.WriteData1(DW_AT_language, DW_LANG_Java);
+    info.WriteAddr(DW_AT_low_pc, cunit_low_pc + text_section_offset);
+    info.WriteAddr(DW_AT_high_pc, cunit_high_pc + text_section_offset);
+    info.WriteData4(DW_AT_stmt_list, debug_line->size());
+    for (auto method_info : compilation_unit) {
+      std::string method_name = PrettyMethod(method_info->dex_method_index_,
+                                             *method_info->dex_file_, true);
+      if (deduped_addresses.find(method_info->low_pc_) != deduped_addresses.end()) {
+        method_name += " [DEDUPED]";
       }
-      DefaultSrcMap dex2line_;
-    } debug_info_callbacks;
-
-    const DexFile* dex = mi.dex_file_;
-    if (mi.code_item_ != nullptr) {
-      dex->DecodeDebugInfo(mi.code_item_,
-                           (mi.access_flags_ & kAccStatic) != 0,
-                           mi.dex_method_index_,
-                           DebugInfoCallbacks::NewPosition,
-                           nullptr,
-                           &debug_info_callbacks);
+      info.StartTag(DW_TAG_subprogram, DW_CHILDREN_no);
+      info.WriteStrp(DW_AT_name, method_name.data(), debug_str);
+      info.WriteAddr(DW_AT_low_pc, method_info->low_pc_ + text_section_offset);
+      info.WriteAddr(DW_AT_high_pc, method_info->high_pc_ + text_section_offset);
+      info.EndTag();  // DW_TAG_subprogram
     }
+    info.EndTag();  // DW_TAG_compile_unit
+    auto* debug_info_patches = oat_writer->GetAbsolutePatchLocationsFor(".debug_info");
+    WriteDebugInfoCU(debug_abbrev_offset, info, debug_info, debug_info_patches);
 
-    // Get and deduplicate directory and filename.
-    int file_index = 0;  // 0 - primary source file of the compilation.
-    auto& dex_class_def = dex->GetClassDef(mi.class_def_index_);
-    const char* source_file = dex->GetSourceFile(dex_class_def);
-    if (source_file != nullptr) {
-      std::string file_name(source_file);
-      size_t file_name_slash = file_name.find_last_of('/');
-      std::string class_name(dex->GetClassDescriptor(dex_class_def));
-      size_t class_name_slash = class_name.find_last_of('/');
-      std::string full_path(file_name);
-
-      // Guess directory from package name.
-      int directory_index = 0;  // 0 - current directory of the compilation.
-      if (file_name_slash == std::string::npos &&  // Just filename.
-          class_name.front() == 'L' &&  // Type descriptor for a class.
-          class_name_slash != std::string::npos) {  // Has package name.
-        std::string package_name = class_name.substr(1, class_name_slash - 1);
-        auto it = directories_map.find(package_name);
-        if (it == directories_map.end()) {
-          directory_index = 1 + directories.size();
-          directories_map.emplace(package_name, directory_index);
-          directories.push_back(package_name);
-        } else {
-          directory_index = it->second;
+    // Write .debug_line section.
+    std::vector<FileEntry> files;
+    std::unordered_map<std::string, size_t> files_map;
+    std::vector<std::string> directories;
+    std::unordered_map<std::string, size_t> directories_map;
+    int code_factor_bits_ = 0;
+    int dwarf_isa = -1;
+    switch (isa) {
+      case kArm:  // arm actually means thumb2.
+      case kThumb2:
+        code_factor_bits_ = 1;  // 16-bit instuctions
+        dwarf_isa = 1;  // DW_ISA_ARM_thumb.
+        break;
+      case kArm64:
+      case kMips:
+      case kMips64:
+        code_factor_bits_ = 2;  // 32-bit instructions
+        break;
+      case kNone:
+      case kX86:
+      case kX86_64:
+        break;
+    }
+    DebugLineOpCodeWriter<> opcodes(false /* 32bit */, code_factor_bits_);
+    opcodes.SetAddress(text_section_offset + cunit_low_pc);
+    if (dwarf_isa != -1) {
+      opcodes.SetISA(dwarf_isa);
+    }
+    for (const OatWriter::DebugInfo* mi : compilation_unit) {
+      struct DebugInfoCallbacks {
+        static bool NewPosition(void* ctx, uint32_t address, uint32_t line) {
+          auto* context = reinterpret_cast<DebugInfoCallbacks*>(ctx);
+          context->dex2line_.push_back({address, static_cast<int32_t>(line)});
+          return false;
         }
-        full_path = package_name + "/" + file_name;
+        DefaultSrcMap dex2line_;
+      } debug_info_callbacks;
+
+      const DexFile* dex = mi->dex_file_;
+      if (mi->code_item_ != nullptr) {
+        dex->DecodeDebugInfo(mi->code_item_,
+                             (mi->access_flags_ & kAccStatic) != 0,
+                             mi->dex_method_index_,
+                             DebugInfoCallbacks::NewPosition,
+                             nullptr,
+                             &debug_info_callbacks);
       }
 
-      // Add file entry.
-      auto it2 = files_map.find(full_path);
-      if (it2 == files_map.end()) {
-        file_index = 1 + files.size();
-        files_map.emplace(full_path, file_index);
-        files.push_back(FileEntry {
-          file_name,
-          directory_index,
-          0,  // Modification time - NA.
-          0,  // File size - NA.
-        });
-      } else {
-        file_index = it2->second;
-      }
-    }
-    opcodes.SetFile(file_index);
+      // Get and deduplicate directory and filename.
+      int file_index = 0;  // 0 - primary source file of the compilation.
+      auto& dex_class_def = dex->GetClassDef(mi->class_def_index_);
+      const char* source_file = dex->GetSourceFile(dex_class_def);
+      if (source_file != nullptr) {
+        std::string file_name(source_file);
+        size_t file_name_slash = file_name.find_last_of('/');
+        std::string class_name(dex->GetClassDescriptor(dex_class_def));
+        size_t class_name_slash = class_name.find_last_of('/');
+        std::string full_path(file_name);
 
-    // Generate mapping opcodes from PC to Java lines.
-    const DefaultSrcMap& dex2line_map = debug_info_callbacks.dex2line_;
-    uint32_t low_pc = text_section_offset + mi.low_pc_;
-    if (file_index != 0 && !dex2line_map.empty()) {
-      bool first = true;
-      for (SrcMapElem pc2dex : mi.compiled_method_->GetSrcMappingTable()) {
-        uint32_t pc = pc2dex.from_;
-        int dex_pc = pc2dex.to_;
-        auto dex2line = dex2line_map.Find(static_cast<uint32_t>(dex_pc));
-        if (dex2line.first) {
-          int line = dex2line.second;
-          if (first) {
-            first = false;
-            if (pc > 0) {
-              // Assume that any preceding code is prologue.
-              int first_line = dex2line_map.front().to_;
-              // Prologue is not a sensible place for a breakpoint.
-              opcodes.NegateStmt();
-              opcodes.AddRow(low_pc, first_line);
-              opcodes.NegateStmt();
-              opcodes.SetPrologueEnd();
+        // Guess directory from package name.
+        int directory_index = 0;  // 0 - current directory of the compilation.
+        if (file_name_slash == std::string::npos &&  // Just filename.
+            class_name.front() == 'L' &&  // Type descriptor for a class.
+            class_name_slash != std::string::npos) {  // Has package name.
+          std::string package_name = class_name.substr(1, class_name_slash - 1);
+          auto it = directories_map.find(package_name);
+          if (it == directories_map.end()) {
+            directory_index = 1 + directories.size();
+            directories_map.emplace(package_name, directory_index);
+            directories.push_back(package_name);
+          } else {
+            directory_index = it->second;
+          }
+          full_path = package_name + "/" + file_name;
+        }
+
+        // Add file entry.
+        auto it2 = files_map.find(full_path);
+        if (it2 == files_map.end()) {
+          file_index = 1 + files.size();
+          files_map.emplace(full_path, file_index);
+          files.push_back(FileEntry {
+            file_name,
+            directory_index,
+            0,  // Modification time - NA.
+            0,  // File size - NA.
+          });
+        } else {
+          file_index = it2->second;
+        }
+      }
+      opcodes.SetFile(file_index);
+
+      // Generate mapping opcodes from PC to Java lines.
+      const DefaultSrcMap& dex2line_map = debug_info_callbacks.dex2line_;
+      uint32_t low_pc = text_section_offset + mi->low_pc_;
+      if (file_index != 0 && !dex2line_map.empty()) {
+        bool first = true;
+        for (SrcMapElem pc2dex : mi->compiled_method_->GetSrcMappingTable()) {
+          uint32_t pc = pc2dex.from_;
+          int dex_pc = pc2dex.to_;
+          auto dex2line = dex2line_map.Find(static_cast<uint32_t>(dex_pc));
+          if (dex2line.first) {
+            int line = dex2line.second;
+            if (first) {
+              first = false;
+              if (pc > 0) {
+                // Assume that any preceding code is prologue.
+                int first_line = dex2line_map.front().to_;
+                // Prologue is not a sensible place for a breakpoint.
+                opcodes.NegateStmt();
+                opcodes.AddRow(low_pc, first_line);
+                opcodes.NegateStmt();
+                opcodes.SetPrologueEnd();
+              }
+              opcodes.AddRow(low_pc + pc, line);
+            } else if (line != opcodes.CurrentLine()) {
+              opcodes.AddRow(low_pc + pc, line);
             }
-            opcodes.AddRow(low_pc + pc, line);
-          } else if (line != opcodes.CurrentLine()) {
-            opcodes.AddRow(low_pc + pc, line);
           }
         }
+      } else {
+        // line 0 - instruction cannot be attributed to any source line.
+        opcodes.AddRow(low_pc, 0);
       }
-    } else {
-      // line 0 - instruction cannot be attributed to any source line.
-      opcodes.AddRow(low_pc, 0);
     }
+    opcodes.AdvancePC(text_section_offset + cunit_high_pc);
+    opcodes.EndSequence();
+    auto* debug_line_patches = oat_writer->GetAbsolutePatchLocationsFor(".debug_line");
+    WriteDebugLineTable(directories, files, opcodes, debug_line, debug_line_patches);
   }
-  opcodes.AdvancePC(text_section_offset + cunit_high_pc);
-  opcodes.EndSequence();
-  auto* debug_line_patches = oat_writer->GetAbsolutePatchLocationsFor(".debug_line");
-  WriteDebugLineTable(directories, files, opcodes, debug_line, debug_line_patches);
 }
 
 }  // namespace dwarf
