|
| 1 | +# Contribution Guidelines |
| 2 | + |
| 3 | +As all source{d} projects, this project follows the |
| 4 | +[source{d} Contributing Guidelines](https://github.com/src-d/guide/blob/master/engineering/documents/CONTRIBUTING.md). |
| 5 | + |
| 6 | + |
| 7 | +# Developer documentation |
| 8 | + |
| 9 | +This section has more extended documentation for a brave developer willing to |
| 10 | +contribute by diving into and debugging the native glue code in `src/main/native`. |
| 11 | + |
| 12 | +## Build libuast with debug symbols |
| 13 | +This is not strictly necessary, but will help you to navigate though the stack-traces. |
| 14 | + |
| 15 | +Clone [libuast](https://github.com/bblfsh/libuast) locally and from the project root do: |
| 16 | +``` |
| 17 | +CGO_ENABLED=1 go build -buildmode=c-archive -gcflags "-N -l" -o=libuast.a ./src |
| 18 | +mv libuast.a ../scala-client/src/main/resources/libuast |
| 19 | +``` |
| 20 | + |
| 21 | +Sadly, on non-linux OSes you might still experience issues with CGO due to https://github.com/golang/go/issues/5221. |
| 22 | + |
| 23 | + |
| 24 | +## Build libscalauast with debug symbols |
| 25 | +Compiler flags need to be `-g -O0` used instead of `-fPIC -O2` that is used for releases: |
| 26 | +``` |
| 27 | +$ g++ -shared -Wall -g -std=c++11 -O0 \ |
| 28 | + -I/usr/include \ |
| 29 | + "-I${JAVA_HOME}/include" \ |
| 30 | + "-I${JAVA_HOME}/include/${platform}" \ |
| 31 | + -Isrc/main/resources/libuast \ |
| 32 | + -o "src/main/resources/lib/libscalauast${platform_ext}" \ |
| 33 | + src/main/native/org_bblfsh_client_v2_libuast_Libuast.cc \ |
| 34 | + src/main/native/jni_utils.cc src/main/resources/libuast/libuast.a |
| 35 | +``` |
| 36 | + |
| 37 | +## Run a single test under debugger |
| 38 | +To run a single test from CLI one can: |
| 39 | + |
| 40 | +``` |
| 41 | +./sbt "testOnly org.bblfsh.client.v2.libuast.IteratorNativeTest -- -z \"Native UAST iterator should return non-empty results on decoded objects\"" |
| 42 | +``` |
| 43 | + |
| 44 | +When using `lldb`, this would become a bit more involved as the classpath needs to be |
| 45 | +manually setup for `java` executable: |
| 46 | + |
| 47 | +``` |
| 48 | +PATH="/usr/bin:$PATH" lldb -- java -ea -Xcheck:jni -Djava.library.path=src/main/resources -cp "target/classes:target/test-classes:src/main/resources:${HOME}/.ivy2/cache/org.scalatest/scalatest_2.11/bundles/scalatest_2.11-3.0.1.jar:${HOME}/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.11.jar:${HOME}/.ivy2/cache/org.scala-lang.modules/scala-xml_2.11/bundles/scala-xml_2.11-1.0.5.jar:${HOME}/.ivy2/cache/org.scalactic/scalactic_2.11/bundles/scalactic_2.11-3.0.1.jar:${HOME}/.ivy2/cache/commons-io/commons-io/jars/commons-io-2.5.jar:build/bblfsh-client-assembly-2.0.0-SNAPSHOT.jar:target/*" \ |
| 49 | + org.scalatest.tools.Runner \ |
| 50 | + -s org.bblfsh.client.v2.libuast.IteratorNativeTest \ |
| 51 | + -z "Native UAST iterator" \ |
| 52 | + -f iterator-native-test.txt |
| 53 | +``` |
| 54 | +Actual test output will be saved in `iterator-native-test.txt`. |
| 55 | + |
| 56 | +## When inside the debugger |
| 57 | + |
| 58 | +This is somhow `lldb` specific, but the idea will be the same in GDB. |
| 59 | +To load the debug symbols do: |
| 60 | + |
| 61 | +``` |
| 62 | +run |
| 63 | +continue |
| 64 | +continue |
| 65 | +target symbols add src/main/resources/lib/libscalauast.dylib.dSYM |
| 66 | +``` |
| 67 | + |
| 68 | +If that does not load the symbols, you have to make sure libscalauast library has |
| 69 | +already been loaded to the process by `target modules list`. |
| 70 | +On rare occasions, the library can be loaded but the symbols will still refuse |
| 71 | +to load, it most probably mean that the library is from a different fs path. |
| 72 | +Stop the debugger and do `rm -rf ./target/classes/lib/libscalauast.dylib*` |
| 73 | + |
| 74 | +To actually debug, set a breakpoint like: |
| 75 | +``` |
| 76 | +br s -r Java_org_bblfsh_client_v2_libuast_Libuast_00024UastIter_nativeNext |
| 77 | +run |
| 78 | +c |
| 79 | +``` |
| 80 | + |
| 81 | +Check the stack trace and print values do: |
| 82 | +``` |
| 83 | +bt |
| 84 | +p *node |
| 85 | +``` |
| 86 | + |
| 87 | +Check [official LLDB documentation](https://lldb.llvm.org/use/map.html) for more |
| 88 | +use cases and instructions. |
| 89 | + |
| 90 | +## More tips on JNI debugging |
| 91 | + |
| 92 | +A small curated list of really useful resources on Go&JNI debugging: |
| 93 | + - https://github.com/facebook/rocksdb/wiki/JNI-Debugging |
| 94 | + - https://gist.github.com/dwbuiten/c9865c4afb38f482702e#2-debugging-tips |
| 95 | + - Go and LLDB http://ribrdb.github.io/lldb/ |
| 96 | + |
| 97 | +## JNI details |
| 98 | + |
| 99 | +Here are some resources to understand the JNI machinery and it's best practices: |
| 100 | + - https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html |
| 101 | + - https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html |
| 102 | + - https://developer.android.com/training/articles/perf-jni |
| 103 | + - https://www.artima.com/insidejvm/ed2/jvm9.html |
| 104 | + - http://blog.jamesdbloom.com/JVMInternals.html |
0 commit comments