Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/testing/tests.ioslike.targets
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
<!-- Configuration properties -->
<_ApplePropertyNames Include="AssemblyName" />
<_ApplePropertyNames Include="IncludesTestRunner" />
<_ApplePropertyNames Include="EnableAppSandbox" />
<_ApplePropertyNames Include="MainLibraryFileName" />
<_ApplePropertyNames Include="MonoEnableLLVM" />
<_ApplePropertyNames Include="ShouldILStrip" />
Expand Down
12 changes: 12 additions & 0 deletions src/libraries/sendtohelix-mobile.targets
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@
</XHarnessAppBundleToTest>
</ItemGroup>

<ItemGroup Condition="'$(TargetsAppleMobile)' == 'true'">
<XHarnessAppBundleToTest Update="@(XHarnessAppBundleToTest)"
Condition="$([System.String]::Copy('%(Filename)').StartsWith('iOS.InProcCrashReport.'))">
<ExpectedExitCode>100</ExpectedExitCode>
</XHarnessAppBundleToTest>
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'android'">
<_apks Include="$(TestArchiveTestsRoot)**/*.apk" />
<XHarnessApkToTest Include="@(_apks)">
Expand All @@ -140,6 +147,11 @@
<!-- The android sample returns 42 so it should be considered by xharness as a success -->
<ExpectedExitCode>42</ExpectedExitCode>
</XHarnessApkToTest>
<XHarnessApkToTest Update="@(XHarnessApkToTest)"
Condition="$([System.String]::Copy('%(Filename)').StartsWith('Android.Device_Emulator.InProcCrashReport.'))">
<ExpectedExitCode>100</ExpectedExitCode>
<DeviceOutputPath>/sdcard/Android/data/%(AndroidPackageName)/files/inproccrashreport.zip</DeviceOutputPath>
</XHarnessApkToTest>
</ItemGroup>
</Target>

Expand Down
19 changes: 19 additions & 0 deletions src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@
<ProjectExclusions Include="$(RepoRoot)\src\tests\FunctionalTests\Android\Device_Emulator\JIT\Android.Device_Emulator.JIT.Static.Test.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'android' and '$(RuntimeFlavor)' != 'CoreCLR'">
<ProjectExclusions Include="$(RepoRoot)\src\tests\FunctionalTests\Android\Device_Emulator\InProcCrashReport\**\*.Test.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'android' and '$(RuntimeFlavor)' == 'CoreCLR' and '$(RunDisabledAndroidTests)' != 'true'">
<!-- https://github.com/dotnet/runtime/issues/72908 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Reflection.MetadataLoadContext\tests\System.Reflection.MetadataLoadContext.Tests.csproj" />
Expand Down Expand Up @@ -685,6 +689,21 @@
Condition="'$(TestAssemblies)' == 'true'"
BuildInParallel="$(BuildTestInParallel)" />

<ProjectReference Include="$(RepoRoot)\src\tests\FunctionalTests\Android\Device_Emulator\InProcCrashReport\**\*.Test.csproj"
Exclude="@(ProjectExclusions)"
Condition="'$(TestAssemblies)' == 'true' and '$(ArchiveTests)' == 'true' and
'$(TargetOS)' == 'android' and '$(RuntimeFlavor)' == 'CoreCLR' and
'$(TestNativeAOT)' != 'true' and '$(UseNativeAOTRuntime)' != 'true'"
BuildInParallel="false" />

<ProjectReference Include="$(RepoRoot)\src\tests\FunctionalTests\iOS\InProcCrashReport\**\*.Test.csproj"
Exclude="@(ProjectExclusions)"
Condition="'$(TestAssemblies)' == 'true' and '$(ArchiveTests)' == 'true' and
('$(TargetOS)' == 'ios' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'maccatalyst') and
'$(TargetArchitecture)' == 'arm64' and '$(RuntimeFlavor)' == 'CoreCLR' and
'$(TestNativeAOT)' != 'true' and '$(UseNativeAOTRuntime)' != 'true'"
BuildInParallel="false" />

<ProjectReference Include="$(MSBuildThisFileDirectory)testPackages\testPackages.proj"
Condition="'$(TestPackages)' == 'true'" />

Expand Down
16 changes: 14 additions & 2 deletions src/tasks/AndroidAppBuilder/Templates/CMakeLists-android.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@ cmake_minimum_required(VERSION 3.10)

project(monodroid)

enable_language(C ASM)
enable_language(C CXX ASM)

if(ANDROID_NDK_MAJOR VERSION_LESS "23")
message(FATAL_ERROR "Error: need at least Android NDK 23, got ${ANDROID_NDK_REVISION}!")
endif()

add_compile_options(-Werror=missing-prototypes -Werror=missing-declarations -Wall -std=c99)
add_compile_options(-Wall)

# These warnings describe C function declarations and can be rejected by C++ compilers.
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Werror=missing-prototypes>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Werror=missing-declarations>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-std=c99>)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# ANDROID_STL=none does not provide the C++ ABI support needed by RTTI or exceptions.
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>)

add_library(
monodroid
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Abort: a SIGABRT crash thread with no managed exception and native-only
frames. Exercises the non-managed-exception path and the SIGABRT signal
formatting (distinct from the SIGSEGV scenarios). -->
<PropertyGroup>
<AssemblyName>Android.Device_Emulator.InProcCrashReport.Abort.Test</AssemblyName>
<MainLibraryFileName>Android.Device_Emulator.InProcCrashReport.Abort.Test.dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_ABORT</DefineConstants>
</PropertyGroup>

<Import Project="../Shared/InProcCrashReport.Common.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- A valid report root with lifecycle output disabled must only emit compact output. -->
<PropertyGroup>
<AssemblyName>Android.Device_Emulator.InProcCrashReport.ConsoleOnly.Test</AssemblyName>
<MainLibraryFileName>Android.Device_Emulator.InProcCrashReport.ConsoleOnly.Test.dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_CONSOLEONLY</DefineConstants>
</PropertyGroup>
<Import Project="../Shared/InProcCrashReport.Common.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Repeated caller-sink reports, rejection paths, and lifecycle isolation. -->
<PropertyGroup>
<AssemblyName>Android.Device_Emulator.InProcCrashReport.OnDemand.Test</AssemblyName>
<MainLibraryFileName>Android.Device_Emulator.InProcCrashReport.OnDemand.Test.dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_ONDEMAND</DefineConstants>
</PropertyGroup>

<Import Project="../Shared/InProcCrashReport.Common.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Rich SIGSEGV: a managed NullReferenceException crash thread with interleaved
managed/native frames and generic-instantiation method names, plus extra
background threads. Exercises the multithreaded, interleaved-stack, generics
and managed-exception format branches in a single report. -->
<PropertyGroup>
<AssemblyName>Android.Device_Emulator.InProcCrashReport.RichSigsegv.Test</AssemblyName>
<MainLibraryFileName>Android.Device_Emulator.InProcCrashReport.RichSigsegv.Test.dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_RICHSIGSEGV</DefineConstants>
</PropertyGroup>
<Import Project="../Shared/InProcCrashReport.Common.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<Project>
<PropertyGroup>
<OutputType>Exe</OutputType>
<RunAOTCompilation>false</RunAOTCompilation>
<TestRuntime>true</TestRuntime>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<ExpectedExitCode>100</ExpectedExitCode>
<DefineConstants>$(DefineConstants);INPROC_ANDROID</DefineConstants>
<!-- The test library links its own PAL/reporter; the managed host remains dynamic. -->
<StaticLinkedRuntime>false</StaticLinkedRuntime>
<CrashReportArtifactPath>/sdcard/Android/data/net.dot.$(AssemblyName)/files/inproccrashreport.zip</CrashReportArtifactPath>
<AdditionalXHarnessArguments>$(AdditionalXHarnessArguments) --device-out-folder=$(CrashReportArtifactPath)</AdditionalXHarnessArguments>
</PropertyGroup>

<PropertyGroup>
<CrashReportAndroidDir>$(MSBuildThisFileDirectory)</CrashReportAndroidDir>
<CrashReportSharedDir>$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'tests', 'baseservices', 'exceptions', 'inproccrashreport', 'Shared'))</CrashReportSharedDir>
<CrashReportSourceDir>$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'coreclr', 'debug', 'crashreport'))</CrashReportSourceDir>
</PropertyGroup>

<ItemGroup>
<Compile Include="$(CrashReportSharedDir)Program.cs" />
<AndroidEnv Include="DOTNET_InProcCrashReportTestArchive" Value="$(CrashReportArtifactPath)" />
</ItemGroup>

<ItemGroup>
<ExtraAppNativeSources Include="$(CrashReportSharedDir)inproccrashreport_test_driver.cpp" />
<ExtraAppNativeSources Include="$(CrashReportAndroidDir)android_log_interpose.c" />
</ItemGroup>

<ItemGroup>
<RuntimeHeaders Include="$(CrashReportSourceDir.TrimEnd('\').TrimEnd('/'))" />
<RuntimeHeaders Include="$(CrashReportAndroidDir.TrimEnd('\').TrimEnd('/'))" />
<RuntimeHeaders Include="$(CoreClrProjectRoot)pal\inc" />
</ItemGroup>

<Target Name="ConfigureCrashReportNativeLibraries" BeforeTargets="_AndroidGenerateAppBundle">
<!-- Android CI builds CoreCLR and the APK in the same job; these archives are link inputs, not Helix payload files. -->
<PropertyGroup>
<CrashReportPalLibrary>$([MSBuild]::NormalizePath('$(CoreCLRArtifactsPath)', 'lib', 'libcoreclrpal.a'))</CrashReportPalLibrary>
<CrashReportMinipalLibrary>$([MSBuild]::NormalizePath('$(ArtifactsObjDir)', 'coreclr', '$(TargetOS).$(TargetArchitecture).$(CoreCLRConfiguration)', 'shared_minipal', 'libminipal.a'))</CrashReportMinipalLibrary>
</PropertyGroup>
<Error Condition="!Exists('$(CrashReportPalLibrary)')" Text="Build CoreCLR first; missing PAL library: $(CrashReportPalLibrary)" />
<Error Condition="!Exists('$(CrashReportMinipalLibrary)')" Text="Build CoreCLR first; missing minipal library: $(CrashReportMinipalLibrary)" />

<!-- AndroidAppBuilder uses ANDROID_STL=none. Supply NDK C++ support statically to avoid packaging libc++_shared.so. -->
<ItemGroup>
<RuntimeHeaders Include="$([MSBuild]::NormalizeDirectory('$(ANDROID_NDK_ROOT)', 'toolchains', 'llvm', 'prebuilt', '$(NdkToolchainPrebuiltOS)', 'sysroot', 'usr', 'include', 'c++', 'v1'))" />
<ExtraAppLinkerArgs Include="$(CrashReportPalLibrary.Replace('\', '/'))" />
<ExtraAppLinkerArgs Include="$(CrashReportMinipalLibrary.Replace('\', '/'))" />
<ExtraAppLinkerArgs Include="-lc++_static" />
<ExtraAppLinkerArgs Include="-lc++abi" />
<ExtraAppLinkerArgs Include="-Wl,--wrap=__android_log_write" />
<!-- Keep the test's PAL and C++ runtime private from the hosting CoreCLR. -->
<ExtraAppLinkerArgs Include="-Wl,--exclude-libs,ALL" />
</ItemGroup>
</Target>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// Captures the in-proc crash reporter's compact console report in-process.
//
// On Android the reporter emits each console line via __android_log_write under
// CRASHREPORT_LOG_TAG ("DOTNET_CRASH"), routed to logcat rather than a file
// descriptor -- so it cannot be captured by redirecting stdout/stderr. This
// translation unit is linked into the same shared library (libmonodroid.so) as
// the PAL-linked reporter, with --wrap=__android_log_write redirecting its calls
// to this wrapper. Lines tagged DOTNET_CRASH are accumulated for later
// validation; every call is also forwarded to the real liblog implementation so
// the report still appears in logcat for debugging.

#include "android_log_interpose.h"

#include <android/log.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>

// Must match CRASHREPORT_LOG_TAG in inproccrashreporter.h.
static const char s_crashTag[] = "DOTNET_CRASH";

// The fixed scenarios currently produce at most 1 KiB. Keep ample headroom
// without allocating from the signal-shaped reporting path.
static char s_capture[16 * 1024];
static size_t s_captureLen;
static bool s_overflowed;

extern int __real___android_log_write(int prio, const char* tag, const char* text);

int __wrap___android_log_write(int prio, const char* tag, const char* text)
{
if (tag != NULL && text != NULL && strcmp(tag, s_crashTag) == 0)
{
size_t textLen = strlen(text);
if (textLen < sizeof(s_capture) - s_captureLen - 1)
{
memcpy(s_capture + s_captureLen, text, textLen);
s_captureLen += textLen;
s_capture[s_captureLen++] = '\n';
s_capture[s_captureLen] = '\0';
}
else
{
s_overflowed = true;
}
}

return __real___android_log_write(prio, tag, text);
}

const char* InProcCrashReportTest_GetConsoleCapture(void)
{
return s_overflowed ? NULL : s_capture;
}

void InProcCrashReportTest_ResetConsoleCapture(void)
{
s_captureLen = 0;
s_capture[0] = '\0';
s_overflowed = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// Shared declarations for the synthetic in-proc crash reporter test's console
// capture. The compact console report is written by the reporter via
// __android_log_write (Android logcat); android_log_interpose.c intercepts those
// writes so the report can be validated in-process alongside the JSON file.

#ifndef ANDROID_LOG_INTERPOSE_H
#define ANDROID_LOG_INTERPOSE_H

#ifdef __cplusplus
extern "C"
{
#endif

int __wrap___android_log_write(int prio, const char* tag, const char* text);

// Returns captured lines since the last reset, or NULL if the buffer overflowed.
const char* InProcCrashReportTest_GetConsoleCapture(void);

// Clears the captured console-report text.
void InProcCrashReportTest_ResetConsoleCapture(void);

#ifdef __cplusplus
}
#endif

#endif // ANDROID_LOG_INTERPOSE_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#pragma once

// AndroidAppBuilder does not supply CoreCLR's platform/architecture definitions.
#define HOST_UNIX 1
#define TARGET_UNIX 1
#define PLATFORM_UNIX 1
#define TARGET_ANDROID 1

#if defined(__x86_64__)
#define HOST_AMD64 1
#define TARGET_AMD64 1
#elif defined(__aarch64__)
#define HOST_ARM64 1
#define TARGET_ARM64 1
#elif defined(__arm__)
#define HOST_ARM 1
#define TARGET_ARM 1
#elif defined(__i386__)
#define HOST_X86 1
#define TARGET_X86 1
#else
#error Unsupported Android architecture
#endif

#if defined(__LP64__)
#define HOST_64BIT 1
#define TARGET_64BIT 1
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- StackOverflow: drives the crash-kind StackOverflow branch via
InProcCrashReportSetCrashKind + the BeginStackOverflowTrace /
AddStackOverflowTraceFrame / EndStackOverflowTrace APIs. Exercises the
dedicated stack-overflow thread emission (compressed trace with a repeated
sequence) instead of normal thread enumeration. -->
<PropertyGroup>
<AssemblyName>Android.Device_Emulator.InProcCrashReport.StackOverflow.Test</AssemblyName>
<MainLibraryFileName>Android.Device_Emulator.InProcCrashReport.StackOverflow.Test.dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_STACKOVERFLOW</DefineConstants>
</PropertyGroup>
<Import Project="../Shared/InProcCrashReport.Common.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<MainLibraryFileName>$(MSBuildProjectName).dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_ABORT</DefineConstants>
</PropertyGroup>
<Import Project="../Shared/InProcCrashReport.Apple.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<MainLibraryFileName>$(MSBuildProjectName).dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_CONSOLEONLY</DefineConstants>
</PropertyGroup>
<Import Project="../Shared/InProcCrashReport.Apple.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<MainLibraryFileName>$(MSBuildProjectName).dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_ONDEMAND</DefineConstants>
</PropertyGroup>
<Import Project="../Shared/InProcCrashReport.Apple.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<MainLibraryFileName>$(MSBuildProjectName).dll</MainLibraryFileName>
<DefineConstants>$(DefineConstants);INPROC_SCENARIO_RICHSIGSEGV</DefineConstants>
</PropertyGroup>
<Import Project="../Shared/InProcCrashReport.Apple.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.26)
# This is an app-packaging input, not a native test-discovery project.
if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
return()
endif()

project(InProcCrashReportAppleNative)

include(../../../../../../eng/native/configurepaths.cmake)
include(${CLR_ENG_NATIVE_DIR}/configurecompiler.cmake)

if(NOT CLR_CMAKE_TARGET_APPLE_MOBILE OR NOT CLR_CMAKE_TARGET_ARCH_ARM64)
message(FATAL_ERROR "This adapter requires an Apple mobile arm64 target.")
endif()

if(NOT EXISTS "${CRASH_REPORT_MINIPAL_LIBRARY}")
message(FATAL_ERROR "Build the matching CoreCLR first; missing minipal: ${CRASH_REPORT_MINIPAL_LIBRARY}")
endif()

include_directories(${CLR_SRC_NATIVE_DIR})
set(LINK_LIBRARIES_ADDITIONAL "${CRASH_REPORT_MINIPAL_LIBRARY}")
set(CRASH_REPORT_APPLE_APP TRUE)
add_subdirectory(
"${CLR_REPO_ROOT_DIR}/src/tests/baseservices/exceptions/inproccrashreport/Shared"
fixture)
Loading
Loading