NAME list uprobe args - basic type
RUN {{BPFTRACE}} -lv 'uprobe:./testprogs/uprobe_test:main'
EXPECT int argc
REQUIRES_FEATURE dwarf
TIMEOUT 5

NAME list uprobe args - pointer type
RUN {{BPFTRACE}} -lv 'uprobe:./testprogs/uprobe_test:uprobeFunction1'
EXPECT int * n
REQUIRES_FEATURE dwarf
TIMEOUT 5

NAME list uprobe args - struct pointer type
RUN {{BPFTRACE}} -lv 'uprobe:./testprogs/uprobe_test:uprobeFunction2'
EXPECT struct Foo * foo1
REQUIRES_FEATURE dwarf
TIMEOUT 5

NAME list uprobe args - anonymous param type
RUN {{BPFTRACE}} -lv 'uprobe:./testprogs/uprobe_test:uprobeFunction3'
EXPECT enum { A, B, C } e
EXPECT union { int a; char b; } u
REQUIRES bash -c "exit 1" # SKIP: anonymous parameter type not supported #3083
REQUIRES_FEATURE dwarf
TIMEOUT 5

NAME uprobe arg by name - char
PROG uprobe:./testprogs/uprobe_test:uprobeFunction1 { printf("c = %c\n", args.c); exit(); }
EXPECT c = x
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test

NAME uprobe arg by name - pointer
PROG uprobe:./testprogs/uprobe_test:uprobeFunction1 { printf("n = %d\n", *(args.n)); exit(); }
EXPECT n = 13
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test

NAME uprobe arg by name - struct
PROG uprobe:./testprogs/uprobe_test:uprobeFunction2 { printf("foo1->a = %d\n", args.foo1->a); exit(); }
EXPECT foo1->a = 123
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test

# NAME uprobe arg by index - 128-bits integer
# PROG uprobe:./testprogs/uprobe_test:uprobeFunctionUint128 { printf("x = %x\ny = %x\nz = %x\nw = %x\n", arg0, arg1, arg2, arg3); exit(); }
# EXPECT x = 9abcdef0
#        y = efefefef
#        z = cdcdcdcd
#        w = abababab
# REQUIRES_FEATURE dwarf
# TIMEOUT 5
# BEFORE ./testprogs/uprobe_test

# NAME uprobe arg by name - 128-bits integer
# PROG uprobe:./testprogs/uprobe_test:uprobeFunctionUint128 { printf("x = %x\ny = %x\nz = %x\nw = %x\n", args.x, args.y, args.z, args.w); exit(); }
# EXPECT x = 9abcdef0
#        y = efefefef
#        z = cdcdcdcd
#        w = abababab
# REQUIRES_FEATURE dwarf
# TIMEOUT 5
# BEFORE ./testprogs/uprobe_test

NAME uprobe arg by name - struct with 128-bits integer
PROG uprobe:./testprogs/uprobe_test:uprobeFunction2 { printf("foo1->d = %x\n", args.foo1->d); exit(); }
EXPECT foo1->d = 9abcdef0
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test

NAME uprobe skip inlined function
PROG config = { probe_inline = 0 }
     uprobe:./testprogs/inline_function:square { @count++ }
     uretprobe:./testprogs/inline_function:main { exit() }
EXPECT @count: 1
REQUIRES_FEATURE dwarf
TIMEOUT 5
AFTER ./testprogs/inline_function

NAME uprobe inlined function
PROG config = { probe_inline = 1 }
     uprobe:./testprogs/inline_function:square { @count++ }
     uretprobe:./testprogs/inline_function:main { exit() }
EXPECT @count: 3
REQUIRES_FEATURE dwarf
TIMEOUT 5
AFTER ./testprogs/inline_function

NAME uprobe inlined function - probe
PROG config = { probe_inline = 1; cache_user_symbols = "PER_PROGRAM"; }
     uprobe:./testprogs/inline_function:square {
       printf("%s\n", probe);
       if (++@count == 3) { exit(); }
     }
EXPECT uprobe:./testprogs/inline_function:square
       uprobe:./testprogs/inline_function:square
       uprobe:./testprogs/inline_function:square
REQUIRES_FEATURE dwarf
TIMEOUT 5
AFTER ./testprogs/inline_function

NAME uprobe inlined function - func
PROG config = { probe_inline = 1; cache_user_symbols = "PER_PROGRAM"; }
     uprobe:./testprogs/inline_function:square {
       printf("%s\n", func);
       if (++@count == 3) { exit(); }
     }
EXPECT main
       main
       square
REQUIRES_FEATURE dwarf
TIMEOUT 5
AFTER ./testprogs/inline_function

NAME uprobe inlined function - ustack
PROG config = { probe_inline = 1; cache_user_symbols = "PER_PROGRAM"; }
     uprobe:./testprogs/inline_function:square {
       printf("%s\n", ustack);
       if (++@count == 3) { exit(); }
     }
EXPECT_REGEX ^\n[ ]+main\+\d+$
EXPECT_REGEX ^\n[ ]+square\+\d+\n[ ]+main\+\d+$
REQUIRES_FEATURE dwarf
TIMEOUT 5
AFTER ./testprogs/inline_function

# Checking backwards compatibility
NAME uprobe args as pointer
PROG uprobe:./testprogs/uprobe_test:uprobeFunction1 { printf("c = %c\n", args->c); exit(); }
EXPECT c = x
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test

NAME struct field string
PROG uprobe:./testprogs/uprobe_test:uprobeFunction2 { printf("foo1->b = %s\n", args.foo1->b); exit(); }
EXPECT foo1->b = hello
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test

NAME struct field array
PROG uprobe:./testprogs/uprobe_test:uprobeFunction2 { print(args.foo1->c); exit(); }
EXPECT [1,2,3]
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test

NAME cast to struct
PROG uprobe:./testprogs/uprobe_test:uprobeFunction2 { printf("foo1->a = %d\n", ((struct Foo *)arg0)->a); exit(); }
EXPECT foo1->a = 123
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test

NAME struct override
PROG struct Foo { int b; } uprobe:./testprogs/uprobe_test:uprobeFunction2 { printf("foo1->b = %d\n", ((struct Foo *)arg0)->b); exit(); }
EXPECT foo1->b = 123
REQUIRES_FEATURE dwarf
TIMEOUT 5
BEFORE ./testprogs/uprobe_test
