Giter Club home page Giter Club logo

go-spew's Introduction

go-spew

Build Status ISC License Coverage Status

Go-spew implements a deep pretty printer for Go data structures to aid in debugging. A comprehensive suite of tests with 100% test coverage is provided to ensure proper functionality. See test_coverage.txt for the gocov coverage report. Go-spew is licensed under the liberal ISC license, so it may be used in open source or commercial projects.

If you're interested in reading about how this package came to life and some of the challenges involved in providing a deep pretty printer, there is a blog post about it here.

Documentation

GoDoc

Full go doc style documentation for the project can be viewed online without installing this package by using the excellent GoDoc site here: http://godoc.org/github.com/davecgh/go-spew/spew

You can also view the documentation locally once the package is installed with the godoc tool by running godoc -http=":6060" and pointing your browser to http://localhost:6060/pkg/github.com/davecgh/go-spew/spew

Installation

$ go get -u github.com/davecgh/go-spew/spew

Quick Start

Add this import line to the file you're working in:

import "github.com/davecgh/go-spew/spew"

To dump a variable with full newlines, indentation, type, and pointer information use Dump, Fdump, or Sdump:

spew.Dump(myVar1, myVar2, ...)
spew.Fdump(someWriter, myVar1, myVar2, ...)
str := spew.Sdump(myVar1, myVar2, ...)

Alternatively, if you would prefer to use format strings with a compacted inline printing style, use the convenience wrappers Printf, Fprintf, etc with %v (most compact), %+v (adds pointer addresses), %#v (adds types), or %#+v (adds types and pointer addresses):

spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)

Debugging a Web Application Example

Here is an example of how you can use spew.Sdump() to help debug a web application. Please be sure to wrap your output using the html.EscapeString() function for safety reasons. You should also only use this debugging technique in a development environment, never in production.

package main

import (
    "fmt"
    "html"
    "net/http"

    "github.com/davecgh/go-spew/spew"
)

func handler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/html")
    fmt.Fprintf(w, "Hi there, %s!", r.URL.Path[1:])
    fmt.Fprintf(w, "<!--\n" + html.EscapeString(spew.Sdump(w)) + "\n-->")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Sample Dump Output

(main.Foo) {
 unexportedField: (*main.Bar)(0xf84002e210)({
  flag: (main.Flag) flagTwo,
  data: (uintptr) <nil>
 }),
 ExportedField: (map[interface {}]interface {}) {
  (string) "one": (bool) true
 }
}
([]uint8) {
 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |
 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0|
 00000020  31 32                                             |12|
}

Sample Formatter Output

Double pointer to a uint8:

	  %v: <**>5
	 %+v: <**>(0xf8400420d0->0xf8400420c8)5
	 %#v: (**uint8)5
	%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5

Pointer to circular struct with a uint8 field and a pointer to itself:

	  %v: <*>{1 <*><shown>}
	 %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
	 %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
	%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}

Configuration Options

Configuration of spew is handled by fields in the ConfigState type. For convenience, all of the top-level functions use a global state available via the spew.Config global.

It is also possible to create a ConfigState instance that provides methods equivalent to the top-level functions. This allows concurrent configuration options. See the ConfigState documentation for more details.

* Indent
	String to use for each indentation level for Dump functions.
	It is a single space by default.  A popular alternative is "\t".

* MaxDepth
	Maximum number of levels to descend into nested data structures.
	There is no limit by default.

* DisableMethods
	Disables invocation of error and Stringer interface methods.
	Method invocation is enabled by default.

* DisablePointerMethods
	Disables invocation of error and Stringer interface methods on types
	which only accept pointer receivers from non-pointer variables.  This option
	relies on access to the unsafe package, so it will not have any effect when
	running in environments without access to the unsafe package such as Google
	App Engine or with the "safe" build tag specified.
	Pointer method invocation is enabled by default.

* DisablePointerAddresses
	DisablePointerAddresses specifies whether to disable the printing of
	pointer addresses. This is useful when diffing data structures in tests.

* DisableCapacities
	DisableCapacities specifies whether to disable the printing of capacities
	for arrays, slices, maps and channels. This is useful when diffing data
	structures in tests.

* ContinueOnMethod
	Enables recursion into types after invoking error and Stringer interface
	methods. Recursion after method invocation is disabled by default.

* SortKeys
	Specifies map keys should be sorted before being printed. Use
	this to have a more deterministic, diffable output.  Note that
	only native types (bool, int, uint, floats, uintptr and string)
	and types which implement error or Stringer interfaces are supported,
	with other types sorted according to the reflect.Value.String() output
	which guarantees display stability.  Natural map order is used by
	default.

* SpewKeys
	SpewKeys specifies that, as a last resort attempt, map keys should be
	spewed to strings and sorted by those strings.  This is only considered
	if SortKeys is true.

Unsafe Package Dependency

This package relies on the unsafe package to perform some of the more advanced features, however it also supports a "limited" mode which allows it to work in environments where the unsafe package is not available. By default, it will operate in this mode on Google App Engine and when compiled with GopherJS. The "safe" build tag may also be specified to force the package to build without using the unsafe package.

License

Go-spew is licensed under the copyfree ISC License.

go-spew's People

Contributors

anaminus avatar andrewzk avatar atombender avatar briandorsey avatar dajohi avatar davecgh avatar deads2k avatar flimzy avatar frapposelli avatar hiveminded avatar jbuberel avatar jrick avatar kevinburke avatar rogpeppe avatar techtonik avatar thockin avatar tshadwell avatar waldyrious avatar wangkechun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-spew's Issues

Feature Request: Provide ability to align types and values per indentation level

While each child is currently indented to the same level, it would be nice to also align the types and values for faster scanning. The following example illustrates:

(main.Foo) {
 unexportedField: (*main.Bar)(0xf84002e210)({
  flag:             (main.Flag) flagTwo,
  data:             (uintptr)   <nil>
  a:                (int)       1
  b:                (uint)      2
  longVariableName: (string)    "test" 
 }),
 ExportedField:   (map[interface {}]interface {}) {
  (string) "one": (bool)      true
  (int)    5    : (main.Flag) flTwo    
 }
}

More config states?

Hi! Thanks for writing go-spew; it's helped me a lot with large structs.

What I was wondering is how hard would it be to add in another bool to ConfigState, say {SimpleDump: true} that would get rid of type and length and the extra info? Or break it down into smaller flags like a Length bool, Type bool, etc..

Sometimes I want the entire output; and sometimes I just want to see values without all of the extra info.

I love spew and I will continue to use it. I just wanted to use only spew for my pretty-printing to stdout.

Thoughts? Or any pointers on me forking it and trying to add that functionality?

Formatting lost for specific object

I've had this issue since always in one of my projects. The newlines and indentations get lost when using spew on a certain object type. All other object both before and after dumping this one, are printed just fine.

This is the type definition and all the subtypes. It can be found in the wild here: https://github.com/ethereum/go-ethereum/blob/master/core/types/receipt.go#L46

type Receipt struct {
	PostState         []byte
	Status            uint
	CumulativeGasUsed *big.Int
	Bloom             Bloom
	Logs              []*Log
	TxHash            common.Hash
	ContractAddress   common.Address
	GasUsed           *big.Int
}

type Hash [HashLength]byte
type Address [AddressLength]byte
type Bloom [BloomByteLength]byte

type Log struct {
	Address     common.Address
	Topics      []common.Hash
	Data        []byte
	BlockNumber uint64
	TxHash      common.Hash
	TxIndex     uint
	BlockHash   common.Hash
	Index       uint
	Removed     bool
}

It looks like some of the values are breaking for formatting.

Here's an example:

(spew.ConfigState) {
 Indent: (string) (len=1) " ",
 MaxDepth: (int) 0,
 DisableMethods: (bool) false,
 DisablePointerMethods: (bool) false,
 DisablePointerAddresses: (bool) false,
 DisableCapacities: (bool) false,
 ContinueOnMethod: (bool) false,
 SortKeys: (bool) false,
 SpewKeys: (bool) false
}
(*types.Receipt)(0xc420001c80)(receipt{status=0 cgas=3500000 bloom=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[]})
(spew.ConfigState) {
 Indent: (string) (len=1) " ",
 MaxDepth: (int) 0,
 DisableMethods: (bool) false,
 DisablePointerMethods: (bool) false,
 DisablePointerAddresses: (bool) false,
 DisableCapacities: (bool) false,
 ContinueOnMethod: (bool) false,
 SortKeys: (bool) false,
 SpewKeys: (bool) false
}

please tag and version this project

Hello,

Can you please tag and version this project?

I am the Debian Maintainer for go-spew and versioning would help Debian keep up with development.

Support %T

I understand that spew does not support the %T formatter - it would be nice if it did.

Stringer : runtime: goroutine stack exceeds 1000000000-byte limit

Hello,
I want to use go-spew into String() string.
For example:

type Example struct {
    foo string
}

func (e Example) String() string {
  return spew.Sprintf("%+v", e)
}

Unfortunately, that generates:

runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

runtime stack:
runtime.throw(0x55c280, 0xe)
    /usr/lib/go/src/runtime/panic.go:547 +0x90
runtime.newstack()
    /usr/lib/go/src/runtime/stack.go:940 +0xb11
runtime.morestack()
    /usr/lib/go/src/runtime/asm_amd64.s:359 +0x7f

goroutine 1 [stack growth]:
fmt.(*pp).argNumber(0xc826df4820, 0x0, 0x553da0, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0)
    /usr/lib/go/src/fmt/print.go:1088 fp=0xc8401002b8 sp=0xc8401002b0
fmt.(*pp).doPrintf(0xc826df4820, 0x553da0, 0x3, 0xc826dbf530, 0x1, 0x1)
    /usr/lib/go/src/fmt/print.go:1144 +0xc87 fp=0xc840100640 sp=0xc8401002b8
fmt.Sprintf(0x553da0, 0x3, 0xc826dbf530, 0x1, 0x1, 0x0, 0x0)
    /usr/lib/go/src/fmt/print.go:203 +0x6f fp=0xc840100690 sp=0xc840100640
github.com/davecgh/go-spew/spew.Sprintf(0x553da0, 0x3, 0xc840100730, 0x1, 0x1, 0x0, 0x0)
    .../github.com/davecgh/go-spew/spew/spew.go:126 +0x90 fp=0xc8401006e8 sp=0xc840100690
main.Person.String(0x26, 0x5544e0, 0x6, 0x554540, 0x7, 0xc82000e0c0, 0x3, 0x3, 0x0, 0x0)
    .../src/cmd/spew/main.go:17 

Do you know a elegant manner to do this ?

Thx

go-spew fails with withmock utility - UnsafeDisabled redeclared in this block

$ withmock go test
ERROR: Failed to install 'github.com/project/db': exit status 2
output:
# github.com/davecgh/go-spew/spew
../../../github.com/davecgh/go-spew/spew/bypasssafe.go:8: UnsafeDisabled redeclared in this block
        previous declaration at ../../../github.com/davecgh/go-spew/spew/bypass.go:11
../../../github.com/davecgh/go-spew/spew/bypasssafe.go:11: unsafeReflectValue redeclared in this block
        previous declaration at ../../../github.com/davecgh/go-spew/spew/bypass.go:57

More info: qur/withmock#50

Feature request: json output

It would be very helpful if there was something like spew.SdumpJSON or a flag on dump methods to kick out our output as JSON.

The specific use case I have in mind is if there's an exception and I want to kick out an object into my logging stream which would then get picked up and shipped off to an ELK stack (Kibana and soon Sumologic can automatically parse json fields).

Feature request: Go syntax deep printing

Often, I am writing units tests and have expected outputs from a function that are structs with many fields, or arrays of structs so there may be >100 fields. I'd like to get one deep print of the struct I am comparing against, get a Go syntax representation, and then edit field values as necessary to write good unit tests.

I currently use a combination ginkgo/gomega Expect output, which is close but not Go syntax, or fmt's %#v printing which is Go syntax but does not dereference pointers. This would be extremely useful. If this not on the roadmap at all, I would be happy to try and implement it in go-spew.

Selective usage of String method

I have some Protobuf/gRPC generated types that I would like to pretty print using spew.

Some types, like enums, have String() methods generated that produce nice, readable output, for an example, see DevStatusReply_Status in the code below. For these types I prefer spew calling String() instead of formatting by itself.

Some types, structs like DevStatusReply_StatusDetails below , have a generated String() method that produces terses output. For these types I would rather have spew handle the printing by itself.

Using ConfigState.DisableMethods I can turn off and on whether spew calls the String() method, but I cannot discern between calling String() for the enums and spew pretty printing for the structs.

Is there a way I can control more finely which String()methods get called? Is there a way to work around this, except duplicating spew's code in my own program?

Code:

type DevStatusReply struct {
    Status      DevStatusReply_Status            `protobuf:"varint,4,opt,name=...`
    Details     *DevStatusReply_StatusDetails `protobuf:"bytes,8,opt,name=..."`
}

type DevStatusReply_Status int32
const (
    DevStatusReply_INVALID_STATUS DevStatusReply_Status = 0
    DevStatusReply_IDLE           DevStatusReply_Status = 1
    // and so on...
)

// prints nice string representation of enum
func (s DevStatusReply_Status) String() string { ... }

type DevStatusReply_StatusDetails struct {
   ...
}

// prints unwanted string representation of struct
func (x *DevStatusReply_StatusDetails) String() { ... }

spew.Dump appears to not be enumerating all structures

Are there any known issues where some structures aren't entirely printed. I submitted a PR to moby/moby#27331 to add this additional debugging (this is a really cool capability, thank you!), and I noticed that in the docker context, almost everything got written out except the contents of container structure. Yet I can do things such as fmt.Println(container.ID) quite happily. Seeing this issue on Windows 10 x64/Windows Server 2016, go 1.7.1 and go-spew @ master/latest.

I haven't managed to repro this though outside of docker with a simpler test program though.

eg

 containers: (*container.memoryStore)(0xc042155ee0)({
  s: (map[string]*container.Container) (len=1) {
   (string) (len=64) "3bcc1fd2c454fa545ce23ff7b9976a27c916fa58ac450079e6e9aba79b991055": (*container.Container)(0xc042423d40)()
  },

Thanks,
John.

Project health?

Is this project dead? There have been open PRs for quite some time.

(Was really hoping to use the DisableNilValues added in #60)

hex.Encode failed under go1.4

2015/01/02 00:20:52 runtime error: invalid memory address or nil pointer dereference
2015/01/02 00:20:52 frame 0:[func:utils.PrintPanicStack,file:/home/ubuntu/rts/src/utils/stack.go,line:13]
2015/01/02 00:20:52 frame 1:[func:runtime.call32,file:/usr/local/go/src/runtime/asm_amd64.s,line:402]
2015/01/02 00:20:52 frame 2:[func:runtime.gopanic,file:/usr/local/go/src/runtime/panic.go,line:387]
2015/01/02 00:20:52 frame 3:[func:runtime.panicmem,file:/usr/local/go/src/runtime/panic.go,line:42]
2015/01/02 00:20:52 frame 4:[func:runtime.sigpanic,file:/usr/local/go/src/runtime/sigpanic_unix.go,line:26
2015/01/02 00:20:52 frame 5:[func:encoding/hex.Encode,file:/usr/local/go/src/encoding/hex/hex.go,line:25]
2015/01/02 00:20:52 frame 6:[func:encoding/hex.(_dumper).Write,file:/usr/local/go/src/encoding/hex/hex.go,line:153]
2015/01/02 00:20:52 frame 7:[func:encoding/hex.Dump,file:/usr/local/go/src/encoding/hex/hex.go,line:106]
2015/01/02 00:20:52 frame 8:[func:github.com/davecgh/go-spew/spew.(_dumpState).dumpSlice,file:/home/ubuntu/rts/src/github.com/davecgh/go-spew/spew/dump.go,line:226]
2015/01/02 00:20:52 frame 9:[func:github.com/davecgh/go-spew/spew.(*dumpState).dump,file:/home/ubuntu/rts/src/github.com/davecgh/go-spew/spew/dump.go,line:349]
2015/01/02 00:20:52 frame 10:[func:github.com/davecgh/go-spew/spew.fdump,file:/home/ubuntu/rts/src/github.com/davecgh/go-spew/spew/dump.go,line:456]
2015/01/02 00:20:52 frame 11:[func:github.com/davecgh/go-spew/spew.Sdump,file:/home/ubuntu/rts/src/github.com/davecgh/go-spew/spew/dump.go,line:471]

How to dump the contents of a pointer?

If you spew.Dump(some-pointer) then you will see something like this:

(*lua.LTable)(0xc4202f1ec0)(table: 0xc4202f1ec0)

It is unclear, how to make it dump the whole structure and not just type name + address?

Displaying len and cap

It would handy if types that had len and cap were spewed with their length and capacity.

I propose the following output, which keeps the type separate from the length and possibly cap as well:

For slices:

([]string) (len=2 cap=10) {
 (string) "Hello",
 (string) "世界"
}

Maps:

(map[string]bool) (len=2) {
 (string) "Hello": (bool) true,
 (string) "世界": (bool) false
}

Strings:

(string) (len=13) "Hello, 世界"

Channels:

(chan string) (len=2 cap=10) 0xc20804e600

Although the len and cap functions are defined for arrays, spewing their results is less useful as both are equal to the array size regardless. Displaying it anyways may be desirable for consistancy, however.

Google App Engine

Is it possible to remove the unsafe package so that your package works with Google App Engine:

parser: bad import "unsafe" in github.com/davecgh/go-spew/spew/common.go

fatal error: stack overflow

I used a Delve debugger and go version go1.6.2 darwin/amd64. When tried to log token's struct I got this message

(*oauth2.token)(0xc82006cea0)(
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

whereas using another method fmt.Printf I get the following

&oauth2.token{Token:oauth2.Token{AccessToken:"(redacted)", TokenType:"", RefreshToken:"", Expiry:time.Time{sec:0, nsec:0, loc:(*time.Location)(0x8ccd80)}, raw:interface {}(nil)}}

Setting the MaxDepth limit doesn't work.

Incorrect representation of pointer values when nil

The following snippet shows that pointers are represented as double pointers when they are nil. I do not think this is intended:

package main

import (
    "github.com/davecgh/go-spew/spew"
)

type A struct {
    P *A
}

func main() {
    spew.Dump(A{})
    spew.Dump(A{P: &A{}})
}

Output:

(main.A) {
 P: (**main.A)()(<nil>)
}
(main.A) {
 P: (*main.A)(0xf840043148)({
  P: (**main.A)()(<nil>)
 })
}

handle map[*A]B better

I have a map[*MyStruct]OtherThing. Even with SortKeys set to true, the map ordering is non-deterministic (pointers, duh). I wonder if we could do something more heavyweight but deterministic when *MyStruct does not have a String() method? Maybe a new config option like SpewKeys which would apply the same spew conversion to each map key, then sort the resulting strings.

I understand it's a pretty niche case, but it would be useful in our generic "hash object" logic.

Alternatively, some way to get an error for a non-deterministic spew?

spewing a slice with go1.4.1

This panics with go 1.4.1:

package main

import "github.com/davecgh/go-spew/spew"

func main() {
c := [102]byte{}
spew.Dump(c[:100])
}

Bug with go 1.4.1

Hi!
I used go-spew in long running process and had this error:

fatal error: unexpected signal during runtime execution
[signal 0xb code=0x1 addr=0x1 pc=0x8069ef0]

runtime stack:
runtime.gothrow(0x8416f68, 0x2a)
        /usr/local/go/src/runtime/panic.go:503 +0x67 fp=0xb63e2f4c sp=0xb63e2f40
runtime.sigpanic()
        /usr/local/go/src/runtime/sigpanic_unix.go:14 +0x53 fp=0xb63e2f74 sp=0xb63e2f4c
scanblock(0x189c89e8, 0x10, 0x8438b68)
        /usr/local/go/src/runtime/mgc0.c:311 +0x840 fp=0xb63e3014 sp=0xb63e2f74
scanframe(0xb63e30a0, 0x0, 0x1)
        /usr/local/go/src/runtime/mgc0.c:740 +0x186 fp=0xb63e3050 sp=0xb63e3014
runtime.gentraceback(0x80520d0, 0x189c89e4, 0x0, 0x1887adc0, 0x0, 0x0, 0x7fffffff, 0xb63e30f8, 0x0, 0x0, ...)
        /usr/local/go/src/runtime/traceback.go:311 +0x5c5 fp=0xb63e30cc sp=0xb63e3050
scanstack(0x1887adc0)
        /usr/local/go/src/runtime/mgc0.c:777 +0x1e0 fp=0xb63e3104 sp=0xb63e30cc
markroot(0x1870a050, 0xc4)
        /usr/local/go/src/runtime/mgc0.c:553 +0xcd fp=0xb63e313c sp=0xb63e3104
runtime.parfordo(0x1870a050)
        /usr/local/go/src/runtime/parfor.c:76 +0x99 fp=0xb63e3198 sp=0xb63e313c
gc(0xb63e32d4)
        /usr/local/go/src/runtime/mgc0.c:1439 +0x1fb fp=0xb63e32c4 sp=0xb63e3198
runtime.gc_m()
        /usr/local/go/src/runtime/mgc0.c:1368 +0xd2 fp=0xb63e32e4 sp=0xb63e32c4
runtime.onM(0x18710000)
        /usr/local/go/src/runtime/asm_386.s:266 +0x50 fp=0xb63e32e8 sp=0xb63e32e4
runtime.mstart()
        /usr/local/go/src/runtime/proc.c:818 fp=0xb63e32ec sp=0xb63e32e8


goroutine 6662130 [garbage collection]:
runtime.switchtoM()
        /usr/local/go/src/runtime/asm_386.s:208 fp=0x1881eae8 sp=0x1881eae4
runtime.gogc(0x0)
        /usr/local/go/src/runtime/malloc.go:469 +0x1aa fp=0x1881eb08 sp=0x1881eae8
runtime.mallocgc(0x10, 0x0, 0x3, 0x0)
        /usr/local/go/src/runtime/malloc.go:341 +0x2c4 fp=0x1881eb60 sp=0x1881eb08
runtime.rawmem(0x8, 0x8)
        /usr/local/go/src/runtime/malloc.go:371 +0x38 fp=0x1881eb74 sp=0x1881eb60
runtime.growslice(0x82e40e0, 0x1881ebd8, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0)
        /usr/local/go/src/runtime/slice.go:83 +0x210 fp=0x1881ebb4 sp=0x1881eb74
github.com/davecgh/go-spew/spew.(*dumpState).dumpPtr(0x18878b80, 0x8379ec0, 0x1882f400, 0x36)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:107 +0x65b fp=0x1881ec6c sp=0x1881ebb4
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x8379ec0, 0x1882f400, 0x36)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:259 +0xdf fp=0x1881edc4 sp=0x1881ec6c
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x82ec860, 0x18737494, 0xf5)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:382 +0xdbd fp=0x1881ef1c sp=0x1881edc4
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x837c9a0, 0x18737480, 0xf9)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:412 +0x13e2 fp=0x1881f074 sp=0x1881ef1c
github.com/davecgh/go-spew/spew.(*dumpState).dumpPtr(0x18878b80, 0x8379ec0, 0x18737480, 0x36)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:154 +0x593 fp=0x1881f12c sp=0x1881f074
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x8379ec0, 0x18737480, 0x36)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:259 +0xdf fp=0x1881f284 sp=0x1881f12c
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x837c9a0, 0x188536e0, 0xf9)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:412 +0x13e2 fp=0x1881f3dc sp=0x1881f284
github.com/davecgh/go-spew/spew.(*dumpState).dumpPtr(0x18878b80, 0x8379ec0, 0x188536e0, 0x36)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:154 +0x593 fp=0x1881f494 sp=0x1881f3dc
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x8379ec0, 0x188536e0, 0x36)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:259 +0xdf fp=0x1881f5ec sp=0x1881f494
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x837e2a0, 0x1882b560, 0xd9)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:412 +0x13e2 fp=0x1881f744 sp=0x1881f5ec
github.com/davecgh/go-spew/spew.(*dumpState).dumpPtr(0x18878b80, 0x838bc80, 0x1882b560, 0x16)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:154 +0x593 fp=0x1881f7fc sp=0x1881f744
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x838bc80, 0x1882b560, 0x16)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:259 +0xdf fp=0x1881f954 sp=0x1881f7fc
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x837f2a0, 0x18853700, 0xd9)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:412 +0x13e2 fp=0x1881faac sp=0x1881f954
github.com/davecgh/go-spew/spew.(*dumpState).dumpPtr(0x18878b80, 0x837fda0, 0x18853700, 0x16)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:154 +0x593 fp=0x1881fb64 sp=0x1881faac
github.com/davecgh/go-spew/spew.(*dumpState).dump(0x18878b80, 0x837fda0, 0x18853700, 0x16)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:259 +0xdf fp=0x1881fcbc sp=0x1881fb64
github.com/davecgh/go-spew/spew.fdump(0x8570060, 0xb75b8470, 0x1882aae0, 0x1881fdbc, 0x1, 0x1)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:456 +0x22c fp=0x1881fd34 sp=0x1881fcbc
github.com/davecgh/go-spew/spew.Sdump(0x1881fdbc, 0x1, 0x1, 0x0, 0x0)
        /gopath/src/github.com/davecgh/go-spew/spew/dump.go:471 +0x8e fp=0x1881fd74 sp=0x1881fd34

Printing []byte panics

Maybe I'm missing something, but when I try to print out my bson.D stuct, it works fine if there is no binary data in it, but if I put in []uint8, it barfs. As a simple example, this will panic:

foo := []byte { byte(41) }
spew.Dump(foo)

which produces

panic: runtime error: invalid memory address or nil pointer dereference

Better cgo support

This can be made smaller:

 buf: ([1024]foo._Ctype_char) {
  (foo._Ctype_char) 115,
  (foo._Ctype_char) 100,
  (foo._Ctype_char) 102,
  (foo._Ctype_char) 115,
  (foo._Ctype_char) 100,
  (foo._Ctype_char) 102,
  (foo._Ctype_char) 115,
  (foo._Ctype_char) 100,
  (foo._Ctype_char) 102,
  (foo._Ctype_char) 115,
  (foo._Ctype_char) 0,
  (foo._Ctype_char) 0,
  (foo._Ctype_char) 0,
  ...

tests fail with gotip

something in gotip must have changed recently and is making the tests fail. They pass fine with:
go version devel +7e1a4e190b02 Thu Dec 19 13:02:06 2013 +0900 linux/amd64
but with:
go version devel +c344ec9f4318 Wed Jan 01 00:00:22 2014 +1100 linux/amd64

=== RUN TestInvalidReflectValue
--- PASS: TestInvalidReflectValue (0.00 seconds)
=== RUN TestAddedReflectValue
--- FAIL: TestAddedReflectValue (0.00 seconds)
internal_test.go:120: TestAddedReflectValue #1
got: (int8) -12 want: (int8) 5
internal_test.go:131: TestAddedReflectValue #2
got: (int8) -11 want: (int8)
internal_test.go:143: TestAddedReflectValue #3 got: -12 want: 5
internal_test.go:155: TestAddedReflectValue #4 got: -11 want:
=== RUN TestSortValues
--- PASS: TestSortValues (0.00 seconds)
=== RUN TestDump
--- FAIL: TestDump (0.00 seconds)
dump_test.go:888: Running 193 tests
panic: reflect.Value.Addr of unaddressable value [recovered]
panic: reflect.Value.Addr of unaddressable value

goroutine 6 [running]:
runtime.panic(0x56a120, 0xc210063c30)
/home/mpl/gotip/src/pkg/runtime/panic.c:264 +0xb6
testing.func·005()
/home/mpl/gotip/src/pkg/testing/testing.go:385 +0xe8
runtime.panic(0x56a120, 0xc210063c30)
/home/mpl/gotip/src/pkg/runtime/panic.c:246 +0x106
reflect.Value.Addr(0x0, 0x0, 0x0, 0x0, 0x0, ...)
/home/mpl/gotip/src/pkg/reflect/value.go:385 +0x75
github.com/davecgh/go-spew/spew.handleMethods(0x7f5a00, 0x7f4e29a8d308, 0xc2100702a0, 0x0, 0x0, ...)
/home/mpl/gocode/src/github.com/davecgh/go-spew/spew/common.go:142 +0x146
github.com/davecgh/go-spew/spew.(*dumpState).dump(0xc210072270, 0x569e20, 0x0, 0x7f, 0x30)
/home/mpl/gocode/src/github.com/davecgh/go-spew/spew/dump.go:277 +0x348
github.com/davecgh/go-spew/spew.fdump(0x7f5a00, 0x7f4e29a8d308, 0xc2100702a0, 0x7f4e29903e88, 0x1, ...)
/home/mpl/gocode/src/github.com/davecgh/go-spew/spew/dump.go:430 +0x287
github.com/davecgh/go-spew/spew.Fdump(0x7f4e29a8d308, 0xc2100702a0, 0x7f4e29903e88, 0x1, 0x1)
/home/mpl/gocode/src/github.com/davecgh/go-spew/spew/dump.go:438 +0x5c
github.com/davecgh/go-spew/spew_test.TestDump(0xc210058240)
/home/mpl/gocode/src/github.com/davecgh/go-spew/spew/dump_test.go:891 +0x2c0
testing.tRunner(0xc210058240, 0x7f90c8)
/home/mpl/gotip/src/pkg/testing/testing.go:391 +0x8b
created by testing.RunTests
/home/mpl/gotip/src/pkg/testing/testing.go:471 +0x958

goroutine 1 [chan receive]:
testing.RunTests(0x60d450, 0x7f9080, 0x8, 0x8, 0x0)
/home/mpl/gotip/src/pkg/testing/testing.go:472 +0x97b
testing.Main(0x60d450, 0x7f9080, 0x8, 0x8, 0x7fd940, ...)
/home/mpl/gotip/src/pkg/testing/testing.go:403 +0x8c
main.main()
/tmp/go-build429184412/github.com/davecgh/go-spew/spew/_test/_testmain.go:73 +0x9c
exit status 2
FAIL github.com/davecgh/go-spew/spew 0.005s

func dump(v reflect.Value) has a problem with reflect.Interface case

Over at

go-spew/spew/dump.go

Lines 264 to 265 in ff59042

case reflect.Interface:
// Do nothing. We should never get here due to unpackValue calls.
,

case reflect.Interface:
    // Do nothing.  We should never get here due to unpackValue calls.

Add the following line:

d.w.Write([]byte("<NOT TRUE, DID GET HERE>"))

And run the following program:

package main

import "go/ast"
import "github.com/davecgh/go-spew/spew"

func main() {
    spew.Dump(ast.NewObj(0, "name"))
}

The output is:

(*ast.Object)(0x4213ba50)({
 Kind: (ast.ObjKind) bad,
 Name: (string) "name",
 Decl: (interface {}) <NOT TRUE, DID GET HERE>,
 Data: (interface {}) <NOT TRUE, DID GET HERE>,
 Type: (interface {}) <NOT TRUE, DID GET HERE>
})

I'm guessing they're nil values. Edit: Confirmed, they're nil. I suppose printing <nil> would be expected behaviour. Without the added line above, it simply doesn't print anything at all for the value of Decl, Data and Type:

(*ast.Object)(0x4213ba50)({
 Kind: (ast.ObjKind) bad,
 Name: (string) "name",
 Decl: (interface {}) ,
 Data: (interface {}) ,
 Type: (interface {}) 
})

I imagine this affects format.go's format() func similarly.

Suggested example for use in web application debugging

I thought it might be useful to add the following snippet to the README file to help users get started with the library:

package main

import (
    "fmt"
    "net/http"

    "github.com/davecgh/go-spew/spew"

)

func handler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/html")
    fmt.Fprintf(w, "Hi there, %s!", r.URL.Path[1:])
    fmt.Fprintf(w, "<!--\n" + spew.Sdump(w) + "\n-->")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

If you're OK with something like this, I'll send a pull request.

%#v formatting with lists

Hi,

I have notices that in fmt.Printf(%#v, list) separate list entities with a ","(comma), but spew use space here, with no way of reconfiguring this. Space separation can be quite confusing when you have a list of strings, as it is ambiguous were the separation really is.

spew fails to detect cyclic data

The following runs forever(*) without producing any output:

package main

import "github.com/davecgh/go-spew/spew"

func main() {
	type loop *loop
	var loop1, loop2 loop
	loop1 = &loop2
	loop2 = &loop1
	spew.Dump(&loop1)
}

(*) It does not hit the stack size limit; its memory usage does keep growing so obviously it will eventually run out of swap or virtual address space...

unsafe on GAE

For environments where unsafe isn't allowed,
will this package follow pointers and print out their concrete value?

Omit empty as an option

Often I'm working with large structs which have fields which are usually empty, but which are of a lot of interest if not empty. I would love there to be an option to omit empty fields. The problem of course is how we define empty.

I would suggest that simply considering the zero or nil state of any field to be an empty field. So, "" would be empty for a string, and 0 would be empty for an int.

Feature Request: Support printing in Go syntax

Right now spew does a great job of visualizing Go data structures for debugging purposes. I think it'd be useful to be able to print the data structures that is valid Go code to recreate the structure itself.

For instance, currently this code...

package main

import "github.com/davecgh/go-spew/spew"

func main() {
    spew.Config.Indent = "\t"

    type Inner struct {
        Field1 string
        Field2 int
    }
    type Lang struct {
        Name  string
        Year  int
        URL   string
        Inner *Inner
    }

    x := Lang{
        Name: "Go",
        Year: 2009,
        URL:  "http",
        Inner: &Inner{
            Field1: "Secret!",
        },
    }

    spew.Dump(x)
}

Will produce:

(main.Lang) {
    Name: (string) "Go",
    Year: (int) 2009,
    URL: (string) "http",
    Inner: (*main.Inner)(0x42166440)({
        Field1: (string) "Secret!",
        Field2: (int) 0
    })
}

But I'd like to be able to print x so that the output would be:

Lang{
    Name: "Go",
    Year: 2009,
    URL:  "http",
    Inner: &Inner{
        Field1: "Secret!",
    },
}

And/or:

Lang{Name: "Go", Year: 2009, URL: "http", Inner: &Inner{Field1: "Secret!"}}

Feature Request: Hide certain types in output

I'm working with the gorilla muxer (https://github.com/gorilla/mux), and am trying to debug my routes, and am getting massive outputs that prevent me from seeing the bits I'm interested in.

A sample struct is like the following:

(*http.Route)(0xc04215a240)({
 parent: (*http.Router)(0xc04200a7e0)({

  // -- a giant struct that is too big for it's own good

 }),
 handler: (*http.JSONHandler)(0xc042004118)({
  H: (func(context.Context, http.ResponseWriter, *http.Request) (interface {}, error)) 0x786ae0
 }),
 matchers: ([]http.matcher) (len=2 cap=2) {
  (*http.routeRegexp)(0xc04200a8a0)({
   template: (string) (len=9) "/register",
   matchHost: (bool) false,
   matchQuery: (bool) false,
   strictSlash: (bool) false,
   useEncodedPath: (bool) false,
   regexp: (*regexp.Regexp)(0xc04204b4a0)({

    // -- another giant struct ...

It would be great to be able to tell spew to ignore anything (or output something like <ignored> instead) that I specify, like *http.Router and *regexp.Regexp.

If that isn't possible, maybe passing in a path, like .parent, or .matchers[n].regexp would be another option.

Thanks for an awesome script!

Output valid Go code initializing structs

Is is possible to output valid Go code that initialize a struct with pointers that can be used in tests? I am printing a large struct (with pointer members) received back as part of a Protobuf response. Trying to use this data to initialize test data. Converting this using fmt.Printf("%#v") does not chase down pointers -- otherwise the format is just perfect. spew uses a different format and I cannot use that.

type Y struct {
	Y1 *string
	Y2 *int32
}

If these are assigned values "str" and 42, then the output should be something like:

Y{ Y1:&[]string{"str"}[0], Y2:&[]int32{42}[0] }

It should also bypass the stringer methods so that field names are used and not struct tagnames etc.

Dump without showing pointer addresses

Hi,

I'd like to use spew in combination with a text diff pkg to show useful error messages when deep equality checks fail in my test cases. Ideally I'd like to have the same output as Dump(), but without the pointer addresses showing. Would you be interested in a patch for this? I'd be happy to propose an API for it first or take a suggestion from you.

Cheers,
Felix

Infinite recursion on circular structure

I am working on a library to generically parse NSKeyedArchiver file formats. A very simply recursive map puts go-spew into an infinite loop.

a := map[string]interface{}{}
a["circular"] = map[string]interface{}{
	"a": a,
}

spew.Dump(a)

Feature Request: Dump byte arrays and slices like hexdump -C does in unix

The current implementation dumps each byte along with its type on a separate line. This documents my intention to modify the dump to output byte arrays and slices like hexdump -C.

([]byte) {
 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |
 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0|
 00000020  31 32                                             |12|
}

Does not spew any struct fields for me:

I have a type like this:

type FrustumCoords struct {
    Vec2
    C, TL, TR, BL, BR Vec3

    x, y Vec3
}

Whether I spew.Printf or spew.Dump a variable of that type, it only spews the fields of the embedded Vec2 (which in turn has two float64 fields, X and Y), nothing else, no C, TL, TR, BL, BR..

What now? Docs say:

* MaxDepth
    Maximum number of levels to descend into nested data structures.
    There is no limit by default.

OK I'm not setting any configs for spew anywhere, so not sure what I have to do?

spew.dump stack overflow problem

package main

import "github.com/davecgh/go-spew/spew"

type A struct {
	AMember int
}

func (this *A) String() string {
	return spew.Sdump(this)
}

type B struct {
	BMember A
}

func main() {
	spew.Config.DisableMethods = false
	b := &B{A{32}}
	spew.Dump(b)
}

render addresses of non-pointer values that have pointer references

At the moment spew does not render addresses of non-pointer values that are referenced by pointers in a dump, this is described in more detail in my issue here kortschak#2.

I have an incomplete implementation of this (its working but I'm still thinking about how to deal with []byte dumps), that I'd be happy to donate back to spew: kortschak@b77c4ff (minor changes in addition to the changes in this CL are required - basically just the wasPtr return value from unpackValue).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.