pprof support for Node.js
A P2P chat box implemented in C which provides both scalability and fault tolerance.
A lock-free software-only runtime system for C++ that eliminates concurrency errors for fork-join parallel programs
MIT-6.828 Operating System Engineering
Solved problems for ICPC
Learning Objective-C and iOS developing in AppDev Grinnell
An iOS app to help stray cats find their home or help you find your new cat
issue commentGoogleCloudPlatform/cloud-profiler-python
Failed to collect and upload profile: dictionary changed size during iteration
this is a fastapi application.
tool.poetry.dependencies]
python = "^3.7"
fastapi = "^0.61.0"
httpx = { extras = ["http2"], version = "^0.16.1" }
uvicorn = "^0.11.8"
loguru = "^0.5.1"
pydantic = {extras = ["email", "dotenv"], version = "^1.7.3"}
pybase62 = "^0.4.3"
arrow = "^0.15.8"
autoname = "^0.1.1"
sentry-sdk = "^0.16.5"
google-api-python-client = "^1.8.4"
google-auth-httplib2 = "^0.0.4"
google-auth-oauthlib = "^0.4.1"
grpcio = "^1.31.0"
motor = "^2.3.0"
dnspython = "^2.0.0"
line-bot-sdk = "^1.18.0"
tenacity = "^6.3.1"
notifiers = "^1.2.1"
omise = "^0.9.0"
python-multipart = "^0.0.5"
furl = "^2.1.0"
imagekitio = "^2.2.5"
jingdi = "^0.1.0"
pyzbar-x = "^0.2.1"
Pillow = "^8.1.0"
fastapi-utils = "^0.2.1"
google-python-cloud-debugger = "^2.15"
tomlkit = "^0.7.0"
locate = "^0.0.1"
parse-with-dot-access = "^1.18.0"
comment created time in 11 hours
issue commentGoogleCloudPlatform/cloud-profiler-python
Failed to collect and upload profile: dictionary changed size during iteration
Could you explain more? What is the stack?
comment created time in a day
issue commentGoogleCloudPlatform/cloud-profiler-python
BlockingIOError on App Engine after some time
@mgrdcm This is not specific to gunicorn, any package or user code could set the same.
I appreciate your point regarding App Engine. We will post an update if we figure out a way to address this.
comment created time in a day
Pull request review commentgoogle/pprof
Update the function comment for FindProgHeaderForMapping.
func FindTextProgHeader(f *elf.File) *elf.ProgHeader { // FindProgHeaderForMapping returns the loadable program segment header that is // fully contained in the runtime mapping with file offset pgoff and memory size-// memsz, or an error if the segment cannot be determined.+// memsz, or an error if the segment cannot be determined. The function returns+// a nil progran header and no error if the ELF binary has no loadable segments.
Oops, updated.
comment created time in a day
Pull request review commentgoogle/pprof
Update the function comment for FindProgHeaderForMapping.
func FindTextProgHeader(f *elf.File) *elf.ProgHeader { // FindProgHeaderForMapping returns the loadable program segment header that is // fully contained in the runtime mapping with file offset pgoff and memory size-// memsz, or an error if the segment cannot be determined.+// memsz, or an error if the segment cannot be determined. The function returns+// a nil progran header and no error if the ELF binary has no loadable segments.
typo: progran
comment created time in a day
PR opened google/pprof
Added text to specify that it can return a nil program header in some cases.
pr created time in a day
issue openedgoogle/pprof
Source listing not found in webview while present in command line
What version of pprof are you using? GOARCH="amd64" GOBIN="" GOCACHE="/home/USER/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/USER/go" GOPROXY="" GORACE="" GOROOT="/home/USER/opt/go" GOTMPDIR="" GOTOOLDIR="/home/USER/opt/go/pkg/tool/linux_amd64" GCCGO="gccgo" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build584220800=/tmp/go-build -gno-record-gcc-switches"
What operating system and processor architecture are you using? Linux Ubuntu 18.04 x64
What did you do? go tool pprof -http=":8000" -source_path=/home/USER/code/APP/src APP cpuProfile.pprof Open the source view, give it focus on "FUNCTION"
FUNCTION_PATH bufio/bufio.go Total: 0 680ms (flat, cum) 3.39% 48 . . ??? 49 . 680ms ??? 55 . . ??? 56 . . ??? 75 . . ??? 78 . . ??? 79 . . ??? --> no source code visible
go tool pprof -source_path=/home/USER/code/APP/src APP cpuProfile.pprof (pprof) list FUNCTION Total: 20.07s ROUTINE ======================== FUNCTION_PATH in bufio/bufio.go 0 680ms (flat, cum) 3.39% of Total Error: Could not find file bufio/bufio.go on path /home/USER/code/APP/src ROUTINE ======================== FUNCTIONPATH in FUNCTION_GO_FILE_IN_GIVEN_PATH.go --> starts listing source code here.
It seems that the webview doesn't show/find the source code, while the command line does.
created time in a day
push eventgoogle/pprof
commit sha 1f0ca0a18a6c71389147d82349e7519e9d270707
Enable symbolization of data objects with the llvm symbolizer (#598) * Compute the correct base offset for non-executable runtime mappings. For user space executables, find the segment associated with the current mapping and use its header in the call to GetBase, instead of using the program header for the segment that includes the .text section. This change is needed for all local symbolizers that handle ELF files. * Enable the llvn-symbolizer to symbolize data addresses. For data addresses, we need to issue "DATA <binary_name> <address>" commands, while for code addresses, we issue "CODE <binary_name> <address>" commands. Right now, the frames for data addresses include the symbol start address and size in the filename field.
push time in 2 days
PR merged google/pprof
This PR adds support for symbolizing virtual data addresses with the llvm-symbolizer. As a prerequisite, we have to compute the correct GetBase offset for data mappings, regardless of which local symbolizer is used.
One of the commits, changes the current behavior from always computing a base offset relative to the executable program segment, to an approach that tries to identify the program segment associated with a given mapping and computing the offset relative to that segment. This change is enabled only for user space mappings. For kernel mappings, we continue to look for the kernel executable segment.
With this change, we drop support for fake mappings that span the entire address space. From an offline discussion with aalexand@:
- fake mappings were added by https://github.com/google/pprof/pull/89 to handle profiles with no mappings that would be generated by golang runtime sometimes;
- local experiments by aalexand@ show the fake mapping is present in Go 1.7 heap profiles, but not in Go 1.8 profiles. This may be related to the fact that the older Go versions didn't use profile.proto and generated legacy text format instead;
- Go 1.7 is not a supported version anymore, so we are OK with dropping support for the fake mapping.
pr closed time in 2 days
issue commentGoogleCloudPlatform/cloud-profiler-python
Failed to collect and upload profile: dictionary changed size during iteration
@CircleOnCircles I assume there wasn't a stack?
comment created time in 2 days
pull request commentgoogle/pprof
Revamp how source listing is produced so it works for inlined functions.
Codecov Report
Merging #599 (10d04a0) into master (39141e7) will decrease coverage by
0.48%. The diff coverage is77.61%.
@@ Coverage Diff @@
## master #599 +/- ##
==========================================
- Coverage 66.97% 66.49% -0.49%
==========================================
Files 78 78
Lines 14160 14462 +302
==========================================
+ Hits 9484 9616 +132
- Misses 3842 3996 +154
- Partials 834 850 +16
| Impacted Files | Coverage Δ | |
|---|---|---|
| internal/report/source.go | 78.86% <77.18%> (-2.55%) |
:arrow_down: |
| internal/driver/driver.go | 70.39% <100.00%> (+0.67%) |
:arrow_up: |
| internal/report/report.go | 21.93% <0.00%> (-7.32%) |
:arrow_down: |
| .../github.com/google/pprof/internal/report/report.go | 21.93% <0.00%> (-7.32%) |
:arrow_down: |
| .../github.com/google/pprof/internal/report/source.go | 78.86% <0.00%> (-2.55%) |
:arrow_down: |
| .../github.com/google/pprof/internal/driver/driver.go | 70.39% <0.00%> (+0.67%) |
:arrow_up: |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing dataPowered by Codecov. Last update 39141e7...7cd4f88. Read the comment docs.
comment created time in 2 days
PR opened google/pprof
Some other things improved due to these changes:
- Produced output does not contain long runs of uninteresting source.
- Speed of producing weblist page for a large binary goes from ~ 57s to ~ 5.5s.
pr created time in 2 days
issue commentGoogleCloudPlatform/cloud-profiler-python
Failed to collect and upload profile: dictionary changed size during iteration
It don't know how to reproduce it exactly.
comment created time in 3 days
issue openedGoogleCloudPlatform/cloud-profiler-python
Failed to collect and upload profile: dictionary changed size during iteration
this is the bug raised in production capture by sentry.
"Failed to collect and upload profile: dictionary changed size during iteration"
CPython, 3.8.2(3.8.2 (default, Apr 23 2020, 14:22:33) [GCC 8.3.0])
created time in 3 days
startedyamamushi/dumap
started time in 3 days
pull request commentgoogle/pprof
Enable symbolization of data objects with the llvm symbolizer
Codecov Report
Merging #598 (149e940) into master (39141e7) will increase coverage by
0.09%. The diff coverage is82.05%.
@@ Coverage Diff @@
## master #598 +/- ##
==========================================
+ Coverage 66.97% 67.06% +0.09%
==========================================
Files 78 78
Lines 14160 14224 +64
==========================================
+ Hits 9484 9540 +56
- Misses 3842 3848 +6
- Partials 834 836 +2
| Impacted Files | Coverage Δ | |
|---|---|---|
| internal/elfexec/elfexec.go | 38.09% <80.95%> (+8.57%) |
:arrow_up: |
| internal/binutils/addr2liner_llvm.go | 65.62% <83.33%> (+1.69%) |
:arrow_up: |
| internal/binutils/binutils.go | 54.86% <83.33%> (+1.45%) |
:arrow_up: |
| .../google/pprof/internal/binutils/addr2liner_llvm.go | 71.87% <0.00%> (+1.38%) |
:arrow_up: |
| ...hub.com/google/pprof/internal/binutils/binutils.go | 45.52% <0.00%> (+1.75%) |
:arrow_up: |
| ...ithub.com/google/pprof/internal/elfexec/elfexec.go | 38.09% <0.00%> (+8.57%) |
:arrow_up: |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing dataPowered by Codecov. Last update 39141e7...149e940. Read the comment docs.
comment created time in 6 days
pull request commentgoogle/pprof
Enable symbolization of data objects with the llvm symbolizer
Tests failed. Please mark this as draft until it's ready for review.
comment created time in 6 days
PR opened google/pprof
pr created time in 6 days
push eventgoogle/pprof
commit sha 39141e76b6471416fad93e101d512dedec969596
proto/profile.proto: fix typo (#577) Signed-off-by: Stephan Renatus <[email protected]> Co-authored-by: Maggie Nolan <[email protected]> Co-authored-by: Kalyana Chadalavada <[email protected]>
push time in 6 days
PR merged google/pprof
pr closed time in 6 days
startedgoogle-research-datasets/paws
started time in 7 days
Pull request review commentgoogle/pprof
func timeLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bo toUnit = strings.TrimSuffix(toUnit, "s") } - var d time.Duration- switch fromUnit {- case "nanosecond", "ns":- d = time.Duration(value) * time.Nanosecond- case "microsecond":- d = time.Duration(value) * time.Microsecond- case "millisecond", "ms":- d = time.Duration(value) * time.Millisecond- case "second", "sec", "s":- d = time.Duration(value) * time.Second- case "cycle":+ if fromUnit == "cycle" { return float64(value), "", true- default:+ }++ uf := func(unit string) (string, float64, bool) {+ return unitFactor(unit, timeUnits)+ }+ as := func(value float64) (float64, string, bool) {+ return autoScale(value, timeUnits)+ }+ return convertUnit(value, fromUnit, toUnit, unit{"s", []string{}, float64(time.Second)}, uf, as)+}++var gcuUnits = []unit{+ {"n*GCU", []string{"nanogcu"}, 1e-9},+ {"u*GCU", []string{"microgcu"}, 1e-6},+ {"m*GCU", []string{"milligcu"}, 1e-3},+ {"GCU", []string{"gcu"}, 1},+ {"k*GCU", []string{"kilogcu"}, 1e3},+ {"M*GCU", []string{"megagcu"}, 1e6},+ {"G*GCU", []string{"gigagcu"}, 1e9},+ {"T*GCU", []string{"teragcu"}, 1e12},+ {"P*GCU", []string{"petagcu"}, 1e15},+}++// isGCUUnit returns whether a name is recognized as a GCU unit.+func isGCUUnit(unit string) bool {+ _, _, gcuUnit := unitFactor(strings.TrimSuffix(strings.ToLower(unit), "s"), gcuUnits)+ return gcuUnit+}++func gcuLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bool) {+ fromUnit = strings.TrimSuffix(strings.ToLower(fromUnit), "s")+ toUnit = strings.TrimSuffix(strings.ToLower(toUnit), "s")+ uf := func(unit string) (string, float64, bool) {+ return unitFactor(unit, gcuUnits)+ }+ as := func(value float64) (float64, string, bool) {+ return autoScale(value, gcuUnits)+ }+ return convertUnit(value, fromUnit, toUnit, unit{"GCU", []string{}, 1.0}, uf, as)+}++// convertUnit converts a value from the fromUnit to the toUnit, autoscaling+// the value if the toUnit is "minimum" or "auto". If the fromUnit is not+// included in units, then a false boolean will be returned. If the toUnit+// is not in units, the value will be returned in terms of the default unit.+func convertUnit(value int64, fromUnit, toUnit string, defaultUnit unit, unitFactor func(string) (string, float64, bool), autoScale func(float64) (float64, string, bool)) (v float64, u string, ok bool) {+ _, fromUnitFactor, ok := unitFactor(fromUnit)+ if !ok { return 0, "", false } + v = float64(value) * fromUnitFactor+ if toUnit == "minimum" || toUnit == "auto" {- switch {- case d < 1*time.Microsecond:- toUnit = "ns"- case d < 1*time.Millisecond:- toUnit = "us"- case d < 1*time.Second:- toUnit = "ms"- case d < 1*time.Minute:- toUnit = "sec"- case d < 1*time.Hour:- toUnit = "min"- case d < 24*time.Hour:- toUnit = "hour"- case d < 15*24*time.Hour:- toUnit = "day"- case d < 120*24*time.Hour:- toUnit = "week"- default:- toUnit = "year"+ if v, u, ok := autoScale(v); ok {+ return v, u, true }+ return v / defaultUnit.factor, defaultUnit.canonicalName, true } - var output float64- dd := float64(d)- switch toUnit {- case "ns", "nanosecond":- output, toUnit = dd/float64(time.Nanosecond), "ns"- case "us", "microsecond":- output, toUnit = dd/float64(time.Microsecond), "us"- case "ms", "millisecond":- output, toUnit = dd/float64(time.Millisecond), "ms"- case "min", "minute":- output, toUnit = dd/float64(time.Minute), "mins"- case "hour", "hr":- output, toUnit = dd/float64(time.Hour), "hrs"- case "day":- output, toUnit = dd/float64(24*time.Hour), "days"- case "week", "wk":- output, toUnit = dd/float64(7*24*time.Hour), "wks"- case "year", "yr":- output, toUnit = dd/float64(365*24*time.Hour), "yrs"- default:- // "sec", "second", "s" handled by default case.- output, toUnit = dd/float64(time.Second), "s"+ toUnit, toUnitFactor, ok := unitFactor(toUnit)+ if !ok {+ return v / defaultUnit.factor, defaultUnit.canonicalName, true+ }+ return v / toUnitFactor, toUnit, true+}++// unitFactor returns the canonical name for the unit, the factor by which one+// must multiply a value specified in terms of unit in order to get the value+// specified in terms of the base unit, and a boolean to indicated if a unit+// was identified for the specified unit within the slice units.+func unitFactor(unit string, units []unit) (string, float64, bool) {
Thanks! This is much simpler.
One thing that happened with this change: 'cycle' is no longer treated as a time unit. There weren't any tests which failed because of this, but wanted to call it out in case this could be a problem.
comment created time in 7 days
Pull request review commentgoogle/pprof
func timeLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bo toUnit = strings.TrimSuffix(toUnit, "s") } - var d time.Duration- switch fromUnit {- case "nanosecond", "ns":- d = time.Duration(value) * time.Nanosecond- case "microsecond":- d = time.Duration(value) * time.Microsecond- case "millisecond", "ms":- d = time.Duration(value) * time.Millisecond- case "second", "sec", "s":- d = time.Duration(value) * time.Second- case "cycle":+ if fromUnit == "cycle" { return float64(value), "", true- default:+ }++ uf := func(unit string) (string, float64, bool) {+ return unitFactor(unit, timeUnits)+ }+ as := func(value float64) (float64, string, bool) {+ return autoScale(value, timeUnits)+ }+ return convertUnit(value, fromUnit, toUnit, unit{"s", []string{}, float64(time.Second)}, uf, as)+}++var gcuUnits = []unit{+ {"n*GCU", []string{"nanogcu"}, 1e-9},+ {"u*GCU", []string{"microgcu"}, 1e-6},+ {"m*GCU", []string{"milligcu"}, 1e-3},+ {"GCU", []string{"gcu"}, 1},+ {"k*GCU", []string{"kilogcu"}, 1e3},+ {"M*GCU", []string{"megagcu"}, 1e6},+ {"G*GCU", []string{"gigagcu"}, 1e9},+ {"T*GCU", []string{"teragcu"}, 1e12},+ {"P*GCU", []string{"petagcu"}, 1e15},+}++// isGCUUnit returns whether a name is recognized as a GCU unit.+func isGCUUnit(unit string) bool {+ _, _, gcuUnit := unitFactor(strings.TrimSuffix(strings.ToLower(unit), "s"), gcuUnits)+ return gcuUnit+}++func gcuLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bool) {+ fromUnit = strings.TrimSuffix(strings.ToLower(fromUnit), "s")+ toUnit = strings.TrimSuffix(strings.ToLower(toUnit), "s")+ uf := func(unit string) (string, float64, bool) {+ return unitFactor(unit, gcuUnits)+ }+ as := func(value float64) (float64, string, bool) {+ return autoScale(value, gcuUnits)+ }+ return convertUnit(value, fromUnit, toUnit, unit{"GCU", []string{}, 1.0}, uf, as)+}++// convertUnit converts a value from the fromUnit to the toUnit, autoscaling+// the value if the toUnit is "minimum" or "auto". If the fromUnit is not+// included in units, then a false boolean will be returned. If the toUnit+// is not in units, the value will be returned in terms of the default unit.+func convertUnit(value int64, fromUnit, toUnit string, defaultUnit unit, unitFactor func(string) (string, float64, bool), autoScale func(float64) (float64, string, bool)) (v float64, u string, ok bool) {+ _, fromUnitFactor, ok := unitFactor(fromUnit)+ if !ok { return 0, "", false } + v = float64(value) * fromUnitFactor+ if toUnit == "minimum" || toUnit == "auto" {- switch {- case d < 1*time.Microsecond:- toUnit = "ns"- case d < 1*time.Millisecond:- toUnit = "us"- case d < 1*time.Second:- toUnit = "ms"- case d < 1*time.Minute:- toUnit = "sec"- case d < 1*time.Hour:- toUnit = "min"- case d < 24*time.Hour:- toUnit = "hour"- case d < 15*24*time.Hour:- toUnit = "day"- case d < 120*24*time.Hour:- toUnit = "week"- default:- toUnit = "year"+ if v, u, ok := autoScale(v); ok {+ return v, u, true }+ return v / defaultUnit.factor, defaultUnit.canonicalName, true } - var output float64- dd := float64(d)- switch toUnit {- case "ns", "nanosecond":- output, toUnit = dd/float64(time.Nanosecond), "ns"- case "us", "microsecond":- output, toUnit = dd/float64(time.Microsecond), "us"- case "ms", "millisecond":- output, toUnit = dd/float64(time.Millisecond), "ms"- case "min", "minute":- output, toUnit = dd/float64(time.Minute), "mins"- case "hour", "hr":- output, toUnit = dd/float64(time.Hour), "hrs"- case "day":- output, toUnit = dd/float64(24*time.Hour), "days"- case "week", "wk":- output, toUnit = dd/float64(7*24*time.Hour), "wks"- case "year", "yr":- output, toUnit = dd/float64(365*24*time.Hour), "yrs"- default:- // "sec", "second", "s" handled by default case.- output, toUnit = dd/float64(time.Second), "s"+ toUnit, toUnitFactor, ok := unitFactor(toUnit)+ if !ok {+ return v / defaultUnit.factor, defaultUnit.canonicalName, true+ }+ return v / toUnitFactor, toUnit, true+}++// unitFactor returns the canonical name for the unit, the factor by which one+// must multiply a value specified in terms of unit in order to get the value+// specified in terms of the base unit, and a boolean to indicated if a unit+// was identified for the specified unit within the slice units.+func unitFactor(unit string, units []unit) (string, float64, bool) {
This is optional, but I would consider a couple of things API-wise, see WDYT.
We could make []unit a type so that it can be a receiver. I'd also name unitFactor as findByAlias and return *unit from it - the reason is that it returns more than just the factor, it pretty much searches for a unit by alias.
Having a knownUnit function could simplify isTimeUnit / isMemoryUnit / isGCUUnit a bit.
So, something like:
type unitList []unit
...
// findByAlias .... Returns nil if the unit with such alias is not found.
func (us unitList) findByAlias(alias string) *unit {
...
}
func (us unitList) autoScale(...) ... {
...
}
func (us unitList) sniffUnit(unit string) *unit {
return us.findByAlias(strings.TrimSuffix(strings.ToLower(unit), "s"))
}
With this, I think you could remove isTimeUnit and its friends as it simply becomes if timeUnits.sniffUnit(s) != nil.
I think convertUnit would also simplify, since now it can also accept a receiver and it doesn't need to accept the function pointers. I could be wrong on this, but I feel that this can simplify.
comment created time in 8 days
Pull request review commentgoogle/pprof
func timeLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bo toUnit = strings.TrimSuffix(toUnit, "s") } - var d time.Duration- switch fromUnit {- case "nanosecond", "ns":- d = time.Duration(value) * time.Nanosecond- case "microsecond":- d = time.Duration(value) * time.Microsecond- case "millisecond", "ms":- d = time.Duration(value) * time.Millisecond- case "second", "sec", "s":- d = time.Duration(value) * time.Second- case "cycle":+ if fromUnit == "cycle" { return float64(value), "", true- default:+ }++ uf := func(unit string) (string, float64, bool) {+ return unitFactor(unit, timeUnits)+ }+ as := func(value float64) (float64, string, bool) {+ return autoScale(value, timeUnits)+ }+ return convertUnit(value, fromUnit, toUnit, unit{"s", []string{}, float64(time.Second)}, uf, as)+}++var caseInsensitiveGCUUnits = []unit{+ {"n*GCU", []string{"nanogcu"}, 1e-9},+ {"u*GCU", []string{"microgcu"}, 1e-6},+ {"m*GCU", []string{"milligcu"}, 1e-3},+ {"GCU", []string{"gcu"}, 1},+ {"k*GCU", []string{"kilogcu"}, 1e3},+ {"M*GCU", []string{"megagcu"}, 1e6},+ {"G*GCU", []string{"gigagcu"}, 1e9},+ {"T*GCU", []string{"teragcu"}, 1e12},+ {"P*GCU", []string{"petagcu"}, 1e15},+}++var caseSensitiveGCUUnits = []unit{
Removed this.
comment created time in 8 days
PR closed google/pprof
When @wyk9787 was importing pprof code from here into our internal repository, a test failed with the error undefined: math.Round.
This change removes the usage of math.Round to allow for import of pprof (I manually applied this change while importing pprof and tests built and passed).
I'm open to other fixes; just want to be sure we unblock importing pprof.
pr closed time in 8 days
pull request commentgoogle/pprof
Stop using math.Round to allow for pprof import
There is offline discussion on this, let's resolve that first. It's unclear that supporting pre-1.10 go versions is something we want to do.
comment created time in 8 days
pull request commentgoogle/pprof
Stop using math.Round to allow for pprof import
It would be nice to understand why this happened - is this Go version incompatibility or what? I'd be surprised if math.Round is particularly new.
comment created time in 8 days