United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-8038392 : Generating prelink cache breaks JAVA 'jinfo' utility normal behaviour

Details
Type:
Bug
Submit Date:
2014-03-26
Status:
Resolved
Updated Date:
2014-06-13
Project Name:
JDK
Resolved Date:
2014-06-13
Component:
hotspot
OS:
linux_redhat_7.2
Sub-Component:
svc
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
7,8,9
Fixed Versions:

Related Reports

Sub Tasks

Description
Running prelink to generate its cache while java is running causes the OpenJDK "jinfo" utility to fail. 
                                    

Comments
-------- Original Message --------
Subject: Bug: Generating prelink cache breaks JAVA 'jinfo' utility normal behaviour
Date: Tue, 18 Mar 2014 14:11:13 -0400 (EDT)
From: Carlos Santos <casantos@redhat.com>
To: hotspot-dev@openjdk.java.net

Hello,

My name is Carlos Santos and I'm a Red Hat software maintenance engineer. Recently a customer noticed that running prelink to generate its cache causes the OpnJDK "jinfo" utility to fail. I'm transcribing below our internal bug report.

Version-Release number of selected component (if applicable):

java-1.7.0-openjdk-1.7.0.51-2.4.4.1.el6_5

How reproducible:

Always

Steps to Reproduce:

1. export LIBSAPROC_DEBUG=1
2. yum install -y java-1.7.0-openjdk-devel
3. javac TCPServer.java (see attachment)
4. prelink -ua
5. java TCPServer &     (take the process pid)
6. jinfo <pid>          (works, lots of information shown)
7. prelink -a
8. jinfo <pid>          (fails, lots of information shown)

Actual results:

Step 8 fails, the message below is shown and the Java vm is kept stopped.

   [1]+  Stopped                 java TCPServer

Expected results:

All steps should succeed.

Additional info:

The problem happens because when prelink runs while the Java VM is running the format of the proc/<pid>/maps file changes to a funky format:

  - Libraries that are to be ignored receive a trailing " (deleted)"
  - Libraries that are provided by the prelink cache receive a trailing ".#prelink#.xyTMjC (deleted)"

This leads jinfo to fail parsing the maps file.

The problem can be fixed by means of the attached patch (java-1.7.0-openjdk-debug-prelink.patch).

Changes in function nfo_fd (file openjdk/hotspot/agent/src/os/linux/ps_proc.c):

  - Discard libraries that must be ignored.
  - Remove the the trailing ".#prelink#.xyTMjC (deleted)" from the names of libraries that must not be discarded
  - Add debug messages about discarded and kept shared objects.

Changes in function add_lib_info_fd (file openjdk/hotspot/agent/src/os/linux/libproc_impl.c):

  - Save library base address at newlib->base. It was being left as null, which led to failures searching for symbols in the shared objects.
  - Fixed/enhanced debug messages.

I attempted to open an account in the OpenJDK bug tracking system to submit the report there but did not find a way. The instructions at

    http://openjdk.java.net/contribute/

say that I need to submit a signed OCA, but I was told that Red Hat employees are already covered by the OCA.

Thanks in advance for your help.

Carlos Santos (casantos)
Senior *Software* Maintenance Engineer
(no, I'm not going to fix your roof)
Red Hat, Inc
                                     
2014-03-26
-- openjdk/hotspot/agent/src/os/linux/libproc_impl.c.orig	2014-01-22 23:37:47.474655768 -0200
+++ openjdk/hotspot/agent/src/os/linux/libproc_impl.c	2014-01-23 16:16:04.718422855 -0200
@@ -156,14 +156,22 @@
 
 lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
    lib_info* newlib;
+   int namelen;
 
    if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
       print_debug("can't allocate memory for lib_info\n");
       return NULL;
    }
 
-   strncpy(newlib->name, libname, sizeof(newlib->name));
-   newlib->base = base;
+   namelen = strlen(libname);
+   if (namelen >= sizeof(newlib->name)) {
+      print_debug("shared object path too long: '%s'\n", libname);
+      free(newlib);
+      return NULL;
+   }
+
+   memcpy(newlib->name, libname, namelen);
+   newlib->name[namelen] = '\0';
 
    if (fd == -1) {
       if ( (newlib->fd = pathmap_open(newlib->name)) < 0) {
@@ -183,11 +191,13 @@
       return NULL;
    }
 
-   newlib->symtab = build_symtab(newlib->fd, libname);
+   newlib->symtab = build_symtab(newlib->fd, newlib->name);
    if (newlib->symtab == NULL) {
       print_debug("symbol table build failed for %s\n", newlib->name);
    }
 
+   newlib->base = base;
+
    // even if symbol table building fails, we add the lib_info.
    // This is because we may need to read from the ELF file for core file
    // address read functionality. lookup_symbol checks for NULL symtab.
@@ -279,7 +289,7 @@
     return err;
   }
 
-  print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);
+  print_debug("thread_db : pthread %x (lwp %d)\n", ti.ti_tid, ti.ti_lid);
 
   if (ptr->callback(ptr->ph, ti.ti_tid, ti.ti_lid) != true)
     return TD_ERR;
--- openjdk/hotspot/agent/src/os/linux/ps_proc.c.orig	2014-01-22 23:37:47.475655795 -0200
+++ openjdk/hotspot/agent/src/os/linux/ps_proc.c	2014-01-23 16:20:44.003824476 -0200
@@ -272,11 +272,22 @@
   }
 
   while(fgets_no_cr(buf, 256, fp)){
-    char * word[6];
-    int nwords = split_n_str(buf, 6, word, ' ', '\0');
-    if (nwords > 5 && find_lib(ph, word[5]) == false) {
+    char * word[7];
+    int nwords = split_n_str(buf, 7, word, ' ', '\0');
+    char* pprelink = (nwords > 5) ? strstr(word[5], ".#prelink#.") : NULL;
+
+    if (pprelink) {
+       *pprelink = '\0';
+       print_debug("keeping shared object '%s' (prelinked, deleted)\n", word[5]);
+    }
+
+    // prelink-deleted libs will have a seventh "(deleted)" word
+    if (nwords > 6 && pprelink == NULL && strcmp(word[6], "(deleted)") == 0) {
+       print_debug("ignoring shared object '%s' (deleted)\n", word[5]);
+    } else if (nwords > 5 && find_lib(ph, word[5]) == false) {
        intptr_t base;
        lib_info* lib;
+       char* pprelink = NULL;
 #ifdef _LP64
        sscanf(word[0], "%lx", &base);
 #else

                                     
2014-03-26
URL:   http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/rev/b19ccfb09cf2
User:  dsamersoff
Date:  2014-06-13 13:02:36 +0000

                                     
2014-06-13



Hardware and Software, Engineered to Work Together