Skip to content
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

Merged
merged 2 commits into from
Jul 7, 2023
Merged

delve: add ppc64le support #2963

merged 2 commits into from
Jul 7, 2023

Conversation

alexsaezm
Copy link
Contributor

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.

@derekparker
Copy link
Member

derekparker commented Jul 5, 2022

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.

@aarzilli
Copy link
Member

Is this marked as Draft by accident or is it still a draft?

@alexsaezm
Copy link
Contributor Author

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...?

@aarzilli
Copy link
Member

No problem, I just thought I'd remind you.

@alexsaezm
Copy link
Contributor Author

Removed the draft status. Some tests are still failing but it is functional.

Related issue #1564

@derekparker
Copy link
Member

@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.

Copy link
Member

@aarzilli aarzilli left a 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/ppc64le_arch.go Outdated Show resolved Hide resolved
pkg/dwarf/regnum/ppc64le.go Show resolved Hide resolved
pkg/dwarf/regnum/ppc64le.go Outdated Show resolved Hide resolved
@@ -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
Copy link
Member

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:

  1. there should be a PR to fix it against cmd/link
  2. the disassembly method should be used

Copy link
Member

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.

Copy link
Member

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 Show resolved Hide resolved
pkg/proc/target_exec.go Outdated Show resolved Hide resolved
pkg/proc/target_exec.go Outdated Show resolved Hide resolved
pkg/proc/target_exec.go Outdated Show resolved Hide resolved
pkg/proc/target_exec.go Show resolved Hide resolved
pkg/proc/target_exec.go Outdated Show resolved Hide resolved
pkg/dwarf/regnum/ppc64le.go Outdated Show resolved Hide resolved
@@ -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
Copy link
Member

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/bininfo.go Show resolved Hide resolved
pkg/proc/linutil/regs_ppc64le_arch.go Outdated Show resolved Hide resolved
pkg/proc/linutil/regs_ppc64le_arch.go Outdated Show resolved Hide resolved
pkg/proc/native/threads_linux_ppc64le.go Outdated Show resolved Hide resolved
@@ -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",
Copy link
Member

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.

@@ -158,6 +158,9 @@ func (g *G) Stacktrace(depth int, opts StacktraceOptions) ([]Stackframe, error)
if err != nil {
return nil, err
}
if it.err != nil {
Copy link
Member

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.

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)
Copy link
Member

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.

@alexsaezm
Copy link
Contributor Author

I updated the PR with several modifications according to your comments @aarzilli & @derekparker

@aarzilli
Copy link
Member

aarzilli commented Mar 8, 2023

I'll take a better look tomorrow but also there are several failing tests on existing platforms.

Copy link
Member

@aarzilli aarzilli left a 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.

case num <= 31:
return fmt.Sprintf("R%d", num)
case num <= 62:
return fmt.Sprintf("F%d", num)
Copy link
Member

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

case num == PPC64LE_PC:
return "PC"
case num == PPC64LE_LR:
return "Link"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LR

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
Copy link
Member

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?

case num == PPC64LE_LR:
return "Link"
case num >= PPC64LE_V0 && num <= 108:
return fmt.Sprintf("V%d", num-64)
Copy link
Member

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?


const (
PPC64LE_R0 = 0 // General Purpose Registers: from R0 to R31
PPC64LE_F0 = 0 // Floating point registers: from F0 to F31
Copy link
Member

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?

// 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"),
Copy link
Member

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
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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.
Copy link
Member

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.

@@ -586,6 +586,7 @@ func TestNextGeneral(t *testing.T) {
}

func TestNextConcurrent(t *testing.T) {
skipOn(t, "broken", "freebsd")
Copy link
Member

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.

Copy link
Contributor Author

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.

@@ -211,6 +226,9 @@ func (it *stackIterator) Next() bool {
}

callFrameRegs, ret, retaddr := it.advanceRegs()
if it.err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still wondering about this.

@@ -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
Copy link
Member

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.

@@ -3337,7 +3337,7 @@ func TestCgoStacktrace(t *testing.T) {
}

skipOn(t, "broken - cgo stacktraces", "386")
skipOn(t, "broken - cgo stacktraces", "windows", "arm64")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge problem

Copy link
Contributor Author

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

@@ -3900,6 +3903,9 @@ func TestInlinedStacktraceAndVariables(t *testing.T) {
}

func TestInlineStep(t *testing.T) {
if runtime.GOARCH == "ppc64le" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skipOn(t, "broken", "ppc64le")

@@ -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")
Copy link
Member

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

@@ -858,6 +858,7 @@ func Test1Issue355(t *testing.T) {
}

func Test1Disasm(t *testing.T) {
t.Skip("skipped on ppc64le: broken")
Copy link
Member

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

@@ -1359,6 +1359,7 @@ func TestIssue355(t *testing.T) {
}

func TestDisasm(t *testing.T) {
t.Skip("skipped on ppc64le: broken")
Copy link
Member

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

@@ -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")
Copy link
Member

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

pkg/proc/ppc64le_arch.go Outdated Show resolved Hide resolved
@@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover print.

pkg/dwarf/regnum/ppc64le.go Show resolved Hide resolved
@@ -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
Copy link
Member

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/bininfo.go Show resolved Hide resolved
pkg/proc/ppc64le_arch.go Outdated Show resolved Hide resolved
@@ -2863,6 +2873,7 @@ func TestNextInDeferReturn(t *testing.T) {
}

func TestAttachDetach(t *testing.T) {
skipOn(t, "broken", "ppc64le")
Copy link
Member

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")
Copy link
Member

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")
Copy link
Member

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?

@@ -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" {
Copy link
Member

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" {
Copy link
Member

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?

if entryLine == line {
return pc, nil
}
pc, _, line, ok := fn.cu.lineInfo.PrologueEndPC(fn.Entry, fn.End)
Copy link
Member

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
Copy link
Member

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.

Copy link
Contributor Author

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

Copy link
Member

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.

Copy link
Member

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
Copy link
Member

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.

}
}

// According to LLDB's documentation, there is 172 registers in total, across 4 categories:
Copy link
Member

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.

@aarzilli
Copy link
Member

aarzilli commented Jul 7, 2023

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.

@aarzilli
Copy link
Member

aarzilli commented Jul 7, 2023

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.

@alexsaezm
Copy link
Contributor Author

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.

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.

I'll squash the whole thing because there's a lot of commits that means nothing.

@alexsaezm
Copy link
Contributor Author

alexsaezm commented Jul 7, 2023

Squashed and rebased, hopefully now we can find out what is going on.

Copy link
Member

@aarzilli aarzilli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@alexsaezm
Copy link
Contributor Author

alexsaezm commented Jul 7, 2023

Looks like TestFindReturnAddressTopOfStackFn now fails (on ppc64le)... working on it 😞

@aarzilli
Copy link
Member

aarzilli commented Jul 7, 2023

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.

@derekparker
Copy link
Member

Looks like all that's needed now is to fix TestGeneratedDoc and then this is good to merge.

@alexsaezm
Copy link
Contributor Author

Looks like all that's needed now is to fix TestGeneratedDoc and then this is good to merge.

Done

pkg/proc/ppc64le_arch.go Outdated Show resolved Hide resolved
pkg/proc/ppc64le_arch.go Outdated Show resolved Hide resolved
pkg/proc/proc_test.go Outdated Show resolved Hide resolved
pkg/proc/proc_test.go Outdated Show resolved Hide resolved
Copy link
Member

@derekparker derekparker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@derekparker derekparker merged commit 71f1220 into go-delve:master Jul 7, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants