2014-06-21 6 views
5

Ich versuche, zusammen mit dem Tutorial here zu folgen und in einen segfault zu laufen. Der folgende Code funktioniert in dem Sinne, dass es einen Modulkopf auf output.ll druckt, aber es segfaults irgendwo auch.Segfault in Haskell LLVM-Generelle Codegenerierung

module Main where 

import Control.Monad.Error 
import LLVM.General.Module 
import LLVM.General.Context 
import qualified LLVM.General.AST as AST 

--Create and write out an empty LLVM module 
main :: IO() 
main = writeModule (AST.defaultModule { AST.moduleName = "myModule" }) 

outputFile :: File 
outputFile = File "output.ll" 

writeModule :: AST.Module -> IO() 
writeModule mod = withContext $ (\context -> 
        liftError $ withModuleFromAST context mod (\m -> 
         liftError $ writeLLVMAssemblyToFile outputFile m)) 

--perform the action, or fail on an error 
liftError :: ErrorT String IO a -> IO a 
liftError = runErrorT >=> either fail return 

Ich vermute, das auf den folgenden Hinweis aus dem verknüpften Tutorial zusammenhängt:

Es ist sehr wichtig, daran zu erinnern, nicht Ressourcen zu übergeben oder versuchen, außerhalb der Halterung zu verwenden, da dies führen undefiniertes Verhalten und/oder segfaults.

Ich denke in diesem Zusammenhang wird die "Klammer" durch die withContext Funktion implementiert, die es scheint, als ob alles behandelt werden sollte.

Wenn ich die Definition von writeModule zu

ändern
writeModule mod = do assembly <- (withContext $ (\context -> 
         liftError $ withModuleFromAST context mod moduleLLVMAssembly)) 
        putStrLn assembly 

, dass anstelle von Schreiben in eine Datei, die ich aus der String-Darstellung des LLVM Montage nur drucken, wird kein segfault geworfen.

Hat jemand Erfahrung mit diesen Bindungen? Ich bin auch daran interessiert, die Fehlerfälle für die von mir zitierte Warnung zu kennen. Das heißt, wie würde man "vergessen", keine Ressourcen außerhalb der Klammer zu verwenden? Alle Funktionen, die eine Context erfordern, benötigen einen. Ist diese Art von Ressourcen-Scoping-Problem nicht genau das, was Haskell gut für Sie handhaben kann?

Versionsinformationen:

  • llvm-general-3.4.3.0
  • LLVM version 3.4
  • Default target: x86_64-apple-darwin13.2.0
+0

Ich denke, meine Intuition über die Bracketing Zeug wird von der Seite auf der [Klammer Muster] (http: //www.haskell.org/haskellwiki/Bracket_pattern), die besagt "Im Allgemeinen sind in den Bibliotheken viele Funktionen mit Namen beginnend mit' mit' definiert, um verschiedene Ressourcen auf diese Weise zu verwalten. " – Cardano

+0

Ohne Bezug zu Ihrer Frage: Warum wickeln Sie alles in 'writeModule' in einen trivialen' do' Block? – dfeuer

+0

Whoops, das ist wahrscheinlich ein Bearbeitungsfehler. – Cardano

Antwort

3

Es würde helfen, wenn Sie Ihre LLVM und Kabalen Umgebung geteilt ist LLVM berüchtigt für mit sich selbst rückwärts unvereinbar ist, so Möglicherweise liegt ein Problem bei der Verwendung der neuesten Versionen der Bindungen vor.

Hinter den Kulissen writeLLVMAssemblyToFile verwendet einen C++ - Aufruf, um die Datei IO-Operation zu tun, und ich spekuliere, dass es einen Verweis auf das LLVM-Modul als Ergebnis der Finalisierung der Dateiressource hält.

Versuchen Sie, das Modul zu einem String unter Verwendung moduleString zu rendern und dann nur in die IO-Monade zu heben, um writeFile von Haskell aufzurufen, anstatt durch C++ zum Schreiben zu gehen.

import LLVM.General.Context 
import LLVM.General.Module as Mod 
import qualified LLVM.General.AST as AST 

import Control.Monad.Error 

main :: IO() 
main = do 
    writeModule (AST.defaultModule { AST.moduleName = "myModule" }) 
    return() 

writeModule :: AST.Module -> IO (Either String()) 
writeModule ast = 
    withContext $ \ctx -> 
    runErrorT $ withModuleFromAST ctx ast $ \m -> do 
     asm <- moduleString m 
     liftIO $ writeFile "output.ll" asm 

Die Bindungen können nach wie vor eher spröde in meiner Erfahrung, sollten Sie auf der issue tracker fragen, ob das Problem weiterhin besteht.

EDIT: Dies ist eine Problemumgehung für eine alte Version, die nachträglich behoben wurde. Siehe: https://github.com/bscarlet/llvm-general/issues/109