7133122: SA throws sun.jvm.hotspot.debugger.UnmappedAddressException when it should not

Sun, 22 Sep 2013 18:49:09 +0400

author
dsamersoff
date
Sun, 22 Sep 2013 18:49:09 +0400
changeset 5758
1f42d3ec1759
parent 5756
a7609ec351d6
child 5759
ae2edb3df7fb

7133122: SA throws sun.jvm.hotspot.debugger.UnmappedAddressException when it should not
Summary: replace PT_LOAD segment with library segment when necessary
Reviewed-by: dholmes, sla

agent/src/os/linux/ps_core.c file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/os/linux/ps_core.c	Fri Sep 20 18:19:07 2013 -0700
     1.2 +++ b/agent/src/os/linux/ps_core.c	Sun Sep 22 18:49:09 2013 +0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -698,29 +698,58 @@
    1.11  
    1.12  // read segments of a shared object
    1.13  static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
    1.14 -   int i = 0;
    1.15 -   ELF_PHDR* phbuf;
    1.16 -   ELF_PHDR* lib_php = NULL;
    1.17 +  int i = 0;
    1.18 +  ELF_PHDR* phbuf;
    1.19 +  ELF_PHDR* lib_php = NULL;
    1.20  
    1.21 -   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
    1.22 -      return false;
    1.23 +  int page_size=sysconf(_SC_PAGE_SIZE);
    1.24  
    1.25 -   // we want to process only PT_LOAD segments that are not writable.
    1.26 -   // i.e., text segments. The read/write/exec (data) segments would
    1.27 -   // have been already added from core file segments.
    1.28 -   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
    1.29 -      if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
    1.30 -         if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
    1.31 -            goto err;
    1.32 +  if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
    1.33 +    return false;
    1.34 +  }
    1.35 +
    1.36 +  // we want to process only PT_LOAD segments that are not writable.
    1.37 +  // i.e., text segments. The read/write/exec (data) segments would
    1.38 +  // have been already added from core file segments.
    1.39 +  for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
    1.40 +    if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
    1.41 +
    1.42 +      uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
    1.43 +      map_info *existing_map = core_lookup(ph, target_vaddr);
    1.44 +
    1.45 +      if (existing_map == NULL){
    1.46 +        if (add_map_info(ph, lib_fd, lib_php->p_offset,
    1.47 +                          target_vaddr, lib_php->p_filesz) == NULL) {
    1.48 +          goto err;
    1.49 +        }
    1.50 +      } else {
    1.51 +        if ((existing_map->memsz != page_size) &&
    1.52 +            (existing_map->fd != lib_fd) &&
    1.53 +            (existing_map->memsz != lib_php->p_filesz)){
    1.54 +
    1.55 +          print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
    1.56 +                        target_vaddr, lib_php->p_filesz, lib_php->p_flags);
    1.57 +          goto err;
    1.58 +        }
    1.59 +
    1.60 +        /* replace PT_LOAD segment with library segment */
    1.61 +        print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
    1.62 +                     existing_map->memsz, lib_php->p_filesz);
    1.63 +
    1.64 +        existing_map->fd = lib_fd;
    1.65 +        existing_map->offset = lib_php->p_offset;
    1.66 +        existing_map->memsz = lib_php->p_filesz;
    1.67        }
    1.68 -      lib_php++;
    1.69 -   }
    1.70 +    }
    1.71  
    1.72 -   free(phbuf);
    1.73 -   return true;
    1.74 +    lib_php++;
    1.75 +  }
    1.76 +
    1.77 +  free(phbuf);
    1.78 +  return true;
    1.79  err:
    1.80 -   free(phbuf);
    1.81 -   return false;
    1.82 +  free(phbuf);
    1.83 +  return false;
    1.84  }
    1.85  
    1.86  // process segments from interpreter (ld.so or ld-linux.so)

mercurial