From 70589eb662e528995369cc82a1bebbda3b134cf8 Mon Sep 17 00:00:00 2001 From: kornilova-l Date: Thu, 5 Jul 2018 20:50:24 +0300 Subject: [PATCH 1/3] Run tests with valgrind --- Dockerfile | 1 + .../org/scalanative/bindgen/BindgenSpec.scala | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/Dockerfile b/Dockerfile index 5028a2b..bdbb335 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,7 @@ RUN set -x \ g++ openjdk-8-jdk-headless sbt cmake make curl git \ zlib1g-dev \ libgc-dev libunwind8-dev libre2-dev \ + valgrind \ && rm -rf /var/lib/apt/lists/* ARG LLVM_VERSION=6.0 diff --git a/tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala b/tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala index fab3e2e..c622117 100644 --- a/tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala +++ b/tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala @@ -3,6 +3,7 @@ package org.scalanative.bindgen import java.io.File import org.scalatest.FunSpec import scala.io.Source +import scala.sys.process.{Process, ProcessLogger} class BindgenSpec extends FunSpec { describe("Bindgen") { @@ -32,6 +33,23 @@ class BindgenSpec extends FunSpec { def contentOf(file: File) = Source.fromFile(file).getLines.mkString("\n").trim() + /** + * @return valgrind exit code + */ + def checkMemoryErrors(inputFile: File): Int = { + val cmd = Seq( + "valgrind", + "--leak-check=full", + "--error-exitcode=1", + bindgenPath, + inputFile.getAbsolutePath, + "--name", + "lib", + "--" + ) + Process(cmd).run(ProcessLogger(_ => ())).exitValue() + } + for (input <- inputDirectory.listFiles() if input.getName.endsWith(".h")) { it(s"should generate bindings for ${input.getName}") { val testName = input.getName.replace(".h", "") @@ -43,6 +61,10 @@ class BindgenSpec extends FunSpec { assert(output.exists()) assert(contentOf(output) == contentOf(expected)) } + + it(s"should generate bindings for ${input.getName} without memory errors") { + assert(0 == checkMemoryErrors(input)) + } } } } From 30d61e3eb0c62bac9e1f7fa4b833b3d4c7321d3e Mon Sep 17 00:00:00 2001 From: kornilova-l Date: Fri, 13 Jul 2018 14:55:07 +0300 Subject: [PATCH 2/3] Do not run memory checks in build with llvm 5.0 --- build.sbt | 6 ++++++ scripts/test.sh | 6 +++++- .../test/scala/org/scalanative/bindgen/BindgenSpec.scala | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 2acde02..90284ba 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,12 @@ import scala.sys.process._ addCommandAlias("verify", "; ^test:compile ; ^test ; ^scripted ; docs/makeSite") +addCommandAlias( + "verifyWithoutMemoryChecks", + "; ^test:compile ; " + + "^testOnly -- -z \"should exist\" -z \"correct bindings\" ; " + + "^scripted ; " + + "docs/makeSite") val Versions = new { val scala210 = "2.10.6" diff --git a/scripts/test.sh b/scripts/test.sh index 8f3e3cd..98d8c6f 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -13,4 +13,8 @@ if [[ ! -e bindgen/target/.llvm-version ]] || [[ "$( Date: Fri, 13 Jul 2018 16:01:22 +0300 Subject: [PATCH 3/3] Fix memory leaks --- bindgen/Main.cpp | 1 + bindgen/valgrind-suppressions.txt | 17 +++++++++++++++++ bindgen/visitor/TreeVisitor.cpp | 4 +++- .../org/scalanative/bindgen/BindgenSpec.scala | 3 +++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 bindgen/valgrind-suppressions.txt diff --git a/bindgen/Main.cpp b/bindgen/Main.cpp index 4f877d6..cd56d46 100644 --- a/bindgen/Main.cpp +++ b/bindgen/Main.cpp @@ -61,6 +61,7 @@ int main(int argc, const char *argv[]) { char *resolved = realpath(op.getSourcePathList()[0].c_str(), nullptr); LocationManager locationManager(resolved); + delete [] resolved; IR ir(libName, linkName, objectName, Package.getValue(), locationManager); diff --git a/bindgen/valgrind-suppressions.txt b/bindgen/valgrind-suppressions.txt new file mode 100644 index 0000000..d0b93ce --- /dev/null +++ b/bindgen/valgrind-suppressions.txt @@ -0,0 +1,17 @@ +{ + syscall_param_suppression + Memcheck:Param + __pthread_sigmask(set) + fun:__pthread_sigmask + fun:pthread_sigmask + fun:_ZN4llvm3sys7Process25SafelyCloseFileDescriptorEi + fun:_ZN12_GLOBAL__N_18RealFileD1Ev + fun:_ZN12_GLOBAL__N_18RealFileD0Ev + fun:_ZN5clang3vfs10FileSystem16getBufferForFileERKN4llvm5TwineExbb + fun:_ZN5clang11FileManager16getBufferForFileEPKNS_9FileEntryEbb + fun:_ZNK5clang6SrcMgr12ContentCache9getBufferERNS_17DiagnosticsEngineERKNS_13SourceManagerENS_14SourceLocationEPb + fun:_ZNK5clang13SourceManager9getBufferENS_6FileIDENS_14SourceLocationEPb + fun:_ZN5clang12Preprocessor15EnterSourceFileENS_6FileIDEPKNS_15DirectoryLookupENS_14SourceLocationE + fun:_ZN5clang12Preprocessor19EnterMainSourceFileEv + fun:_ZN5clang8ParseASTERNS_4SemaEbb +} diff --git a/bindgen/visitor/TreeVisitor.cpp b/bindgen/visitor/TreeVisitor.cpp index 06807c6..381f131 100644 --- a/bindgen/visitor/TreeVisitor.cpp +++ b/bindgen/visitor/TreeVisitor.cpp @@ -179,7 +179,9 @@ bool TreeVisitor::VisitVarDecl(clang::VarDecl *varDecl) { std::shared_ptr TreeVisitor::getLocation(clang::Decl *decl) { clang::SourceManager &sm = astContext->getSourceManager(); std::string filename = std::string(sm.getFilename(decl->getLocation())); - std::string path = realpath(filename.c_str(), nullptr); + char *resolved = realpath(filename.c_str(), nullptr); + std::string path = resolved; + delete [] resolved; unsigned lineNumber = sm.getSpellingLineNumber(decl->getLocation()); return std::make_shared(path, lineNumber); diff --git a/tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala b/tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala index 0e5b233..be7d65b 100644 --- a/tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala +++ b/tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala @@ -41,6 +41,9 @@ class BindgenSpec extends FunSpec { "valgrind", "--leak-check=full", "--error-exitcode=1", + "--suppressions=", + new File("bindgen/valgrind-suppressions.txt").getAbsolutePath, + "--show-leak-kinds=definite", bindgenPath, inputFile.getAbsolutePath, "--name",