ptrace arm64

273 views
Skip to first unread message

matt

unread,
May 29, 2015, 10:06:04 AM5/29/15
to golan...@googlegroups.com
Has anyone successfully used ptrace on an ARMv8 platform through the golang syscall api?

I'm attempting to do something similar to the ogle framework (github.com/golang/debug/blob/master/ogle/demo/ptrace-linux-amd64/main.go) replacing amd64 specifics with arm64^w AArch64 specifics.

The code snippet can be found here: http://play.golang.org/p/nwzdhJwCoX

When attempting to do a PtraceGetRegs I get "input/output error" returned. Which I'm guessing is an EIO error returned from the syscall. Looks like I'm able to peek/poke the processes memory, but unlike gdb I am unable to read/write the registers.

Anybody got any suggestions?

// Matt

Aram Hăvărneanu

unread,
May 29, 2015, 10:35:05 AM5/29/15
to matt, golang-nuts
Yes, when I did the arm64 port, I wrote some programs that used ptrace
in order to debug what's going on.

https://github.com/4ad/mgk.ro/blob/2e283210e5c3720e7612cd4b8a9fb1500ec264bc/cmd/gotrace/gotrace.go

--
Aram Hăvărneanu

matt

unread,
May 29, 2015, 12:04:37 PM5/29/15
to golan...@googlegroups.com, matthew....@gmail.com
Compiled, Ran.. bang! any ideas??

gotrace: disabling tracing... (this might take a while)
panic: runtime error: invalid memory address or nil pointer dereference
        panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x8f9b0]

goroutine 1 [running]:
io.(*PipeWriter).CloseWithError(0x0, 0x0, 0x0, 0x0, 0x0)
        /work/go/go/src/io/pipe.go:176 +0x30
io.(*PipeWriter).Close(0x0, 0x0, 0x0)
        /work/go/go/src/io/pipe.go:167 +0x40
main.cleanup()
        /work/me/go/src/mgk.ro/cmd/gotrace/gotrace.go:90 +0x100
debug/elf.(*Section).Data(0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /work/go/go/src/debug/elf/file.go:78 +0x3c
mgk.ro/godebug.NewProg(0x4208001180, 0x420800a260, 0x0, 0x0)
        /work/me/go/src/mgk.ro/godebug/godebug.go:46 +0x1dc
main.findprobes()
        /work/me/go/src/mgk.ro/cmd/gotrace/gotrace.go:137 +0x58
main.main()
        /work/me/go/src/mgk.ro/cmd/gotrace/gotrace.go:225 +0x68

goroutine 5 [runnable]:
os/signal.loop()
        /work/go/go/src/os/signal/signal_unix.go:20
created by os/signal.init.1
        /work/go/go/src/os/signal/signal_unix.go:28 +0x4c

goroutine 6 [runnable, locked to thread]:
runtime.gopark(0x263988, 0x4208014298, 0x215e70, 0x9, 0x4208016d16, 0x3)
        /work/go/go/src/runtime/proc.go:185 +0x188
runtime.goparkunlock(0x4208014298, 0x215e70, 0x9, 0x4208000116, 0x3)
        /work/go/go/src/runtime/proc.go:191 +0x5c
runtime.chansend(0x16ff20, 0x4208014240, 0x4208020718, 0x1, 0x64284, 0x2)
        /work/go/go/src/runtime/chan.go:198 +0x4d4
runtime.chansend1(0x16ff20, 0x4208014240, 0x4208020718)
        /work/go/go/src/runtime/chan.go:92 +0x40
runtime.ensureSigM.func1()
        /work/go/go/src/runtime/signal1_unix.go:201 +0x3c4
runtime.goexit()
        /work/go/go/src/runtime/asm_arm64.s:988 +0x4

goroutine 7 [runnable]:
main.signals.func1(0x42080141e0)
        /work/me/go/src/mgk.ro/cmd/gotrace/gotrace.go:123
created by main.signals
        /work/me/go/src/mgk.ro/cmd/gotrace/gotrace.go:126 +0x120

Aram Hăvărneanu

unread,
May 29, 2015, 12:20:43 PM5/29/15
to matt, golang-nuts
You are running the latest version of gotrace, instead of the
ptrace-based version (see the commit SHA1 in my previous message), and
you are running it on a kernel that doesn't have uprobes (e.g. an
unpatched one).

--
Aram Hăvărneanu

matt

unread,
May 29, 2015, 12:40:43 PM5/29/15
to golan...@googlegroups.com, matthew....@gmail.com
Ah yes, my bad. That works, but has the same issue as my snippet, I get a input/output error when making a call to PtraceGetRegs.

...
gotrace: added breakpoint at 0x443560 (_dl_allocate_tls)
gotrace: added breakpoint at 0x43b65c (fdopendir)
gotrace: added breakpoint at 0x413d88 (pvalloc)
gotrace: added breakpoint at 0x438c1c (gettimeofday)
gotrace: added breakpoint at 0x43b628 (__getdents64)
gotrace: input/output error

Perhaps I need some additional permissions enabled.

// Matt

matt

unread,
May 29, 2015, 5:18:09 PM5/29/15
to golan...@googlegroups.com
Curiously using my own method and calls to the syscall.Syscall6 primitive I can get the registers and fp regs using the PTRACE_GETREGSET and PTRACE_SETREGSET calls.

I'm curious why these haven't been added to the syscall package, given that GETREGS and SETREGS are to be deprecated eventually.

// Matt

Ian Lance Taylor

unread,
May 29, 2015, 5:33:40 PM5/29/15
to matt, golang-nuts
On Fri, May 29, 2015 at 2:18 PM, matt <matthew....@gmail.com> wrote:
>
> Curiously using my own method and calls to the syscall.Syscall6 primitive I
> can get the registers and fp regs using the PTRACE_GETREGSET and
> PTRACE_SETREGSET calls.
>
> I'm curious why these haven't been added to the syscall package, given that
> GETREGS and SETREGS are to be deprecated eventually.

The syscall package is frozen. They are in the golang.org/x/sys/unix
package.

Ian

Matthew Horsnell

unread,
May 29, 2015, 5:41:17 PM5/29/15
to Ian Lance Taylor, golang-nuts
Hmm I can only see PtraceGetRegs in x/sys/unix?

https://github.com/golang/sys/blob/04f0f96bfaf771fb288e160e8488fb96562ee3e0/unix/syscall_linux.go
should I be looking elsewhere?

// Matt

Ian Lance Taylor

unread,
May 29, 2015, 6:02:12 PM5/29/15
to Matthew Horsnell, golang-nuts
On Fri, May 29, 2015 at 2:40 PM, Matthew Horsnell
<matthew....@gmail.com> wrote:
> Hmm I can only see PtraceGetRegs in x/sys/unix?
>
> https://github.com/golang/sys/blob/04f0f96bfaf771fb288e160e8488fb96562ee3e0/unix/syscall_linux.go
> should I be looking elsewhere?

Sorry, I probably looked at the wrong thing. PTRACE_GETREGSET is
defined. But you're right that there is no PtraceGetRegset function.
And I guess that the NT_xxx constants aren't defined either. So there
is clearly some work to do here.

Ian

matt

unread,
May 30, 2015, 1:41:17 PM5/30/15
to golan...@googlegroups.com
Worth pushing a patch?

Ian Lance Taylor

unread,
May 30, 2015, 1:45:29 PM5/30/15
to matt, golang-nuts
On Sat, May 30, 2015 at 10:41 AM, matt <matthew....@gmail.com> wrote:
> Worth pushing a patch?

To golang.org/x/sys, absolutely.

Ian

eric fang

unread,
Oct 18, 2019, 7:43:47 AM10/18/19
to golang-nuts
Hi Ian, go-delve for arm64 (https://github.com/go-delve/delve/issues/1715) also encountered this problem, I want to fix this problem. unix.PtraceGetRegsArm64 may be not work on Linux arm64 since version 2.6.34, because PTRACE_GETREGS has been replaced with PTRACE_GETREGSET, no longer support PTRACE_GETREGS. PTRACE_GETREGSET needs to work with different NT_XXX values, and the current API unix.PtraceGetRegSetArm64 obviously does not have such scalability. So I think we may need to add a new API, such as unix.PtraceGetRegSetArm64(pid int, addr int, regsout *PtraceRegsArm64). What do you think?

Ian Lance Taylor

unread,
Oct 18, 2019, 3:58:31 PM10/18/19
to eric fang, golang-nuts
On Fri, Oct 18, 2019 at 4:44 AM eric fang <eric...@arm.com> wrote:
>
> Hi Ian, go-delve for arm64 (https://github.com/go-delve/delve/issues/1715) also encountered this problem, I want to fix this problem. unix.PtraceGetRegsArm64 may be not work on Linux arm64 since version 2.6.34, because PTRACE_GETREGS has been replaced with PTRACE_GETREGSET, no longer support PTRACE_GETREGS. PTRACE_GETREGSET needs to work with different NT_XXX values, and the current API unix.PtraceGetRegSetArm64 obviously does not have such scalability. So I think we may need to add a new API, such as unix.PtraceGetRegSetArm64(pid int, addr int, regsout *PtraceRegsArm64). What do you think?

It's not clear to me that we support arm64 GNU/Linux for versions
before 2.6.34 at all, so perhaps we should just change the existing
function to use GETREGSET and take an additional argument. This will
require changing the generating program in x/sys/unix/linux.

Ian
Reply all
Reply to author
Forward
0 new messages