issue #31 plus continued race detection stuff.

This commit is contained in:
Ian A.Mason 2019-10-22 06:38:16 -07:00
parent 64ececee96
commit fc48468746
4 changed files with 79 additions and 32 deletions

View File

@ -44,6 +44,10 @@ import (
"sync" "sync"
) )
const (
REPLAY_MODE = true
)
type bitcodeToObjectLink struct { type bitcodeToObjectLink struct {
bcPath string bcPath string
objPath string objPath string
@ -51,6 +55,11 @@ type bitcodeToObjectLink struct {
//Compile wraps a call to the compiler with the given args. //Compile wraps a call to the compiler with the given args.
func Compile(args []string, compiler string) (exitCode int) { func Compile(args []string, compiler string) (exitCode int) {
if REPLAY_MODE {
Record(args, compiler)
}
exitCode = 0 exitCode = 0
//in the configureOnly case we have to know the exit code of the compile //in the configureOnly case we have to know the exit code of the compile
//because that is how configure figures out what it can and cannot do. //because that is how configure figures out what it can and cannot do.

View File

@ -61,6 +61,7 @@ type extractionArgs struct {
InputFile string InputFile string
OutputFile string OutputFile string
LinkerName string LinkerName string
LlvmArchiverName string
ArchiverName string ArchiverName string
ArArgs []string ArArgs []string
Extractor func(string) []string Extractor func(string) []string
@ -151,8 +152,9 @@ func resolveTool(defaultPath string, envPath string, usrPath string) (path strin
func parseSwitches() (ea extractionArgs) { func parseSwitches() (ea extractionArgs) {
ea = extractionArgs{ ea = extractionArgs{
LinkerName: "llvm-link", LinkerName: "llvm-link",
ArchiverName: "llvm-ar", LlvmArchiverName: "llvm-ar",
ArchiverName: "ar",
} }
verbosePtr := flag.Bool("v", false, "verbose mode") verbosePtr := flag.Bool("v", false, "verbose mode")
@ -165,9 +167,11 @@ func parseSwitches() (ea extractionArgs) {
outputFilePtr := flag.String("o", "", "the output file") outputFilePtr := flag.String("o", "", "the output file")
archiverNamePtr := flag.String("a", "", "the llvm archiver") llvmArchiverNamePtr := flag.String("a", "", "the llvm archiver (i.e. llvm-ar)")
linkerNamePtr := flag.String("l", "", "the llvm linker") archiverNamePtr := flag.String("r", "", "the system archiver (i.e. ar)")
linkerNamePtr := flag.String("l", "", "the llvm linker (i.e. llvm-link)")
linkArgSizePtr := flag.Int("n", 0, "maximum llvm-link command line size (in bytes)") linkArgSizePtr := flag.Int("n", 0, "maximum llvm-link command line size (in bytes)")
@ -182,7 +186,11 @@ func parseSwitches() (ea extractionArgs) {
ea.LinkArgSize = *linkArgSizePtr ea.LinkArgSize = *linkArgSizePtr
ea.KeepTemp = *keepTempPtr ea.KeepTemp = *keepTempPtr
ea.ArchiverName = resolveTool(ea.ArchiverName, LLVMARName, *archiverNamePtr) if len(*archiverNamePtr) > 0 {
ea.ArchiverName = *archiverNamePtr
}
ea.LlvmArchiverName = resolveTool(ea.LlvmArchiverName, LLVMARName, *llvmArchiverNamePtr)
ea.LinkerName = resolveTool(ea.LinkerName, LLVMLINKName, *linkerNamePtr) ea.LinkerName = resolveTool(ea.LinkerName, LLVMLINKName, *linkerNamePtr)
@ -193,7 +201,7 @@ func parseSwitches() (ea extractionArgs) {
LogInfo("ea.Verbose: %v\n", ea.Verbose) LogInfo("ea.Verbose: %v\n", ea.Verbose)
LogInfo("ea.WriteManifest: %v\n", ea.WriteManifest) LogInfo("ea.WriteManifest: %v\n", ea.WriteManifest)
LogInfo("ea.BuildBitcodeModule: %v\n", ea.BuildBitcodeModule) LogInfo("ea.BuildBitcodeModule: %v\n", ea.BuildBitcodeModule)
LogInfo("ea.ArchiverName: %v\n", ea.ArchiverName) LogInfo("ea.LlvmArchiverName: %v\n", ea.LlvmArchiverName)
LogInfo("ea.LinkerName: %v\n", ea.LinkerName) LogInfo("ea.LinkerName: %v\n", ea.LinkerName)
LogInfo("ea.OutputFile: %v\n", ea.OutputFile) LogInfo("ea.OutputFile: %v\n", ea.OutputFile)
@ -259,7 +267,7 @@ func handleThinArchive(ea extractionArgs) {
var objectFiles []string var objectFiles []string
var bcFiles []string var bcFiles []string
objectFiles = listArchiveFiles(ea.InputFile) objectFiles = listArchiveFiles(ea, ea.InputFile)
LogInfo("handleThinArchive: extractionArgs = %v\nobjectFiles = %v\n", ea, objectFiles) LogInfo("handleThinArchive: extractionArgs = %v\nobjectFiles = %v\n", ea, objectFiles)
@ -309,7 +317,7 @@ func handleThinArchive(ea extractionArgs) {
} }
func listArchiveFiles(inputFile string) (contents []string) { func listArchiveFiles(ea extractionArgs, inputFile string) (contents []string) {
var arArgs []string var arArgs []string
arArgs = append(arArgs, "-t") arArgs = append(arArgs, "-t")
arArgs = append(arArgs, inputFile) arArgs = append(arArgs, inputFile)
@ -322,7 +330,7 @@ func listArchiveFiles(inputFile string) (contents []string) {
return return
} }
func extractFile(archive string, filename string, instance int) bool { func extractFile(ea extractionArgs, archive string, filename string, instance int) bool {
var arArgs []string var arArgs []string
if runtime.GOOS != osDARWIN { if runtime.GOOS != osDARWIN {
arArgs = append(arArgs, "xN") arArgs = append(arArgs, "xN")
@ -344,10 +352,10 @@ func extractFile(archive string, filename string, instance int) bool {
return true return true
} }
func fetchTOC(inputFile string) map[string]int { func fetchTOC(ea extractionArgs, inputFile string) map[string]int {
toc := make(map[string]int) toc := make(map[string]int)
contents := listArchiveFiles(inputFile) contents := listArchiveFiles(ea, inputFile)
for _, item := range contents { for _, item := range contents {
//iam: this is a hack to make get-bc work on libcurl.a //iam: this is a hack to make get-bc work on libcurl.a
@ -399,14 +407,14 @@ func handleArchive(ea extractionArgs) {
} }
//1. fetch the Table of Contents //1. fetch the Table of Contents
toc := fetchTOC(inputFile) toc := fetchTOC(ea, inputFile)
LogDebug("Table of Contents of %v:\n%v\n", inputFile, toc) LogDebug("Table of Contents of %v:\n%v\n", inputFile, toc)
for obj, instance := range toc { for obj, instance := range toc {
for i := 1; i <= instance; i++ { for i := 1; i <= instance; i++ {
if obj != "" && extractFile(inputFile, obj, i) { if obj != "" && extractFile(ea, inputFile, obj, i) {
artifacts := ea.Extractor(obj) artifacts := ea.Extractor(obj)
LogInfo("\t%v\n", artifacts) LogInfo("\t%v\n", artifacts)
@ -469,8 +477,8 @@ func archiveBcFiles(ea extractionArgs, bcFiles []string) {
var args []string var args []string
args = append(args, "rs", absOutputFile) args = append(args, "rs", absOutputFile)
args = append(args, bcFilesInDir...) args = append(args, bcFilesInDir...)
success, err := execCmd(ea.ArchiverName, args, dir) success, err := execCmd(ea.LlvmArchiverName, args, dir)
LogInfo("ea.ArchiverName = %s, args = %v, dir = %s\n", ea.ArchiverName, args, dir) LogInfo("ea.LlvmArchiverName = %s, args = %v, dir = %s\n", ea.LlvmArchiverName, args, dir)
if !success { if !success {
LogFatal("There was an error creating the bitcode archive: %v.\n", err) LogFatal("There was an error creating the bitcode archive: %v.\n", err)
} }

View File

@ -26,11 +26,15 @@ const (
func Record(args []string, compiler string) { func Record(args []string, compiler string) {
logfile := os.Getenv(recording_env_var) logfile := os.Getenv(recording_env_var)
if len(logfile) > 0 { if len(logfile) > 0 {
fp, err := os.OpenFile(logfile, os.O_WRONLY | os.O_APPEND | os.O_CREATE, os.ModePerm) fp, err := os.OpenFile(logfile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.ModePerm)
if err != nil { panic(err) } if err != nil {
panic(err)
}
defer fp.Close() defer fp.Close()
dir, err := os.Getwd() dir, err := os.Getwd()
if err != nil { panic(err) } if err != nil {
panic(err)
}
fp.WriteString(dir) fp.WriteString(dir)
fp.WriteString("\n") fp.WriteString("\n")
fp.WriteString(compiler) fp.WriteString(compiler)
@ -43,23 +47,21 @@ func Record(args []string, compiler string) {
} }
} }
type CompilerCall struct { type CompilerCall struct {
Pwd string Pwd string
Name string Name string
Args []string Args []string
} }
func readCompilerCall(scanner *bufio.Scanner) (call *CompilerCall) { func readCompilerCall(scanner *bufio.Scanner) (call *CompilerCall) {
if scanner.Scan() { if scanner.Scan() {
//got one line, probably an entire call too ... //got one line, probably an entire call too ...
callp := new(CompilerCall) //pass in a local version later, save on mallocing. callp := new(CompilerCall) //pass in a local version later, save on mallocing.
line := scanner.Text() line := scanner.Text()
if len(line) == 0 { if len(line) == 0 {
panic("empty CompilerCall.Pwd") panic("empty CompilerCall.Pwd")
} }
call.Pwd = line callp.Pwd = line
if !scanner.Scan() { if !scanner.Scan() {
panic("non-existant CompilerCall.Name") panic("non-existant CompilerCall.Name")
} }
@ -67,37 +69,42 @@ func readCompilerCall(scanner *bufio.Scanner) (call *CompilerCall) {
if len(line) == 0 { if len(line) == 0 {
panic("empty CompilerCall.Name") panic("empty CompilerCall.Name")
} }
call.Name = line callp.Name = line
for scanner.Scan() { for scanner.Scan() {
line = scanner.Text() line = scanner.Text()
if len(line) == 0 { if len(line) == 0 {
if len(call.Args) == 0 { if len(callp.Args) == 0 {
panic("empty CompilerCall.Args") panic("empty CompilerCall.Args")
} }
break break
} }
call.Args = append(call.Args, line) callp.Args = append(callp.Args, line)
} }
call = callp call = callp
} }
return return
} }
/* /*
* *
*/ */
func Replay(path string) (ok bool) { func Replay(path string) (ok bool) {
fp, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm) fp, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm)
if err != nil { return } if err != nil {
defer fp.Close() return
}
defer fp.Close()
scanner := bufio.NewScanner(fp) scanner := bufio.NewScanner(fp)
for { for {
callp := readCompilerCall(scanner) callp := readCompilerCall(scanner)
if callp == nil { return } if callp == nil {
return
}
ok = replayCall(callp) ok = replayCall(callp)
if !ok { return } if !ok {
return
}
} }
ok = true ok = true
return return
@ -108,7 +115,9 @@ func Replay(path string) (ok bool) {
*/ */
func replayCall(call *CompilerCall) bool { func replayCall(call *CompilerCall) bool {
err := os.Chdir(call.Pwd) err := os.Chdir(call.Pwd)
if err != nil { panic(err) } if err != nil {
panic(err)
}
exitCode := Compile(call.Args, call.Name) exitCode := Compile(call.Args, call.Name)
if exitCode != 0 { if exitCode != 0 {
return false return false

21
tests/replay_test.go Normal file
View File

@ -0,0 +1,21 @@
package test
import (
"github.com/SRI-CSL/gllvm/shared"
"testing"
"fmt"
)
func Test_replay_thttpd(t *testing.T) {
arg := "../data/thttpd_reply.log"
ok := shared.Replay(arg)
if !ok {
t.Errorf("Replay of %v returned %v\n", arg, ok)
} else {
fmt.Println("Replay OK")
}
}