From 71978ec88a2aa8ec92df080a4a6becf623957c81 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Mon, 5 Jun 2017 22:45:11 +0200 Subject: [PATCH] Add "-trace" flag (record execution trace) Uses the runtime/trace functionality. TODO: add to man page. --- cli_args.go | 7 ++++--- internal/exitcodes/exitcodes.go | 3 +++ main.go | 28 ++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/cli_args.go b/cli_args.go index bdce4ec..7f67fe3 100644 --- a/cli_args.go +++ b/cli_args.go @@ -8,12 +8,12 @@ import ( "strconv" "strings" + "github.com/hanwen/go-fuse/fuse" "github.com/rfjakob/gocryptfs/internal/configfile" "github.com/rfjakob/gocryptfs/internal/exitcodes" "github.com/rfjakob/gocryptfs/internal/prefer_openssl" "github.com/rfjakob/gocryptfs/internal/stupidgcm" "github.com/rfjakob/gocryptfs/internal/tlog" - "github.com/hanwen/go-fuse/fuse" ) // argContainer stores the parsed CLI options and arguments @@ -23,7 +23,7 @@ type argContainer struct { longnames, allow_other, ro, reverse, aessiv, nonempty, raw64, noprealloc, speed, hkdf, serialize_reads, forcedecode, hh, info bool masterkey, mountpoint, cipherdir, cpuprofile, extpass, - memprofile, ko, passfile, ctlsock, fsname, force_owner string + memprofile, ko, passfile, ctlsock, fsname, force_owner, trace string // Configuration file name override config string notifypid, scryptn int @@ -33,7 +33,7 @@ type argContainer struct { // _ctlsockFd stores the control socket file descriptor (ctlsock stores the path) _ctlsockFd net.Listener // _forceOwner is, if non-nil, a parsed, validated Owner (as opposed to the string above) - _forceOwner *fuse.Owner + _forceOwner *fuse.Owner } var flagSet *flag.FlagSet @@ -140,6 +140,7 @@ func parseCliOpts() (args argContainer) { flagSet.StringVar(&args.ctlsock, "ctlsock", "", "Create control socket at specified path") flagSet.StringVar(&args.fsname, "fsname", "", "Override the filesystem name") flagSet.StringVar(&args.force_owner, "force_owner", "", "uid:gid pair to coerce ownership") + flagSet.StringVar(&args.trace, "trace", "", "Write execution trace to file") flagSet.IntVar(&args.notifypid, "notifypid", 0, "Send USR1 to the specified process after "+ "successful mount - used internally for daemonization") flagSet.IntVar(&args.scryptn, "scryptn", configfile.ScryptDefaultLogN, "scrypt cost parameter logN. Possible values: 10-28. "+ diff --git a/internal/exitcodes/exitcodes.go b/internal/exitcodes/exitcodes.go index 88e8e5f..209656c 100644 --- a/internal/exitcodes/exitcodes.go +++ b/internal/exitcodes/exitcodes.go @@ -58,6 +58,9 @@ const ( OpenConf = 23 // WriteConf - could not write the gocryptfs.conf WriteConf = 24 + // Profiler - error occoured when trying to write cpu or memory profile or + // execution trace + Profiler = 25 ) // Err wraps an error with an associated numeric exit code diff --git a/main.go b/main.go index 1599d53..13514c1 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "path/filepath" "runtime" "runtime/pprof" + "runtime/trace" "strconv" "strings" "time" @@ -212,9 +213,13 @@ func main() { f, err = os.Create(args.cpuprofile) if err != nil { tlog.Fatal.Println(err) - os.Exit(exitcodes.Init) + os.Exit(exitcodes.Profiler) + } + err = pprof.StartCPUProfile(f) + if err != nil { + tlog.Fatal.Println(err) + os.Exit(exitcodes.Profiler) } - pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } // "-memprofile" @@ -224,7 +229,7 @@ func main() { f, err = os.Create(args.memprofile) if err != nil { tlog.Fatal.Println(err) - os.Exit(exitcodes.Init) + os.Exit(exitcodes.Profiler) } defer func() { pprof.WriteHeapProfile(f) @@ -232,7 +237,22 @@ func main() { return }() } - if args.cpuprofile != "" || args.memprofile != "" { + // "-trace" + if args.trace != "" { + tlog.Info.Printf("Writing execution trace to %s", args.trace) + f, err := os.Create(args.trace) + if err != nil { + tlog.Fatal.Println(err) + os.Exit(exitcodes.Profiler) + } + err = trace.Start(f) + if err != nil { + tlog.Fatal.Println(err) + os.Exit(exitcodes.Profiler) + } + defer trace.Stop() + } + if args.cpuprofile != "" || args.memprofile != "" || args.trace != "" { tlog.Info.Printf("Note: You must unmount gracefully, otherwise the profile file(s) will stay empty!\n") } // "-openssl"