Add CLI protocol interop tests.
authorMikhail Kurinnoi <m.kurinnoi@samsung.com>
Tue, 22 Aug 2023 10:42:38 +0000 (13:42 +0300)
committerGleb Balykov/Advanced System SW Lab /SRR/Staff Engineer/Samsung Electronics <g.balykov@samsung.com>
Wed, 13 Sep 2023 20:48:48 +0000 (05:48 +0900)
Fix rendezvous resolve logic.

13 files changed:
packaging/netcoredbg.spec
src/debugger/interop_mem_helpers.cpp
test-suite/CLITestBreakpoint/Program.cs
test-suite/CLITestBreakpoint/log_test.txt
test-suite/CLITestInteropBreakpoint/CLITestInteropBreakpoint.csproj [new file with mode: 0644]
test-suite/CLITestInteropBreakpoint/Program.cs [new file with mode: 0644]
test-suite/CLITestInteropBreakpoint/commands.txt [new file with mode: 0644]
test-suite/CLITestInteropBreakpoint/log_test.txt [new file with mode: 0644]
test-suite/CLITestInteropBreakpoint/program.c [new file with mode: 0644]
test-suite/run_cli_test.sh
test-suite/run_tests.sh
test-suite/sdb_run_tests.sh
test-suite/test-suite.sln

index 21434ef2df2ab0e529c39b422c094df9590fd6c3..285eff6069b3a529f23363eca5355a7c998db0da 100644 (file)
@@ -41,6 +41,7 @@ Requires: coreclr
 %define netcoreapp      %{netshareddir}/Microsoft.NETCore.App/
 %define netcoreappalias dotnet.tizen/netcoreapp
 %define sdktoolsdir     /home/owner/share/tmp/sdk_tools
+%define netcoredbg_test %{sdktoolsdir}/netcoredbg-tests
 %define install_prefix /usr
 %define sdk_install_prefix /home/owner/share/tmp/sdk_tools/netcoredbg
 %define netcoreapp_hotreload_min_ver 6.0.0
@@ -64,6 +65,14 @@ Requires: coreclr
 %description
 This is a CoreCLR debugger for Tizen.
 
+%package -n netcoredbg-test
+Summary:  Native tests for netcoredbg
+Requires: netcoredbg
+AutoReqProv: no
+
+%description -n netcoredbg-test
+Tests native libs
+
 %prep
 %setup -q
 cp %{SOURCE1001} .
@@ -123,6 +132,11 @@ if [ "${is_hot_reload_supported}" == "1" ]; then
     NCDB_HOOK_TargetFramework=net6.0 dotnet build -c Debug ../src/ncdbhook
 fi
 
+# Native tests
+# CLITestInteropBreakpoint
+g++ -g -fPIC -c "../test-suite/CLITestInteropBreakpoint/program.c" -o ./test_breakpoint.o
+g++ -g -fPIC -shared -o libtest_breakpoint.so test_breakpoint.o
+
 %install
 cd build
 %make_install
@@ -150,6 +164,13 @@ find lib/netstandard1.3/ -name '*.dll' -exec %{_datarootdir}/%{netcoreappalias}/
 install -p -m 644 lib/netstandard1.3/*.dll %{buildroot}%{sdk_install_prefix}
 touch %{buildroot}%{sdk_install_prefix}/version-%{version}-%{release}
 
+mkdir -p %{buildroot}%{netcoredbg_test}
+install -p -m 644 libtest_breakpoint.so %{buildroot}%{netcoredbg_test}
+
 %files
 %manifest netcoredbg.manifest
 %{sdk_install_prefix}/*
+
+%files -n netcoredbg-test
+%manifest %{name}.manifest
+%{netcoredbg_test}/*
index c1f3bc1f16f91c3209015307587b6015c84330ac..ddbf70b87d436e7d7c877efe7c18ec1fdce1ef1e 100644 (file)
@@ -172,7 +172,7 @@ bool ResolveRendezvous(pid_t pid, std::uintptr_t &rendezvousAddr)
     {
         if (seg.get_hdr().type == elf::pt::dynamic)
         {
-            dynamicAddr = (elfFile->is_PIE() ? startAddr : 0) + seg.get_hdr().vaddr;
+            dynamicAddr = startAddr + seg.get_hdr().vaddr;
             break;
         }
     }
index f97c3a2b954f8904c76a5260d1d064f407dae277..3e578dc508f853e5aa56e7a8fb67978748180e0d 100644 (file)
@@ -6,7 +6,7 @@ namespace CLITestBreakpoint
     {\r
         static void Main(string[] args)\r
         {\r
-            Console.WriteLine("Hello World!");      // BREAK1\r
+            Console.WriteLine("<stdout_marker>Hello World!");      // BREAK1\r
         }\r
     }\r
 }\r
index f301989d51f108699a5cefdddb7f097c9837790d..1d38bbb720772f84c3fa02fc7ff63d71e17dd5e6 100644 (file)
@@ -4,13 +4,12 @@ b Program.cs:9
 r
 \^running
 breakpoint modified,  Breakpoint 1 at .*CLITestBreakpoint/Program.cs:9
-stopped, reason: breakpoint 1 hit, thread id: .*, stopped threads: all, times= 1, frame=\{CLITestBreakpoint\.Program\.Main\(\) at .*CLITestBreakpoint/Program.cs:9\}
+stopped, reason: breakpoint 1 hit, thread id: [0-9]+, stopped threads: all, times= 1, frame=\{CLITestBreakpoint\.Program\.Main\(\) at .*CLITestBreakpoint/Program.cs:9\}
 s
 \^running
-Hello World!
-stopped, reason: end stepping range, thread id: .*, stopped threads: all, frame=\{CLITestBreakpoint\.Program\.Main\(\) at .*CLITestBreakpoint/Program.cs:10\}
+stopped, reason: end stepping range, thread id: [0-9]+, stopped threads: all, frame=\{CLITestBreakpoint\.Program\.Main\(\) at .*CLITestBreakpoint/Program.cs:10\}
 bt
-#0 CLITestBreakpoint\.Program\.Main\(\) at .*CLITestBreakpoint/Program.cs:10
+#0: .* CLITestBreakpoint.dll` CLITestBreakpoint\.Program\.Main\(\) at .*CLITestBreakpoint/Program.cs:10
 c
 \^running
 stopped, reason: exited, exit-code: 0
diff --git a/test-suite/CLITestInteropBreakpoint/CLITestInteropBreakpoint.csproj b/test-suite/CLITestInteropBreakpoint/CLITestInteropBreakpoint.csproj
new file mode 100644 (file)
index 0000000..d453e9a
--- /dev/null
@@ -0,0 +1,8 @@
+<Project Sdk="Microsoft.NET.Sdk">\r
+\r
+  <PropertyGroup>\r
+    <OutputType>Exe</OutputType>\r
+    <TargetFramework>netcoreapp3.1</TargetFramework>\r
+  </PropertyGroup>\r
+\r
+</Project>\r
diff --git a/test-suite/CLITestInteropBreakpoint/Program.cs b/test-suite/CLITestInteropBreakpoint/Program.cs
new file mode 100644 (file)
index 0000000..0c1f77b
--- /dev/null
@@ -0,0 +1,20 @@
+using System;\r
+using System.Runtime.InteropServices;\r
+\r
+namespace CLITestInteropBreakpoint\r
+{\r
+    class Program\r
+    {\r
+        [DllImport("./libtest_breakpoint.so")]\r
+        public static extern void native_method();\r
+\r
+        static void Main(string[] args)\r
+        {\r
+            Console.WriteLine("<stdout_marker>Managed: Start");\r
+\r
+            native_method(); // BREAK1\r
+\r
+            Console.WriteLine("<stdout_marker>Managed: End");\r
+        }\r
+    }\r
+}\r
diff --git a/test-suite/CLITestInteropBreakpoint/commands.txt b/test-suite/CLITestInteropBreakpoint/commands.txt
new file mode 100644 (file)
index 0000000..56ae465
--- /dev/null
@@ -0,0 +1,9 @@
+set just-my-code 1
+b Program.cs:15
+b program.c:7
+r
+bt
+c
+bt
+c
+
diff --git a/test-suite/CLITestInteropBreakpoint/log_test.txt b/test-suite/CLITestInteropBreakpoint/log_test.txt
new file mode 100644 (file)
index 0000000..a8e6552
--- /dev/null
@@ -0,0 +1,23 @@
+set just-my-code 1
+b Program.cs:15
+ Breakpoint 1 at Program.cs:15 --pending, warning: No executable code of the debugger's target code type is associated with this line.
+b program.c:7
+ Breakpoint 2 at program.c:7 --pending, warning: No executable code of the debugger's target code type is associated with this line.
+r
+\^running
+breakpoint modified,  Breakpoint 1 at .*CLITestInteropBreakpoint/Program.cs:15
+stopped, reason: breakpoint 1 hit, thread id: [0-9]+, stopped threads: all, times= 1, frame=\{CLITestInteropBreakpoint\.Program\.Main\(\) at .*CLITestInteropBreakpoint/Program.cs:15\}
+bt
+#0: .* CLITestInteropBreakpoint.dll` CLITestInteropBreakpoint\.Program.Main\(\) at .*CLITestInteropBreakpoint/Program\.cs:15
+#1: .* libcoreclr.so` .*
+c
+\^running
+breakpoint modified,  Breakpoint 2 at .*CLITestInteropBreakpoint.*program\.c:7
+stopped, reason: breakpoint 2 hit, thread id: [0-9]+, stopped threads: all, times= 1, frame=\{libtest_breakpoint.so` native_method\(\) at .*CLITestInteropBreakpoint.*program\.c:7\}
+bt
+#0: .* libtest_breakpoint.so` native_method\(\) at .*CLITestInteropBreakpoint.*program\.c:7
+#1: .* \[CoreCLR Native Frame\]|^#1: .* \[Native Frame\(s\), unwind failed - CoreCLR don't provide registers context\]
+c
+\^running
+stopped, reason: exited, exit-code: 0
+\^exit
diff --git a/test-suite/CLITestInteropBreakpoint/program.c b/test-suite/CLITestInteropBreakpoint/program.c
new file mode 100644 (file)
index 0000000..7364f65
--- /dev/null
@@ -0,0 +1,8 @@
+#include <stdio.h>\r
+\r
+extern "C" void native_method()\r
+{\r
+    setvbuf(stdout, NULL, _IONBF, 0);\r
+    printf("<stdout_marker>Native: Start\n");\r
+    printf("<stdout_marker>Native: End\n");                     // BREAK2\r
+}\r
index 47116d83bfa20477ac5f6046ff580761c3fcda02..3f251185f3849a666eface8b95dc62fc95609ecf 100755 (executable)
@@ -17,11 +17,39 @@ skip_line()
 {
     local line=$1
 
+    # Replies
+
+    # Note, we check only first 2 frames in backtraces, since in case of interop we can't count on other info.
+    if [[ "$line" == "#0:"* ]] ||
+       [[ "$line" == "#1:"* ]]
+    then
+        exit
+    elif [[ "$line" =~ ^#[0-9]+:.* ]]
+    then
+        echo "1"
+        exit
+    fi
+
+    # Ignore text sent by program itself, since we can't predict line of this text in log.
+    if [[ "$line" == "<stdout_marker>"* ]]
+    then
+        echo "1"
+        exit
+    fi
+
+    # Events
+
     if [[ -z "$line" ]] ||
        [[ "$line" == "library loaded:"* ]] ||
+       [[ "$line" == "library unloaded:"* ]] ||
        [[ "$line" == "no symbols loaded, base address:"* ]] ||
        [[ "$line" == "symbols loaded, base address:"* ]] ||
-       [[ "$line" == "thread created, id:"* ]] ;
+       [[ "$line" == "thread created, id:"* ]] ||
+       [[ "$line" == "thread exited, id:"* ]] ||
+       [[ "$line" == "native thread created, id: "* ]] ||
+       [[ "$line" == "managed thread created, id: "* ]] ||
+       [[ "$line" == "native thread exited, id: "* ]] ||
+       [[ "$line" == "managed thread exited, id: "* ]]
     then
         echo "1"
     else
index b2dd3411efb521b89a329dc4bc9a1cd2b7d62f1a..f98fe3d5f25059ce3d8d629e4835c816554ea32c 100755 (executable)
@@ -16,6 +16,7 @@ ${testnames}        </testsuite>
 
 ALL_TEST_NAMES=(
     "CLITestBreakpoint"
+    "CLITestInteropBreakpoint"
     "MIExampleTest"
     "MITestBreakpoint"
     "MITestExpression"
@@ -82,6 +83,9 @@ ALL_TEST_NAMES=(
 
 # Skipped tests:
 # VSCodeTest297killNCD --- is not automated enough. For manual run only.
+
+INTEROP="0"
+
 for i in "$@"
 do
 case $i in
@@ -94,6 +98,10 @@ case $i in
     code_coverage_report=true
     shift
     ;;
+    -i|--interop)
+    INTEROP="1"
+    shift
+    ;;
     *)
         TEST_NAMES="$TEST_NAMES *"
     ;;
@@ -173,6 +181,23 @@ for TEST_NAME in $TEST_NAMES; do
         continue
     }
 
+    # Native part compilation for interop testing
+    if  [[ $TEST_NAME == CLITestInterop* ]] ;
+    then
+        if [[ $INTEROP == "0" ]] ;
+        then
+            continue
+        fi
+
+        pushd $(pwd)
+        mkdir "$TEST_NAME/build"
+        cd "$TEST_NAME/build"
+        clang++ -g -fPIC -c "../program.c" -o ./test_breakpoint.o
+        clang++ -g -fPIC -shared -o "../bin/Debug/netcoreapp3.1/libtest_breakpoint.so" test_breakpoint.o
+        # Note, we don't remove build directory for test possible issues with interop test execution/build.
+        popd
+    fi
+
     SOURCE_FILES=""
     for file in `find $TEST_NAME \! -path "$TEST_NAME/obj/*" -type f -name "*.cs"`; do
         SOURCE_FILES="${SOURCE_FILES}${file};"
@@ -188,7 +213,13 @@ for TEST_NAME in $TEST_NAMES; do
 
     if [[ $TEST_NAME == CLI* ]] ;
     then
-        ./run_cli_test.sh "$NETCOREDBG" "$TEST_NAME" "$TEST_NAME/bin/Debug/netcoreapp3.1/$TEST_NAME.dll" "$TEST_NAME/commands.txt"
+        CLI_NETCOREDBG=$NETCOREDBG
+        if  [[ $TEST_NAME == CLITestInterop* ]] ;
+        then
+            CLI_NETCOREDBG="$NETCOREDBG --interop-debugging"
+        fi
+
+        ./run_cli_test.sh "$CLI_NETCOREDBG" "$TEST_NAME" "$TEST_NAME/bin/Debug/netcoreapp3.1/$TEST_NAME.dll" "$TEST_NAME/commands.txt"
     else
         PROTO="mi"
         if  [[ $TEST_NAME == VSCode* ]] ;
index 201718efbb1dec13949032620d3b765aa6bb61e5..e064794ca7f6a5c6d3141cd9a8bdf1f52bd9eb2c 100755 (executable)
@@ -32,6 +32,7 @@ generate_xml()
 
 ALL_TEST_NAMES=(
     "CLITestBreakpoint"
+    "CLITestInteropBreakpoint"
     "MIExampleTest"
     "MITestBreakpoint"
     "MITestExpression"
@@ -178,8 +179,16 @@ if [[ -z $RPMFILE ]]; then
     # The following command assumes that GBS build was performed on a clean system (or in Docker),
     # which means only one such file exists.
     RPMFILE=$(find $GBSROOT/local/repos/ -type f -name netcoredbg-[0-9]\*$ARCH.rpm -print -quit)
+    RPMFILE_TEST=$(find $GBSROOT/local/repos/ -type f -name netcoredbg-test-[0-9]\*$ARCH.rpm -print -quit)
+    RPMFILE_TESTDEBUG=$(find $GBSROOT/local/repos/ -type f -name netcoredbg-test-debuginfo-[0-9]\*$ARCH.rpm -print -quit)
+else
+    # Find tests related RPMs near debugger RPM.
+    RPMFILE_TEST=$(find $(dirname "${RPMFILE}") -type f -name netcoredbg-test-[0-9]\*$ARCH.rpm -print -quit)
+    RPMFILE_TESTDEBUG=$(find $(dirname "${RPMFILE}") -type f -name netcoredbg-test-debuginfo-[0-9]\*$ARCH.rpm -print -quit)
 fi
 
+REMOTETESTDIR=$TOOLS_ABS_PATH/netcoredbg-tests
+
 # Repackage RPM file as TGZ
 
 if [ ! -f "$RPMFILE" ]; then echo "Debugger RPM not found"; exit 1; fi
@@ -190,20 +199,35 @@ TARGZNAME=$PKGNAME-$PKGVERSION-$PKGARCH.tar.gz
 if [ -d "$SCRIPTDIR/unpacked" ]; then rm -rf "$SCRIPTDIR/unpacked"; fi
 mkdir "$SCRIPTDIR/unpacked" && cd "$SCRIPTDIR/unpacked"
 rpm2cpio "$RPMFILE" | cpio -idmv
+if [[ -f "$RPMFILE_TEST" ]] ;
+then
+    rpm2cpio "$RPMFILE_TEST" | cpio -idmv
+else
+    echo "Debugger Test RPM not found"
+fi
+if [[ -f "$RPMFILE_TESTDEBUG" ]] ;
+then
+    rpm2cpio "$RPMFILE_TESTDEBUG" | cpio -idmv
+    # Note, "home" folder is a symlink with real location in Tizen is "/opt/usr/home", debug info located in "/usr/lib/debug/home/.." will be never found.
+    # So, we just copy debuginfo close to library .so file.
+    cp -a "./usr/lib/debug/home/owner/share/tmp/sdk_tools/netcoredbg-tests/." "./$REMOTETESTDIR"
+    rm -rf "./usr/lib/debug/home/owner/share/tmp/sdk_tools/netcoredbg-tests/"
+else
+    echo "Debugger Test Debug Info RPM not found"
+fi
 touch .$TOOLS_ABS_PATH/$PKGNAME/version-$PKGVERSION
 tar cfz ../$TARGZNAME --owner=owner --group=users -C .$TOOLS_ABS_PATH .
 cd ..
 
 # Upload TGZ to target and unpack
 
-REMOTETESTDIR=$TOOLS_ABS_PATH/netcoredbg-tests
-
 $SDB shell rm -rf "$TOOLS_ABS_PATH/netcoredbg"
+$SDB shell rm -rf "$TOOLS_ABS_PATH/netcoredbg-tests"
 $SDB shell mkdir -p $TOOLS_ABS_PATH/on-demand
 $SDB push $TARGZNAME $TOOLS_ABS_PATH/on-demand
-$SDB shell "cd $TOOLS_ABS_PATH && tar xf $TOOLS_ABS_PATH/on-demand/$(basename $TARGZNAME)"
 $SDB shell rm -rf "$REMOTETESTDIR"
 $SDB shell mkdir $REMOTETESTDIR
+$SDB shell "cd $TOOLS_ABS_PATH && tar xf $TOOLS_ABS_PATH/on-demand/$(basename $TARGZNAME)"
 
 NETCOREDBG=$TOOLS_ABS_PATH/netcoredbg/netcoredbg
 
@@ -244,9 +268,15 @@ for TEST_NAME in $TEST_NAMES; do
     if [[ $TEST_NAME == CLI* ]] ;
     then
 
+        CLI_NETCOREDBG=$NETCOREDBG
+        if  [[ $TEST_NAME == CLITestInterop* ]] ;
+        then
+            CLI_NETCOREDBG="$NETCOREDBG --interop-debugging"
+        fi
+
         $SDB push $SCRIPTDIR/$TEST_PROJ_NAME/commands.txt $REMOTETESTDIR
         $SDB root on
-        ./run_cli_test.sh "$SDB shell $NETCOREDBG" "$TEST_NAME" "$REMOTETESTDIR/$TEST_NAME.dll" "$REMOTETESTDIR/commands.txt"
+        ./run_cli_test.sh "$SDB shell $CLI_NETCOREDBG" "$TEST_NAME" "$REMOTETESTDIR/$TEST_NAME.dll" "$REMOTETESTDIR/commands.txt"
         let RC=$?
         $SDB root off
 
index 2a663560a74a24307a7df74e32afc105e5fa72d7..6d7e35d9a3c422ba417b900efb82b57037bad8f5 100644 (file)
@@ -129,6 +129,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestBreakpointUpdate", "M
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLITestBreakpoint", "CLITestBreakpoint\CLITestBreakpoint.csproj", "{3F7823C7-880F-4CD3-931B-86B0F4F05423}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLITestInteropBreakpoint", "CLITestInteropBreakpoint\CLITestInteropBreakpoint.csproj", "{61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}"
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Any CPU = Debug|Any CPU
@@ -910,5 +912,17 @@ Global
                {3F7823C7-880F-4CD3-931B-86B0F4F05423}.Release|x64.Build.0 = Release|Any CPU
                {3F7823C7-880F-4CD3-931B-86B0F4F05423}.Release|x86.ActiveCfg = Release|Any CPU
                {3F7823C7-880F-4CD3-931B-86B0F4F05423}.Release|x86.Build.0 = Release|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Debug|x64.Build.0 = Debug|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Debug|x86.Build.0 = Debug|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Release|Any CPU.Build.0 = Release|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Release|x64.ActiveCfg = Release|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Release|x64.Build.0 = Release|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Release|x86.ActiveCfg = Release|Any CPU
+               {61A32EDF-96A7-42B6-9B4B-E52D99D0E1B5}.Release|x86.Build.0 = Release|Any CPU
        EndGlobalSection
 EndGlobal