This is the first time I have had to make calls to native libraries from Go.
I am trying to setup event hooks with the windows libraries to listen for network interface changes, so far I have been successful with setting up a listener with NotifyAddrChange.
Now I am trying with NotifyIpInterfaceChange with the following code
package main
import (
"golang.org/x/sys/windows"
"log"
"syscall"
"unsafe"
)
var (
modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll")
procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange")
)
type context struct{}
func main() {
log.Printf("Loaded [iphlpapi.dll] at {%#v}", modiphlpapi.Handle())
log.Printf("Found [NotifyIpInterfaceChange] at {%#v}", procNotifyIpInterfaceChange.Addr())
context := &context{}
interfaceChange := windows.Handle(0)
ret, _, errNum := procNotifyIpInterfaceChange.Call(syscall.AF_UNSPEC, syscall.NewCallback(callback), uintptr(unsafe.Pointer(context)), 0, uintptr(interfaceChange))
log.Printf("%#v %#v", ret, errNum)
}
func callback(callerContext, row, notificationType uintptr) uintptr {
log.Printf("callback invoked by Windows API (%#v %#v %#v)", callerContext, row, notificationType)
return 0
}
The code compiles fine and starts up without any issue, the problem happens once the function is invoke, then I get the following exception
D:\>event-listen_type2.exe
2017/06/22 22:12:39 Loaded [iphlpapi.dll] at {0x7ffac96f0000}
2017/06/22 22:12:39 Found [NotifyIpInterfaceChange] at {0x7ffac96f7e20}
Exception 0xc0000005 0x1 0x0 0x7ffac96f7edb
PC=0x7ffac96f7edb
syscall.Syscall6(0x7ffac96f7e20, 0x5, 0x0, 0x454170, 0x54d360, 0x0, 0x0, 0x0, 0xc042015350, 0xc042015300, ...)
/usr/local/Cellar/go/1.8.3/libexec/src/runtime/syscall_windows.go:174 +0x6b
github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows.(*Proc).Call(0xc04203a620, 0xc042050300, 0x5, 0x5, 0x30, 0x4b12e0, 0x1, 0xc042050300)
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows/dll_windows.go:139 +0x5c1
github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows.(*LazyProc).Call(0xc042050270, 0xc042050300, 0x5, 0x5, 0x1, 0xc04201a000, 0xc04202df78, 0x4043a3)
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows/dll_windows.go:309 +0x66
main.main()
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/main_windows.go:25 +0x229
rax 0x0
rbx 0xc3f10
rcx 0x1fb5cd87abfd0000
rdi 0x0
rsi 0x454170
rbp 0xc04202dc00
rsp 0x8fdf0
r8 0x8fb78
r9 0x7ffac96fb4c0
r10 0x0
r11 0x8fcf0
r12 0x0
r13 0xffffffee
r14 0x0
r15 0xaa
rip 0x7ffac96f7edb
rflags 0x10246
cs 0x33
fs 0x53
gs 0x2b
From some googling I know that exception type 0xc0000005 is a access violation thrown by the CPU when a program tries to access memory not allocated to it but looking through my code I can't tell where that is happening. All pointers passed are for items in the application.
Any help here would be magnificent.
According to documentation, the latest parameter of NotifyIpInterfaceChange is both in/out and need to be a pointer to HANDLE. Change the system call to:
ret, _, errNum := procNotifyIpInterfaceChange.Call(syscall.AF_UNSPEC,
syscall.NewCallback(callback),
uintptr(unsafe.Pointer(context)),
0,
uintptr(unsafe.Pointer(&interfaceChange))) //this must be pointer
EDIT:
As mentioned in the comment and this go-nuts discussion, for multi-threaded callback, import "C" need to be added, even if we don't use cgo.
Related
This is the scenario that I am working with. I have a 64 bit kernel mode driver project that I'm compiling and building in Visual Studio 2019 Community with the target OS being Windows 8.1 64 bit. This project contains an MyASM.asm file which in turn has a single assembly function defined (see below). The project compiles and builds successfully. So far so good. Now the problem that I'm having is when I try calling this single assembly function from main.cpp file the system crashes by freezing and locking up no BSOD. What can be causing this to happen ? Have I got the syntax correct for the .asm file am I missing anything ?
================================= MyASM.asm file ====================================
EXTERN DbgPrint:PROC
.data
dbgString byte "ATest() routine has been CALLED!\n", 0
.code
main PROC
main ENDP
ATest PROC PUBLIC
;MOV RDX, Offset dbgString
;PUSH [RDX]
;CALL DbgPrint
;POP RDX ;***check to see if DbgPrintEx cleans up the stack***
;RET
SUB RSP, 40h
MOV RCX, offset dbgString
CALL DbgPrint
ADD RSP, 40h
RET
ATest ENDP
END
============================== main.cpp file ==============================
extern "C" void ATest(void);
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath)
{
// NTSTATUS variable to record success or failure
NTSTATUS status = STATUS_SUCCESS;
status = ByePgInitialize(SystemWideExceptionHandler, TRUE);
if (!NT_SUCCESS(status)) return status;
// Allocate the driver configuration object
WDF_DRIVER_CONFIG config;
// Print "Hello World" for DriverEntry
//KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n"));
// Initialize the driver configuration object to register the entry point for the
// EvtDeviceAdd callback, KmdfHelloWorldEvtDeviceAdd
WDF_DRIVER_CONFIG_INIT(&config,
KmdfHelloWorldEvtDeviceAdd
);
// Finally, create the driver object
status = WdfDriverCreate(DriverObject,
RegistryPath,
WDF_NO_OBJECT_ATTRIBUTES,
&config,
WDF_NO_HANDLE
);
if (status != STATUS_SUCCESS)
return STATUS_UNSUCCESSFUL;
else
ATest();
}
A big thanks to fuz and PeterCordes and the source code found here.
main proc
sub rsp, 40h
mov rcx, offset dbgstring
call printf
add rsp, 40h
ret
main endp
My Golang source code is as follows.
package main
func add(x, y int) int {
return x + y
}
func main() {
_ = add(1, 2)
}
The assembly code I obtained using go tool compile -N -l -S main.go > file1.s is as follows(part of it).
;file1.s
"".main STEXT size=54 args=0x0 locals=0x18 funcid=0x0
0x0000 00000 (main.go:7) TEXT "".main(SB), ABIInternal, $24-0
0x0000 00000 (main.go:7) CMPQ SP, 16(R14)
0x0004 00004 (main.go:7) PCDATA $0, $-2
0x0004 00004 (main.go:7) JLS 47
……
0x002f 00047 (main.go:7) CALL runtime.morestack_noctxt(SB)
0x0034 00052 (main.go:7) PCDATA $0, $-1
0x0034 00052 (main.go:7) JMP 0
And the assembly code I obtained using go tool compile -N -l main.go and go tool objdump -S -gnu main.o > file2.s is as follows(part of it).
;file2.s
TEXT "".main(SB) gofile..D:/code/Test/025_go/007_ass/main.go
func main() {
0x5b6 493b6610 CMPQ 0x10(R14), SP // cmp 0x10(%r14),%rsp
0x5ba 7629 JBE 0x5e5 // jbe 0x5e5
……
func main() {
0x5e5 e800000000 CALL 0x5ea // callq 0x5ea [1:5]R_CALL:runtime.morestack_noctxt
0x5ea ebca JMP "".main(SB) // jmp 0x5b6
My questions are:
Why are the source and destination of the CMPQ instructions in file1.s and file2.s opposite, as in CMPQ SP, 16(R14) vs CMPQ 0x10(R14), SP?
For the above two code, my understanding is: when SP <= R14 + 16, call runtime.morestack_noctxt to extend stack. But what I don't understand is: why is SP <= R14 + 16, what is the logic behind? R14 is link register?
Is the code in file2.s a dead loop? Why is it so? Why is the code in file1.s not a dead loop?
What is the meaning of [1:5] in [1:5]R_CALL:runtime.morestack_noctxt in file2.s?
I have a basic knowledge of c++/golang as well as assembly, and I understand the memory layout of programs, but I am really confused about the above questions. Can anyone help me, or what material should I read?
Thank you to everyone who helps me.
Why are the source and destination of the CMPQ instructions in file1.s and file2.s opposite, as in CMPQ SP, 16(R14) vs CMPQ 0x10(R14), SP?
This is likely a bug in the disassembler which I encourage you to file with the Go project. The Go assembler has AT&T operand order for almost all instructions. The CMP family of instructions is a major exception which for easier use has the Intel operand order (i.e. CMPQ foo, bar; JGT baz jumps to baz if foo > bar).
For the above two code, my understanding is: when SP <= R14 + 16, call runtime.morestack_noctxt to extend stack. But what I don't understand is: why is SP <= R14 + 16, what is the logic behind? R14 is link register?
R14 holds a pointer to the g structure corresponding to the currently active Go routine and 0x10(R14) holds the stack limit stackguard0. See user1856856's answer for details. This is a new development following the register ABI proposal. stackguard0 lowest stack address the thread can use before it has to ask the runtime for more stack.
Is the code in file2.s a dead loop? Why is it so? Why is the code in file1.s not a dead loop?
No. When runtime.morestack_noctxt returns, it has changed R14 to the new stack limit, hence the comparison will succeed. It is possible that it will not succeed in which case once again more stack is allocated until it does. This means it is normally not an endless loop.
What is the meaning of [1:5] in [1:5]R_CALL:runtime.morestack_noctxt in file2.s?
This comments hints on the presence of a relocation, indicating that the linker will have to patch in the address of runtime.morestack_noctxt at link time. You can see that the function address in the instruction e800000000 is all zeroes, so as is the call doesn't go anywhere useful. This only changes when the linker resolves the relocation.
for question 2,in amd64 system, R14 is the register that holds the current g,you can check the function
// Append code to p to check for stack split.
// Appends to (does not overwrite) p.
// Assumes g is in rg.
// Returns last new instruction and G register.
func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) (*obj.Prog, int16) {
// emit...
// Load G register
var rg int16
p, rg = loadG(ctxt, cursym, p, newprog)
var q1 *obj.Prog
if framesize <= objabi.StackSmall {
// small stack: SP <= stackguard
// CMPQ SP, stackguard
p = obj.Appendp(p, newprog)
p.As = cmp
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SP
p.To.Type = obj.TYPE_MEM
p.To.Reg = rg
p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if cursym.CFunc() {
p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
and the loadG
func loadG(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc) (*obj.Prog, int16) {
if ctxt.Arch.Family == sys.AMD64 && cursym.ABI() == obj.ABIInternal {
// Use the G register directly in ABIInternal
return p, REGG
}
var regg int16 = REG_CX
if ctxt.Arch.Family == sys.AMD64 {
regg = REGG // == REG_R14
}
and the file in src/cmd/internal/obj/x86/a.out.go
REGG = REG_R14 // g register in ABIInternal
the g structure is
type g struct {
// Stack parameters.
// stack describes the actual stack memory: [stack.lo, stack.hi).
// stackguard0 is the stack pointer compared in the Go stack growth prologue.
// It is stack.lo+StackGuard normally, but can be StackPreempt to trigger a preemption.
// stackguard1 is the stack pointer compared in the C stack growth prologue.
// It is stack.lo+StackGuard on g0 and gsignal stacks.
// It is ~0 on other goroutine stacks, to trigger a call to morestackc (and crash).
stack stack // offset known to runtime/cgo
stackguard0 uintptr // offset known to liblink
stackguard1 uintptr // offset known to liblink
}
and the stack structure is
// Stack describes a Go execution stack.
// The bounds of the stack are exactly [lo, hi),
// with no implicit data structures on either side.
type stack struct {
lo uintptr
hi uintptr
}
so i think an offset(16) to R14 is the value of current g's stackguard0
I'm trying to debug memory issue on Go, i.e. RSS keeps on increasing, no leak is found via pprof, most likely is due to Go not returning memory to OS when it's freed (classic scavenger issue in Go: https://github.com/golang/go/issues/30333)
I'm trying to understand how the memory is allocated into heap and when they are deallocated.
strace doesn't help much so far, so I'm trying to use ltrace
ltrace -e malloc+free go run main.go
Unfortunately, it immediately crashes the program.
Any ideas how to use ltrace on go program? or it's not possible at all?
go->malloc(56) = 0x1f4f010
libpthread.so.0->free(nil) = <void>
go->free(0x1f4f010) = <void>
go->malloc(24) = 0x1f4f050
go->malloc(24) = 0x1f4f2c0
go->malloc(24) = 0x1f4f2c0
go->malloc(24) = 0x1f4f2c0
SIGILL: illegal instruction
PC=0x4aeb5e m=4 sigcode=2
goroutine 9 [syscall]:
syscall.Syscall6(0xf7, 0x1, 0x5865, 0xc000166dc8, 0x1000004, 0x0, 0x0, 0x4d0601, 0xc0003edf20, 0xc000166e08)
/usr/local/go/src/syscall/asm_linux_amd64.s:44 +0x5 fp=0xc000166d78 sp=0xc000166d70 pc=0x4aeb35
os.(*Process).blockUntilWaitable(0xc000027b30, 0x203000, 0xc0002d0000, 0x2)
/usr/local/go/src/os/wait_waitid.go:31 +0x98 fp=0xc000166e68 sp=0xc000166d78 pc=0x4d4db8
os.(*Process).wait(0xc000027b30, 0xa842a0, 0xa842a8, 0xa84298)
/usr/local/go/src/os/exec_unix.go:22 +0x39 fp=0xc000166ee0 sp=0xc000166e68 pc=0x4cca69
os.(*Process).Wait(...)
/usr/local/go/src/os/exec.go:125
os/exec.(*Cmd).Wait(0xc000325b80, 0x0, 0x0)
/usr/local/go/src/os/exec/exec.go:501 +0x60 fp=0xc000166f58 sp=0xc000166ee0 pc=0x50bbc0
os/exec.(*Cmd).Run(0xc000325b80, 0xc000260e10, 0x27)
/usr/local/go/src/os/exec/exec.go:341 +0x5c fp=0xc000166f80 sp=0xc000166f58 pc=0x50b05c
cmd/go/internal/work.(*Builder).toolID(0xc0000a55e0, 0xa3c61a, 0x7, 0xb, 0xc0001673c8)
/usr/local/go/src/cmd/go/internal/work/buildid.go:193 +0x44d fp=0xc000167170 sp=0xc000166f80 pc=0x83a51d
cmd/go/internal/work.(*Builder).buildActionID(0xc0000a55e0, 0xc0002e9400, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/cmd/go/internal/work/exec.go:242 +0x1215 fp=0xc000167588 sp=0xc000167170 pc=0x840c15
cmd/go/internal/work.(*Builder).build(0xc0000a55e0, 0xc0002e9400, 0x0, 0x0)
/usr/local/go/src/cmd/go/internal/work/exec.go:397 +0x52a6 fp=0xc000167e30 sp=0xc000167588 pc=0x847606
cmd/go/internal/work.(*Builder).Do.func2(0xc0002e9400)
/usr/local/go/src/cmd/go/internal/work/exec.go:117 +0x36d fp=0xc000167ef0 sp=0xc000167e30 pc=0x87666d
cmd/go/internal/work.(*Builder).Do.func3(0xc000028d60, 0xc0000a55e0, 0xc0003d9740)
/usr/local/go/src/cmd/go/internal/work/exec.go:177 +0x79 fp=0xc000167fc8 sp=0xc000167ef0 pc=0x876799
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc000167fd0 sp=0xc000167fc8 pc=0x45c4c1
created by cmd/go/internal/work.(*Builder).Do
/usr/local/go/src/cmd/go/internal/work/exec.go:164 +0x3a1
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc000028d68)
/usr/local/go/src/runtime/sema.go:56 +0x42
sync.(*WaitGroup).Wait(0xc000028d60)
/usr/local/go/src/sync/waitgroup.go:130 +0x64
cmd/go/internal/work.(*Builder).Do(0xc0000a55e0, 0xc000152dc0)
/usr/local/go/src/cmd/go/internal/work/exec.go:186 +0x3c5
cmd/go/internal/run.runRun(0xea3d40, 0xc0000201a0, 0x1, 0x1)
/usr/local/go/src/cmd/go/internal/run/run.go:143 +0x54d
main.main()
/usr/local/go/src/cmd/go/main.go:189 +0x57f
goroutine 6 [syscall]:
os/signal.signal_recv(0x0)
/usr/local/go/src/runtime/sigqueue.go:147 +0x9c
os/signal.loop()
/usr/local/go/src/os/signal/signal_unix.go:23 +0x22
created by os/signal.init.0
/usr/local/go/src/os/signal/signal_unix.go:29 +0x41
goroutine 10 [runnable]:
os/exec.(*Cmd).Start.func1(0xc000325b80, 0xc0003d97e0)
/usr/local/go/src/os/exec/exec.go:434
created by os/exec.(*Cmd).Start
/usr/local/go/src/os/exec/exec.go:434 +0x608
goroutine 11 [runnable]:
os/exec.(*Cmd).Start.func1(0xc000325b80, 0xc0003d9820)
/usr/local/go/src/os/exec/exec.go:434
created by os/exec.(*Cmd).Start
/usr/local/go/src/os/exec/exec.go:434 +0x608
rax 0xf0013d48
rbx 0xc000030000
rcx 0xffffffffffffffff
rdx 0xc000166dc8
rdi 0x1
rsi 0x5865
rbp 0xc000166e58
rsp 0xc000166d70
r8 0x0
r9 0x0
r10 0x1000004
r11 0x202
r12 0xf1
r13 0x0
r14 0xb16d58
r15 0x0
rip 0x4aeb5e
rflags 0x10286
cs 0x33
fs 0x0
gs 0x0
+++ exited (status 2) +++
I wrote a custom dll export in c# which is working in c
This is my c# code for dll export
[DllExport]
/* GetMSLResult from the parameter as lat, lon, and gps elevation */
public static double GetMSLResult(IntPtr lat, IntPtr lon, IntPtr gpsElevation) => Helper.GetMSL(Helper.GetGeoID(Helper.IntPtrToDouble(lat), Helper.IntPtrToDouble(lon)), Helper.IntPtrToDouble(gpsElevation));
which is working and expose via
dumpbin /exports ClassLibrary1.dll
Which has my procedure is present
Also as i test in c code its working as well
this is my
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
typedef int(*GetMSLResult)(const wchar_t* str, const wchar_t* str1);
int main()
{
auto dll = ::LoadLibrary(L"ClassLibrary1.dll"); // さっき作ったC# DLLの名前を指定する
{
auto result = reinterpret_cast<GetMSLResult>(::GetProcAddress(dll, "Count"));
wcout << result(L"34.00", L"40.00") << endl; // this returns 74.00
wcout << result(L"90.00", L"40.00") << endl; // this returns 130.00
}
if ( dll )
::FreeLibrary(dll); // 解放は忘れずに!!
return 0;
}
this is working successfully, in golang i created a test code to read the exported dll not imported dll.
I wrote a simple test in windows how to do it but it seems i got an error and exited when i try to call the function i want to return the value
package main
import (
"fmt"
"syscall"
"unsafe"
)
func main() {
h := syscall.NewLazyDLL("ClassLibrary1.dll")
proc := h.NewProc("GetGeoID")
a := string("32.00")
n, _, _ := proc.Call(uintptr(unsafe.Pointer(&a)))
//fmt.Printf("teast %v", n)
fmt.Printf("Hello dll function returns %d\n", n)
}
Currently this is my golang code.
In my GeoID expected two parameter which is lattitude and longitude
so in my code in golang
a := string("32.00")
b := string("32.00")
i want this to pass the parameter a and b to my dll procedure functions
so that i could be able to get a result.
n, _, _ := proc.Call(uintptr(unsafe.Pointer(&a)))
But currently i received this error
Exception 0xe0434352 0x80131537 0x0 0x766afd62
PC=0x766afd62
syscall.Syscall(0x6e35290e, 0x1, 0x11006108, 0x0, 0x0, 0x0, 0x0, 0x0)
C:/Go/src/runtime/syscall_windows.go:184 +0xbb
syscall.(*Proc).Call(0x11004100, 0x110120e0, 0x1, 0x1, 0x10, 0x4907e0, 0x1, 0x110120e0)
C:/Go/src/syscall/dll_windows.go:171 +0x10a
syscall.(*LazyProc).Call(0x11049aa0, 0x110120e0, 0x1, 0x1, 0x0, 0x44bc01, 0x11034000, 0x11034000)
C:/Go/src/syscall/dll_windows.go:333 +0x48
main.main()
C:/Users/christopher/developer/go/src/gotest/main.go:16 +0x103
eax 0x19fbc0
ebx 0x5
ecx 0x5
edx 0x0
edi 0x1
esi 0x19fc80
ebp 0x19fc18
esp 0x19fbc0
eip 0x766afd62
eflags 0x216
cs 0x23
fs 0x53
gs 0x2b
exit status 2
Is there any good way i can call my custom dll procedure or function
like GetAge(34, 56) and the result in golang? currently ive been using LoadDLL, NewLazyDLL and other stuff but i could not be able to achieve my goal, does somebody can suggest a good way to do it?
I ran ltrace on a Word processor and opened a sample file, but surprisingly got only two calls.
__libc_start_main(0x8048820, 1, 0xbfe08844, 0x8048850, 0x80488b0 <unfinished ...>
_ZN10AP_UnixApp4mainEPKciPPc(0x8048910, 1, 0xbfe08844, 0xb61feff4, 0x8048850) = 0
+++ exited (status 0) +++
Shouldn't ltrace print all library calls?
The problem is that ltrace only intercepts calls from the main executable (abiword here) to other shared libraries, but does not intercept calls from one shared library to another.
For abiword, the main function doesn't actually do much:
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400a70 <+0>: mov %rsi,%rdx
0x0000000000400a73 <+3>: mov %edi,%esi
0x0000000000400a75 <+5>: mov $0x400b6c,%edi
0x0000000000400a7a <+10>: jmpq 0x400950 <_ZN10AP_UnixApp4mainEPKciPPc#plt>
End of assembler dump.
As you can see, it simply does a return AP_UnixApp::main(argc, "abiword", argv);, and all the real activity happens in the library that implements AP_UnixApp::main (in my case, in /usr/lib/libabiword-2.8.so).
On a Fedora system, you can try using frysk instead. In particular, this:
ftrace -sym '*' abiword
produces a (very long) trace, beginning with:
528.528 attached /usr/bin/abiword
528.528 call #libpthread.so.0#_init(0x1, 0x7fffa8ba5bd8, 0x7fffa8ba5be8, 0x7fffa8ba5be8, 0x1f25bc2, 0x7)
528.528 call #libpthread.so.0#__pthread_initialize_minimal(0x1, 0x7fffa8ba5bd8, 0x7fffa8ba5be8, 0x7fffa8ba5be8, 0x1f25bc2, 0x7)
528.528 call #libpthread.so.0#__libc_sigaction(0x20, 0x7fffa8ba5a70, 0x0, 0x0, 0x1f25bc2, 0x7)
528.528 call #libpthread.so.0#__libc_sigaction(0x21, 0x7fffa8ba5a70, 0x0, 0x7f32501f27b0, 0x0, 0x7)
528.528 call #libc.so.6#getrlimit(0x3, 0x7fffa8ba5b10, 0x3f, 0x40, 0x0, 0x7) = 0
528.528 call #libc.so.6#sysconf(0x1e, 0x7fffa8ba5b10, 0x3f, 0x30220e7b17, 0x0, 0x7)
528.528 call #libc.so.6#getpagesize(0x1e, 0x7fffa8ba5b10, 0xfffffffffff51435, 0x30220e7b17, 0x0, 0x7) = 4096
528.528 leave #libc.so.6#sysconf = 4096
528.528 call #libc.so.6#__libc_dl_error_tsd(0x1e, 0x7fffa8ba5b10, 0x800000, 0x2a40, 0x0, 0x7) = 139854069229848
...
Ftrace documentation here.