set testname usymfileline

# tests functions usymfileline(), usymline(), and usymfile()
# it also tests that the functions fail gracefully when there is no debug_line
# info for the user program.

if {![installtest_p]} { untested $test; return }
if {![uprobes_p]} { untested "$test"; return }

# compile the c++ program
set compile_flags "additional_flags=-g compiler=g++"
set compile_result [target_compile $srcdir/$subdir/$testname.cxx ./$testname executable $compile_flags]
if {$compile_result != ""} {
    verbose -log "target_compile failed: $compile_result" 2
    fail "$testname - unable to compile, $compile_result"
    untested "$testname"
    return
} else {
    pass "$testname - compiled successfully"
}

# check that it can use uprobes
if {![uprobes_p]} {
  untested "$testname (uprobes)"
}

set script {\
probe process("usymfileline").function("test_method") {\
  print("systemtap starting probe\nsystemtap ending probe\n")\
  printf("%s\n", TAPSETFUNCTION($1))\
  exit()}\
}

set tests {usymfileline usymline usymfile}
set expectedoutput {".*usymfileline.cxx:\[4-5]\r\n" "\[4-5]\r\n" ".*usymfileline.cxx\r\n"}

foreach test $tests eoutput $expectedoutput {
  set testscript [string map "TAPSETFUNCTION $test" $script]
  # test with an invalid address. the expected output is the same for all cases
  stap_run "$test ()" no_load "0x0\r\n" -e $testscript 0 -c ./usymfileline
  # test with uaddr()
  stap_run "$test ()" no_load $eoutput -e $testscript uaddr() -c ./usymfileline
}

# test that the runtime linenumber and filename info  match up with translation
# time info. (look for @PATH: within probe point)
set script {\
global failed=0\
probe begin {print("systemtap starting probe\nsystemtap ending probe\n")}\
probe process("usymfileline").statement("*@*:*"){\
  ppstring = pp()\
  symstring = "@".usymfileline(uaddr())\
  if (isinstr(ppstring, symstring) != 1) {\
    failed++;\
    printf ("failed. pp(): %s  usymfileline(): %s\n", ppstring, symstring)\
  }\
}\
probe end { if (failed == 0) println("passed") }\
}
stap_run "pp == usymfileline" no_load "passed\r\n" -e $script -c ./usymfileline

eval exec objcopy -R .debug_line $testname

# cannot use the same script as before because process.function("*") will fail
# (during pass 2) without debug_line info. since we are just testing that
# the function fails gracefully, can just use process.begin instead
set script {\
probe process("usymfileline").begin {\
  print("systemtap starting probe\nsystemtap ending probe\n")\
  printf("%s\n", TAPSETFUNCTION($1))\
  exit()}\
}
foreach test $tests {
  set testscript [string map "TAPSETFUNCTION $test" $script]
  # test with uaddr(). check that it can still fail gracefully.
  stap_run "$test (no debug_line)" no_load "0x\[0-9,a-f]*\r\n" -e $testscript uaddr() -c ./usymfileline 
}

exec rm -f ./$testname
