insert panic handlers

This commit is contained in:
James Bardin 2021-10-27 16:33:35 -04:00
parent 3f31533f86
commit d03a037567
12 changed files with 31 additions and 4 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/hashicorp/terraform/internal/backend" "github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/command/views" "github.com/hashicorp/terraform/internal/command/views"
"github.com/hashicorp/terraform/internal/configs/configschema" "github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/states/statemgr" "github.com/hashicorp/terraform/internal/states/statemgr"
"github.com/hashicorp/terraform/internal/terraform" "github.com/hashicorp/terraform/internal/terraform"
"github.com/hashicorp/terraform/internal/tfdiags" "github.com/hashicorp/terraform/internal/tfdiags"
@ -313,6 +314,7 @@ func (b *Local) Operation(ctx context.Context, op *backend.Operation) (*backend.
// Do it // Do it
go func() { go func() {
defer logging.PanicHandler()
defer done() defer done()
defer stop() defer stop()
defer cancel() defer cancel()

View File

@ -7,6 +7,7 @@ import (
"github.com/hashicorp/terraform/internal/backend" "github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/command/views" "github.com/hashicorp/terraform/internal/command/views"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/plans" "github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/states" "github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/states/statefile" "github.com/hashicorp/terraform/internal/states/statefile"
@ -156,6 +157,7 @@ func (b *Local) opApply(
var applyDiags tfdiags.Diagnostics var applyDiags tfdiags.Diagnostics
doneCh := make(chan struct{}) doneCh := make(chan struct{})
go func() { go func() {
defer logging.PanicHandler()
defer close(doneCh) defer close(doneCh)
log.Printf("[INFO] backend/local: apply calling Apply") log.Printf("[INFO] backend/local: apply calling Apply")
applyState, applyDiags = lr.Core.Apply(plan, lr.Config) applyState, applyDiags = lr.Core.Apply(plan, lr.Config)

View File

@ -6,6 +6,7 @@ import (
"log" "log"
"github.com/hashicorp/terraform/internal/backend" "github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/plans" "github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/plans/planfile" "github.com/hashicorp/terraform/internal/plans/planfile"
"github.com/hashicorp/terraform/internal/states/statefile" "github.com/hashicorp/terraform/internal/states/statefile"
@ -79,6 +80,7 @@ func (b *Local) opPlan(
var planDiags tfdiags.Diagnostics var planDiags tfdiags.Diagnostics
doneCh := make(chan struct{}) doneCh := make(chan struct{})
go func() { go func() {
defer logging.PanicHandler()
defer close(doneCh) defer close(doneCh)
log.Printf("[INFO] backend/local: plan calling Plan") log.Printf("[INFO] backend/local: plan calling Plan")
plan, planDiags = lr.Core.Plan(lr.Config, lr.InputState, lr.PlanOpts) plan, planDiags = lr.Core.Plan(lr.Config, lr.InputState, lr.PlanOpts)

View File

@ -7,6 +7,7 @@ import (
"os" "os"
"github.com/hashicorp/terraform/internal/backend" "github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/states" "github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/states/statemgr" "github.com/hashicorp/terraform/internal/states/statemgr"
"github.com/hashicorp/terraform/internal/tfdiags" "github.com/hashicorp/terraform/internal/tfdiags"
@ -77,6 +78,7 @@ func (b *Local) opRefresh(
var refreshDiags tfdiags.Diagnostics var refreshDiags tfdiags.Diagnostics
doneCh := make(chan struct{}) doneCh := make(chan struct{})
go func() { go func() {
defer logging.PanicHandler()
defer close(doneCh) defer close(doneCh)
newState, refreshDiags = lr.Core.Refresh(lr.Config, lr.InputState, lr.PlanOpts) newState, refreshDiags = lr.Core.Refresh(lr.Config, lr.InputState, lr.PlanOpts)
log.Printf("[INFO] backend/local: refresh calling Refresh") log.Printf("[INFO] backend/local: refresh calling Refresh")

View File

@ -18,6 +18,7 @@ import (
"github.com/hashicorp/terraform-svchost/disco" "github.com/hashicorp/terraform-svchost/disco"
"github.com/hashicorp/terraform/internal/backend" "github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/configs/configschema" "github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/states/remote" "github.com/hashicorp/terraform/internal/states/remote"
"github.com/hashicorp/terraform/internal/states/statemgr" "github.com/hashicorp/terraform/internal/states/statemgr"
"github.com/hashicorp/terraform/internal/terraform" "github.com/hashicorp/terraform/internal/terraform"
@ -755,6 +756,7 @@ func (b *Remote) Operation(ctx context.Context, op *backend.Operation) (*backend
// Do it. // Do it.
go func() { go func() {
defer logging.PanicHandler()
defer done() defer done()
defer stop() defer stop()
defer cancel() defer cancel()

View File

@ -13,6 +13,7 @@ import (
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/backend" "github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/plans" "github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/terraform" "github.com/hashicorp/terraform/internal/terraform"
) )
@ -464,6 +465,8 @@ func (b *Remote) confirm(stopCtx context.Context, op *backend.Operation, opts *t
result := make(chan error, 2) result := make(chan error, 2)
go func() { go func() {
defer logging.PanicHandler()
// Make sure we cancel doneCtx before we return // Make sure we cancel doneCtx before we return
// so the input command is also canceled. // so the input command is also canceled.
defer cancel() defer cancel()

View File

@ -17,6 +17,7 @@ import (
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
version "github.com/hashicorp/go-version" version "github.com/hashicorp/go-version"
"github.com/hashicorp/terraform/internal/backend" "github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/plans" "github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/tfdiags" "github.com/hashicorp/terraform/internal/tfdiags"
) )
@ -319,6 +320,8 @@ in order to capture the filesystem context the remote workspace expects:
// cancellable after that period, we attempt to cancel it. // cancellable after that period, we attempt to cancel it.
if lockTimeout := op.StateLocker.Timeout(); lockTimeout > 0 { if lockTimeout := op.StateLocker.Timeout(); lockTimeout > 0 {
go func() { go func() {
defer logging.PanicHandler()
select { select {
case <-stopCtx.Done(): case <-stopCtx.Done():
return return

View File

@ -22,6 +22,7 @@ import (
"github.com/hashicorp/terraform-svchost/disco" "github.com/hashicorp/terraform-svchost/disco"
"github.com/hashicorp/terraform/internal/command/cliconfig" "github.com/hashicorp/terraform/internal/command/cliconfig"
"github.com/hashicorp/terraform/internal/httpclient" "github.com/hashicorp/terraform/internal/httpclient"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/terraform" "github.com/hashicorp/terraform/internal/terraform"
"github.com/hashicorp/terraform/internal/tfdiags" "github.com/hashicorp/terraform/internal/tfdiags"
@ -450,6 +451,7 @@ func (c *LoginCommand) interactiveGetTokenByCode(hostname svchost.Hostname, cred
}), }),
} }
go func() { go func() {
defer logging.PanicHandler()
err := server.Serve(listener) err := server.Serve(listener)
if err != nil && err != http.ErrServerClosed { if err != nil && err != http.ErrServerClosed {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(

View File

@ -12,7 +12,6 @@ import (
// This output is shown if a panic happens. // This output is shown if a panic happens.
const panicOutput = ` const panicOutput = `
!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!
Terraform crashed! This is always indicative of a bug within Terraform. Terraform crashed! This is always indicative of a bug within Terraform.
@ -24,11 +23,11 @@ shown below, and any additional information which may help replicate the issue.
[1]: https://github.com/hashicorp/terraform/issues [1]: https://github.com/hashicorp/terraform/issues
!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!
` `
// PanicHandler is called to recover from an internal panic in Terraform, and // PanicHandler is called to recover from an internal panic in Terraform, and
// is intended to replace the standard stack trace with a more user friendly // augments the standard stack trace with a more user friendly error message.
// error message.
// PanicHandler must be called as a defered function. // PanicHandler must be called as a defered function.
func PanicHandler() { func PanicHandler() {
recovered := recover() recovered := recover()

View File

@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs" "github.com/hashicorp/terraform/internal/configs"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/providers" "github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/provisioners" "github.com/hashicorp/terraform/internal/provisioners"
"github.com/hashicorp/terraform/internal/states" "github.com/hashicorp/terraform/internal/states"
@ -264,6 +265,8 @@ func (c *Context) watchStop(walker *ContextGraphWalker) (chan struct{}, <-chan s
done := c.runContext.Done() done := c.runContext.Done()
go func() { go func() {
defer logging.PanicHandler()
defer close(wait) defer close(wait)
// Wait for a stop or completion // Wait for a stop or completion
select { select {

View File

@ -4,6 +4,7 @@ import (
"log" "log"
"strings" "strings"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/tfdiags" "github.com/hashicorp/terraform/internal/tfdiags"
"github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/addrs"
@ -39,6 +40,10 @@ func (g *Graph) walk(walker GraphWalker) tfdiags.Diagnostics {
// Walk the graph. // Walk the graph.
walkFn := func(v dag.Vertex) (diags tfdiags.Diagnostics) { walkFn := func(v dag.Vertex) (diags tfdiags.Diagnostics) {
// the walkFn is called asynchronously, and needs to be recovered
// separately in the case of a panic.
defer logging.PanicHandler()
log.Printf("[TRACE] vertex %q: starting visit (%T)", dag.VertexName(v), v) log.Printf("[TRACE] vertex %q: starting visit (%T)", dag.VertexName(v), v)
defer func() { defer func() {

View File

@ -59,6 +59,8 @@ func main() {
} }
func realMain() int { func realMain() int {
defer logging.PanicHandler()
var err error var err error
tmpLogPath := os.Getenv(envTmpLogPath) tmpLogPath := os.Getenv(envTmpLogPath)