Graal: Debug-info not working with valgrind and possibly other tools

Created on 12 Aug 2020  ·  3Comments  ·  Source: oracle/graal

Describe the issue
Apparently since #2700 I have been abusing the comp_dir dwarf attribute (with the blessings of gdb).

According to the dwarf spec:

A DW_AT_comp_dir attribute whose value is a null-terminated string containing the current working directory of the compilation command that produced this compilation unit in whatever form makes sense for the host system.

The suggested form for the value of the DW_AT_comp_dir attribute on UNIX systems is “hostname:pathname”. If no hostname is available, the suggested form is “:pathname”.

There is no mention about supporting multiple directories in comp_dir as a colon separated list, e.g. sources/jdk:sources/graal.

As a result, some programs like valgrind produce corrupted output when fed such strings in comp_dir (see https://github.com/graalvm/mandrel/issues/103).

Steps to reproduce the issue

cd /tmp
cat <<EOF >Main.java
public class Main {
    public static void main(String[] args) {
       if (args.length<1) {
           System.out.println("Hello, Sailor!");
       } else {
           System.out.println("Hello, "+args[0]);
       }
    }
}
EOF
javac Main.java
rm -rf sources
native-image -g Main
valgrind --tool=callgrind ./main

Now if we inspect the output file of callgrind we see a _weird_ entry for Utf8.java:

$ grep "Utf8.java" callgrind.out.*
fi=(328) sources/graal:sources/jdk/com/oracle/svm/core/util/Utf8.java

while the file is under:

$ find sources -name "Utf8.java"  
sources/graal/com/oracle/svm/core/util/Utf8.java

This is happening because valgrind (correctly) expects comp_dir to contain a single directory (instead of colon separated list of directories) and proceeds to append to the file path to that directory (see https://sourceware.org/git/?p=valgrind.git;a=blob;f=coregrind/m_debuginfo/readdwarf3.c;h=c4d529bc6db74c75410b8e118453881588fb9036;hb=refs/heads/master#l1781)

Describe GraalVM and your environment:

  • GraalVM version: 2743b68d018567d2dc03d0f7738bd6370ae8fe23
  • JDK major version: 11
  • OS: Fedora 32
  • Architecture: AMD64
bug native-image

All 3 comments

@adinn removing the jdk, graal and src subdirectories from the sources directoriy simplifies the code a lot and also fixes the issue (we can then just set the comp_dir to point to the DebugInfoSourceCacheRoot).

A potential issue I see with this approach is that we might get conflicts (files with same paths) in the sources directory, but I believe we should anyway detect such conflicts and resolve them even in the current state (with the subdirectories present).

Proof-of-concept patch:

diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/sources/SourceCache.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/sources/SourceCache.java
index 55c8e3bb060..0bca294cfe5 100644
--- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/sources/SourceCache.java
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/sources/SourceCache.java
@@ -72,7 +72,7 @@ public abstract class SourceCache {
      * Create some flavour of source cache.
      */
     protected SourceCache() {
-        basePath = SubstrateOptions.getDebugInfoSourceCacheRoot().resolve(getType().getSubdir());
+        basePath = SubstrateOptions.getDebugInfoSourceCacheRoot();
         srcRoots = new ArrayList<>();
     }

diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/sources/SourceManager.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/sources/SourceManager.java
index 1f5b4cbb5d9..a113e92b2df 100644
--- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/sources/SourceManager.java
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/sources/SourceManager.java
@@ -81,7 +81,7 @@ public class SourceManager {
                         path = path.resolve(fileName);
                     }
                 } else {
-                    verifiedCachePaths.put(resolvedType, SubstrateOptions.getDebugInfoSourceCacheRoot().resolve(sourceCacheType.getSubdir()));
+                    verifiedCachePaths.put(resolvedType, SubstrateOptions.getDebugInfoSourceCacheRoot());
                 }
             }
         }

With the above patch valgrind generates correct paths:

$ grep "Utf8.java" callgrind.out.*
fi=(318) sources/com/oracle/svm/core/util/Utf8.java
$ find sources -name "Utf8.java"                                               
sources/com/oracle/svm/core/util/Utf8.java

@olpaw Please assign this issue to me.

@zakkak

removing the jdk, graal and src subdirectories from the sources directoriy simplifies the code a lot and also fixes the issue (we can then just set the comp_dir to point to the DebugInfoSourceCacheRoot).

Yes, that sounds like it is probably going to be the best solution to this issue.

A potential issue I see with this approach is that we might get conflicts (files with same paths) in the sources directory, but I believe we should anyway detect such conflicts and resolve them even in the current state (with the subdirectories present).

I think that is probably unlikely. Let's go with your proposed patch. n.b. you'll need to get rid of the getSubDir method on enum SourceCacheType.

Was this page helpful?
0 / 5 - 0 ratings