-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
delve: add ppc64le support #2963
Conversation
Adding the v1.9.1 milestone as I'd like to get this in for the next release. Of course this also depends on CI availability so we might slip a bit, but I wanted to at least aim for it to be included. |
Is this marked as Draft by accident or is it still a draft? |
It's still not 100% functional so I guess it's still a draft...? |
No problem, I just thought I'd remind you. |
cdb245e
to
3e42216
Compare
Removed the draft status. Some tests are still failing but it is functional. Related issue #1564 |
@alexsaezm thanks for this! Any test that is still failing please just skip explicitly and provide some explanation. We can work on adding CI for this as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's going to be a builder for teamcity there should be a builder for teamcity before this is merged. If there isn't going to be a builder for teamcity this should be gated behind a build flag in support_sentinel_linux.go much like the windows/arm64 backend is gated behind a build flag in support_sentinel_window.go.
pkg/proc/bininfo.go
Outdated
@@ -365,8 +366,19 @@ func FindFunctionLocation(p Process, funcName string, lineOffset int) ([]uint64, | |||
// If sameline is set FirstPCAfterPrologue will always return an | |||
// address associated with the same line as fn.Entry. | |||
func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error) { | |||
// The DWARF prologue_end statement is incorrect in ppc64le and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very skeptical that this code can be correct. How does this skip the prologue? Not skipping the prologue will cause a number of problems. If the prologue_end position is wrong then:
- there should be a PR to fix it against cmd/link
- the disassembly method should be used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, we should be using the disassembly method as with other arches. Looks like we just need to update the disassemble patterns for matching against.
Also, I'll look into the upstream patch to fix the prologue_end position.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've taken a second look at this, the patch to add prologue_end markers (63fd764502e08d067293a93d6d1a566951255ce5) still looks correct to me, even when observing where the prologue_end marker is placed in the executables.
pkg/proc/bininfo.go
Outdated
@@ -365,8 +366,19 @@ func FindFunctionLocation(p Process, funcName string, lineOffset int) ([]uint64, | |||
// If sameline is set FirstPCAfterPrologue will always return an | |||
// address associated with the same line as fn.Entry. | |||
func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error) { | |||
// The DWARF prologue_end statement is incorrect in ppc64le and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, we should be using the disassembly method as with other arches. Looks like we just need to update the disassemble patterns for matching against.
Also, I'll look into the upstream patch to fix the prologue_end position.
pkg/proc/proc_test.go
Outdated
@@ -3324,6 +3324,11 @@ func logStacktrace(t *testing.T, p *proc.Target, frames []proc.Stackframe) { | |||
name = fmt.Sprintf("%s inlined in %s", frames[j].Call.Fn.Name, frames[j].Current.Fn.Name) | |||
} | |||
|
|||
t.Logf("\t%#x %#x %#x %s at %s:%d\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a rebase error but I agree this should be removed.
pkg/proc/stack.go
Outdated
@@ -158,6 +158,9 @@ func (g *G) Stacktrace(depth int, opts StacktraceOptions) ([]Stackframe, error) | |||
if err != nil { | |||
return nil, err | |||
} | |||
if it.err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was done to not hide there error when the full stack could not be unwound, because otherwise it gets hidden. Can likely be removed now.
pkg/proc/stack.go
Outdated
switch rule.Rule { | ||
default: | ||
fallthrough | ||
case frame.RuleUndefined: | ||
return nil, nil | ||
case frame.RuleSameVal: | ||
if it.regs.Reg(regnum) == nil { | ||
return nil, nil | ||
return nil, fmt.Errorf("register %d undefined", regnum) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we can just return nil here.
I updated the PR with several modifications according to your comments @aarzilli & @derekparker |
I'll take a better look tomorrow but also there are several failing tests on existing platforms. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I marked a bunch of things as merge errors but it could also be that github is being weird about the diff because of the merge conflict in proc_test.go.
pkg/dwarf/regnum/ppc64le.go
Outdated
case num <= 31: | ||
return fmt.Sprintf("R%d", num) | ||
case num <= 62: | ||
return fmt.Sprintf("F%d", num) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Judging from the reference document this should be num-32
pkg/dwarf/regnum/ppc64le.go
Outdated
case num == PPC64LE_PC: | ||
return "PC" | ||
case num == PPC64LE_LR: | ||
return "Link" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LR
pkg/dwarf/regnum/ppc64le.go
Outdated
const ( | ||
PPC64LE_R0 = 0 // General Purpose Registers: from R0 to R31 | ||
PPC64LE_F0 = 0 // Floating point registers: from F0 to F31 | ||
PPC64LE_V0 = 0 // Vector (Altivec/VMX) registers: from V0 to V31 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the same as VR0? Shouldn't it be 77?
pkg/dwarf/regnum/ppc64le.go
Outdated
case num == PPC64LE_LR: | ||
return "Link" | ||
case num >= PPC64LE_V0 && num <= 108: | ||
return fmt.Sprintf("V%d", num-64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should 64 be PPC64LE_V0?
pkg/dwarf/regnum/ppc64le.go
Outdated
|
||
const ( | ||
PPC64LE_R0 = 0 // General Purpose Registers: from R0 to R31 | ||
PPC64LE_F0 = 0 // Floating point registers: from F0 to F31 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be 32?
pkg/proc/native/proc.go
Outdated
// with gdb once AsyncPreempt was enabled. While implementing the port, | ||
// few tests failed while it was enabled, but cannot be warrantied that | ||
// disabling it fixed the issues. | ||
DisableAsyncPreempt: runtime.GOOS == "windows" || runtime.GOOS == "freebsd" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64") || (runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Readding freebsd here is also a merge error.
@@ -1,6 +1,6 @@ | |||
// This file is used to detect build on unsupported GOOS/GOARCH combinations. | |||
|
|||
//go:build linux && !amd64 && !arm64 && !386 | |||
// +build linux,!amd64,!arm64,!386 | |||
//go:build linux && !amd64 && !arm64 && !386 && !ppc64le |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the story going to be with CI? Are we going to have a ppc64 builder? Otherwise we should do the same thing we did with windows/arm64 and put it behind a build tag I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I requested a PPC64LE machine to put it into the CI system. I already have it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the status on getting TeamCity agent installed there?
var prologuesPPC64LE []opcodeSeq | ||
|
||
func init() { | ||
// Note: these will be the gnu opcodes and not the Go opcodes. Verify the sequences are as expected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't think these should be here unless the comment in FirstPCAfterPrologue is wrong.
pkg/proc/proc_test.go
Outdated
@@ -586,6 +586,7 @@ func TestNextGeneral(t *testing.T) { | |||
} | |||
|
|||
func TestNextConcurrent(t *testing.T) { | |||
skipOn(t, "broken", "freebsd") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bunch of these have been reintroduced due to merge errors. In fact a lot of changes in this file seem to be merge errors and should be rolled back.
Unless maybe there are no merge errors and github UI is just lying to me because of the merge conflict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a merge error as you said. I think is now fixed.
pkg/proc/stack.go
Outdated
@@ -211,6 +226,9 @@ func (it *stackIterator) Next() bool { | |||
} | |||
|
|||
callFrameRegs, ret, retaddr := it.advanceRegs() | |||
if it.err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still wondering about this.
pkg/proc/bininfo.go
Outdated
@@ -365,8 +366,19 @@ func FindFunctionLocation(p Process, funcName string, lineOffset int) ([]uint64, | |||
// If sameline is set FirstPCAfterPrologue will always return an | |||
// address associated with the same line as fn.Entry. | |||
func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error) { | |||
// The DWARF prologue_end statement is incorrect in ppc64le and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've taken a second look at this, the patch to add prologue_end markers (63fd764502e08d067293a93d6d1a566951255ce5) still looks correct to me, even when observing where the prologue_end marker is placed in the executables.
pkg/proc/proc_test.go
Outdated
@@ -3337,7 +3337,7 @@ func TestCgoStacktrace(t *testing.T) { | |||
} | |||
|
|||
skipOn(t, "broken - cgo stacktraces", "386") | |||
skipOn(t, "broken - cgo stacktraces", "windows", "arm64") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merge problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's now fixed
pkg/proc/proc_test.go
Outdated
@@ -3900,6 +3903,9 @@ func TestInlinedStacktraceAndVariables(t *testing.T) { | |||
} | |||
|
|||
func TestInlineStep(t *testing.T) { | |||
if runtime.GOARCH == "ppc64le" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skipOn(t, "broken", "ppc64le")
service/dap/server_test.go
Outdated
@@ -2465,6 +2465,7 @@ func TestGlobalScopeAndVariables(t *testing.T) { | |||
// got loaded. It then steps into a function in another package and tests that | |||
// the registers were updated by checking PC. | |||
func TestRegistersScopeAndVariables(t *testing.T) { | |||
t.Skip("skipped on ppc64le: broken") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be guarded by an if
service/test/integration1_test.go
Outdated
@@ -858,6 +858,7 @@ func Test1Issue355(t *testing.T) { | |||
} | |||
|
|||
func Test1Disasm(t *testing.T) { | |||
t.Skip("skipped on ppc64le: broken") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be guarded by an if
service/test/integration2_test.go
Outdated
@@ -1359,6 +1359,7 @@ func TestIssue355(t *testing.T) { | |||
} | |||
|
|||
func TestDisasm(t *testing.T) { | |||
t.Skip("skipped on ppc64le: broken") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be guarded by an if
service/test/integration2_test.go
Outdated
@@ -2855,6 +2856,7 @@ func assertLine(t *testing.T, state *api.DebuggerState, file string, lineno int) | |||
} | |||
|
|||
func TestPluginSuspendedBreakpoint(t *testing.T) { | |||
t.Skip("skipped on ppc64le: broken") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be guarded by an if
cmd/dlv/cmds/commands.go
Outdated
@@ -690,6 +690,7 @@ func traceCmd(cmd *cobra.Command, args []string) { | |||
fmt.Fprintf(os.Stderr, "unable to set tracepoint on function %s: %#v\n", funcs[i], err) | |||
continue | |||
} | |||
fmt.Fprintf(os.Stderr, "Addrs %#v\n", addrs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover print.
@@ -1,6 +1,6 @@ | |||
// This file is used to detect build on unsupported GOOS/GOARCH combinations. | |||
|
|||
//go:build linux && !amd64 && !arm64 && !386 | |||
// +build linux,!amd64,!arm64,!386 | |||
//go:build linux && !amd64 && !arm64 && !386 && !ppc64le |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the status on getting TeamCity agent installed there?
pkg/proc/proc_test.go
Outdated
@@ -2863,6 +2873,7 @@ func TestNextInDeferReturn(t *testing.T) { | |||
} | |||
|
|||
func TestAttachDetach(t *testing.T) { | |||
skipOn(t, "broken", "ppc64le") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test shouldn't be arch specfic, unless it's failing on PIE on ppc.
@@ -3920,6 +3935,7 @@ func TestInlinedStacktraceAndVariables(t *testing.T) { | |||
} | |||
|
|||
func TestInlineStep(t *testing.T) { | |||
skipOn(t, "broken", "ppc64le") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be arch specific, what's the failure in ppc?
@@ -4080,6 +4096,7 @@ func TestIssue951(t *testing.T) { | |||
} | |||
|
|||
func TestDWZCompression(t *testing.T) { | |||
skipOn(t, "broken", "ppc64le") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be broken based on arch, what's the failure?
pkg/proc/proc_test.go
Outdated
@@ -5838,6 +5864,9 @@ func TestNilPtrDerefInBreakInstr(t *testing.T) { | |||
func TestStepIntoAutogeneratedSkip(t *testing.T) { | |||
// Tests that autogenerated functions are skipped with the new naming | |||
// scheme for autogenerated functions (issue #2948). | |||
if runtime.GOARCH == "ppc64le" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use skipOn
.
@@ -2457,6 +2457,9 @@ func TestGlobalScopeAndVariables(t *testing.T) { | |||
// got loaded. It then steps into a function in another package and tests that | |||
// the registers were updated by checking PC. | |||
func TestRegistersScopeAndVariables(t *testing.T) { | |||
if runtime.GOARCH == "ppc64le" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the failure on ppc?
pkg/proc/bininfo.go
Outdated
if entryLine == line { | ||
return pc, nil | ||
} | ||
pc, _, line, ok := fn.cu.lineInfo.PrologueEndPC(fn.Entry, fn.End) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this undoing the changes for the no-dwarf stuff?
@@ -76,3 +76,11 @@ else | |||
exit $x | |||
fi | |||
|
|||
export GOARCH=ppc64le | |||
go run _scripts/make.go --tags exp.linuxppc64le |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a bunch of test failures in CI, I think this might be what's causing them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was the TestGeneratedDoc. It should be fix now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right: this isn't even running currently in CI because other failures (TestStaticcheck) are causing the script to exit before this is even executed. However I don't think it's going to work. The export GOARCH=ppc64le
makes go run
produce a ppc64le binary for make.go, which won't run.
I think the way to do this is to do GOARCH=ppc64le go build -tags exp.linuxppc64le github.com/go-delve/delve/cmd/dlv
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests now pass, this line however is never executed because of the exit above.
@@ -76,3 +76,11 @@ else | |||
exit $x | |||
fi | |||
|
|||
export GOARCH=ppc64le | |||
go run _scripts/make.go --tags exp.linuxppc64le |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right: this isn't even running currently in CI because other failures (TestStaticcheck) are causing the script to exit before this is even executed. However I don't think it's going to work. The export GOARCH=ppc64le
makes go run
produce a ppc64le binary for make.go, which won't run.
I think the way to do this is to do GOARCH=ppc64le go build -tags exp.linuxppc64le github.com/go-delve/delve/cmd/dlv
directly.
pkg/dwarf/regnum/ppc64le.go
Outdated
} | ||
} | ||
|
||
// According to LLDB's documentation, there is 172 registers in total, across 4 categories: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment needs to start with PPC64LEMaxRegNum or there needs to be an exclusion directive for staticcheck.
I'm not sure what's causing the new test failures on macOS, the only thing that sticks out is the if err return in the stacktracing code. |
PS. builds of master pass the test normally, so it doesn't look like it's something broken in CI but something in this PR. Other possibility is that it's screwing up something with the automatic merge (it's 60 commits), in which case squashing should fix it. |
For some reason ( I think it might be the latest rebase) in linux amd64 several tests fail but they pass on ppc64le. @derekparker suggested me yesterday a change that make it pass again locally but new tests fails on ppc64le.
I'll squash the whole thing because there's a lot of commits that means nothing. |
Squashed and rebased, hopefully now we can find out what is going on. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Looks like |
As far as I am concerned it's fine to merge this with TestFindReturnAddressTopOfStackFn failing on ppc64le, especially since it's behind a build tag. That test isn't that important either. |
Looks like all that's needed now is to fix |
Done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This adds support to PPC64LE architecture. This is still in an early stage of development but I'm opening this draft pull request to keep track of suggestions about the port and other things that might happen.
Currently runtime.Breakpoint is broken for ppc64le so I'm using a patched version of Go.