Please describe what you are doing to trigger the bug:
duplicacy backup -stats
Please describe what you expect to happen (but doesn’t):
Not a panic
Please describe what actually happens (the wrong behaviour):
A panic:
Repository set to /path
Storage set to sftp://...
RSA encryption is enabled
Last backup at revision 213 found
Indexing /path
Parsing filter file /path/.duplicacy/filters
Loaded 8 include/exclude pattern(s)
...
Skipped non-regular file ...
...
Skipped chunk 1 size 2328385, 2.22MB/s 00:24:26 0.0%
Skipped chunk 2 size 2008707, 4.14MB/s 00:13:07 0.1%
Encountered an error (failed to send packet: EOF); retry after 1 second(s)
Skipped chunk 4 size 5357339, 9.25MB/s 00:05:52 0.2%
Skipped chunk 5 size 4623303, 13.65MB/s 00:03:58 0.4%
runtime error: invalid memory address or nil pointer dereference
goroutine 23 [running]:
runtime/debug.Stack(0x41, 0x0, 0x0)
/usr/local/go/src/runtime/debug/stack.go:24 +0x9d
runtime/debug.PrintStack()
/usr/local/go/src/runtime/debug/stack.go:16 +0x22
github.com/gilbertchen/duplicacy/src.CatchLogException()
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/src/duplicacy_log.go:183 +0xee
panic(0x49199e0, 0x5284ef0)
/usr/local/go/src/runtime/panic.go:522 +0x1b5
github.com/gilbertchen/duplicacy/vendor/github.com/pkg/sftp.(*Client).nextID(...)
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/vendor/github.com/pkg/sftp/client.go:178
github.com/gilbertchen/duplicacy/vendor/github.com/pkg/sftp.(*Client).Stat(0x0, 0xc01ff4aa80, 0x29, 0x4796085, 0x28, 0x30, 0xc0207cc930)
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/vendor/github.com/pkg/sftp/client.go:283 +0x3d
github.com/gilbertchen/duplicacy/src.(*SFTPStorage).UploadFile.func1(0x2, 0x2f39000000000068)
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/src/duplicacy_sftpstorage.go:281 +0x5e
github.com/gilbertchen/duplicacy/src.(*SFTPStorage).retry(0xc000284510, 0xc019ca3cd0, 0xc01ff4aa80, 0x29)
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/src/duplicacy_sftpstorage.go:125 +0x70
github.com/gilbertchen/duplicacy/src.(*SFTPStorage).UploadFile(0xc000284510, 0x0, 0xc020adb0e0, 0x48, 0xc02f040000, 0x1f9228, 0x2fa48b, 0x0, 0x0)
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/src/duplicacy_sftpstorage.go:280 +0x1ba
github.com/gilbertchen/duplicacy/src.(*ChunkUploader).Upload(0xc0000cbc70, 0x0, 0xc02af493e0, 0x3, 0xc00003c301)
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/src/duplicacy_chunkuploader.go:138 +0x246
github.com/gilbertchen/duplicacy/src.(*ChunkUploader).Start.func1(0xc0000cbc70, 0x0)
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/src/duplicacy_chunkuploader.go:60 +0x83
created by github.com/gilbertchen/duplicacy/src.(*ChunkUploader).Start
/Users/chgang/zincbox/go/src/github.com/gilbertchen/duplicacy/src/duplicacy_chunkuploader.go:55 +0x48
It seems that the sftp.Client
was set to nil
during a retry then the followed reconnecting failed causing the getSFTPClient()
returns nil
thus the panic.
Proposal of change
Since every function wrapped by retry()
calls getSFTPClient()
, we could ensure the availablity of the client
in retry()
then do this instead:
err = storage.retry(func(client *sftp.Client) error {
// or better, make *sftp.Client an interface to increase the testability.
_, err := client.Stat(fullDir)
return err
})