2016-11-12 6 views
3

Ich bin neu in Golang und Programmierung.Golang Segmentierung Fehler (Core Dumped)

Ich habe ein kleines Programm geschrieben, das Dateien verschiebt, die einer Regex von einem Verzeichnis zu einem anderen entsprechen.

Das Programm läuft erfolgreich auf Ubuntu 16.04 und auf einem Centos 6.8 (Final)

Auf einer bestimmte Centos Maschine (ich weiß nicht, die genaue Version der, dass man. Ich weiß es 6. ist? Und sie niedriger als 6,8) ist, erhalte ich:

Segmentation fault (core dumped)

Meine Forschung zeigt, dass dieser Fehler tritt auf, wenn das OS mir Speicher zuzugreifen nicht gestattet.

Kann mir jemand sagen, wo es in meinem Code schief geht? Bitte weisen Sie auch auf schlechte Praktiken hin, wenn Sie welche sehen.

package main 

import (
    "flag" 
    "fmt" 
    "log" 
    "os" 
    "regexp" 
    "strings" 
) 

func main() { 

    batch := flag.Int("batch", 0, "the amount of files to be processed") 
    pattern := flag.String("pattern", "", "string pattern to be matched") 
    dir := flag.Int("dir", 0, "key from strings.Split(pattern, '')") 
    confirm := flag.String("move", "no", "flags if program should move files") 

    flag.Parse() 

    d, err := os.Open(".") 
    if err != nil { 
     log.Fatal("Could not open directory. ", err) 
    } 

    files, err := d.Readdir(*batch) 
    if err != nil { 
     log.Fatal("Could not read directory. ", err) 
    } 

    for _, file := range files { 
     fname := file.Name() 
     match, err := regexp.Match(*pattern, []byte(fname)) 
     if err != nil { 
      log.Fatal(err) 
     } 
     if match == true { 

      s := strings.Split(fname, "_") 
      dest := s[*dir] 

      switch *confirm { 
      case "no": 
       fmt.Printf(" %s matches %s\n Dir name = %s\n -----------------------\n", fname, *pattern, dest) 

      case "yes": 
       //all directories are expected to be a number. 
       //terminate execution if directory doesn't match regex 
       if match, err := regexp.Match("[0-9]", []byte(dest)); match == false { 
        log.Fatalf("Expected directory name does not match prepared directory.\n Expected dir name must be a number (regex [0-9]) | Current dir name is: %s\n", dest) 
        if err != nil { 
         log.Fatal(err) 
        } 
       } 

       //check if direcotry exists. create it if it doesn't 
       if _, err := os.Stat(dest); os.IsNotExist(err) { 
        err = os.Mkdir(dest, 0777) 
        if err != nil { 
         log.Fatal("Could not create directory. ", err) 
        } 
       } 
       err = os.Rename(fname, fmt.Sprintf("%s/%s", dest, fname)) 
       if err != nil { 
        log.Fatal("Could not move file. ", err) 
       } 
       fmt.Printf("Moved %s to %s\n", fname, dest) 
      } 
     } 
    } 
    fmt.Println("Exit") 
} 
+0

Hatte einen etwas ähnlichen Fall (https://github.com/mhausenblas/cruf/issues/1) und habe nie herausgefunden, was es war. Eine Hypothese war, dass Cross-Compiling die Ursache war (seit ich auf MacOS gebaut habe). –

+1

Bitte kompilieren Sie das Programm mit der Option -ldflags "-w" (z. B. go-build -ldflags "-w" prog.go) und versuchen Sie, es in gdb (gdb prog) zu entpacken und es auszuführen (run). Wenn ein Problem auftritt, zeigen Sie uns in dieser Zeit backtrace (bt). – lofcek

+0

Ich habe das Programm auf der problematischen Maschine gebaut und jetzt funktioniert es. – user3017869

Antwort

0

Meine erste Vermutung wäre, Sie überlauf die Grenzen des 's' Array:

dest := s[*dir] 

ich einige Sicherheitsüberprüfungen hinzugefügt (siehe [Added]):

package main 

import (
    "flag" 
    "fmt" 
    "log" 
    "os" 
    "regexp" 
    "strings" 
) 

func main() { 
    batch := flag.Int("batch", 0, "the amount of files to be processed") 
    pattern := flag.String("pattern", "", "string pattern to be matched") 
    dir := flag.Int("dir", 0, "key from strings.Split(pattern, '')") 
    confirm := flag.String("move", "no", "flags if program should move files") 

    flag.Parse() 

    d, err := os.Open(".") 
    if err != nil { 
     log.Fatal("Could not open directory. ", err) 
    } 
    defer d.Close() // [Added] probably not needed if a directory but doesn't hurt 

    files, err := d.Readdir(*batch) 
    if err != nil { 
     log.Fatal("Could not read directory. ", err) 
    } 

    for _, file := range files { 
     fname := file.Name() 
     match, err := regexp.Match(*pattern, []byte(fname)) 
     if err != nil { 
      log.Fatal(err) 
     } 
     if match == true { 
      s := strings.Split(fname, "_") 

      // [Added] Sanity check *dir index before using 
      if *dir >= len(s) { 
       log.Fatalf("dir is out of range: dir=%d len(s)=%d\n", *dir, len(s)) 
      } 

      dest := s[*dir] 

      switch *confirm { 
      case "no": 
       fmt.Printf(" %s matches %s\n Dir name = %s\n -----------------------\n", fname, *pattern, dest) 

      case "yes": 
       //all directories are expected to be a number. 
       //terminate execution if directory doesn't match regex 
       if match, err := regexp.Match("[0-9]", []byte(dest)); match == false { 
        log.Fatalf("Expected directory name does not match prepared directory.\n Expected dir name must be a number (regex [0-9]) | Current dir name is: %s\n", dest) 
        if err != nil { 
         log.Fatal(err) 
        } 
       } 

       //check if direcotry exists. create it if it doesn't 
       if _, err := os.Stat(dest); os.IsNotExist(err) { 
        err = os.Mkdir(dest, 0777) 
        if err != nil { 
         log.Fatal("Could not create directory. ", err) 
        } 
       } 
       err = os.Rename(fname, fmt.Sprintf("%s/%s", dest, fname)) 
       if err != nil { 
        log.Fatal("Could not move file. ", err) 
       } 
       fmt.Printf("Moved %s to %s\n", fname, dest) 

       // [Added]: Make sure to handle non 'yes/no' answers 
      default: 
       log.Fatalf("confirm is invalid '%s'\n", *confirm) 
      } 
     } 
    } 
    fmt.Println("Exit") 
} 

Nicht sicher, was Sie in das Programm eingeben, aber nichts anderes, was ich sehen kann, würde einen Segmentierungsfehler verursachen.

Verwandte Themen