Skip to content

Commit

Permalink
Add specific test
Browse files Browse the repository at this point in the history
  • Loading branch information
gleocadie committed Jul 26, 2024
1 parent 104eb4b commit 1ad93b5
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 0 deletions.
20 changes: 20 additions & 0 deletions profiler/src/Demos/Samples.Computer01/ComputerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class ComputerService
private NullThreadNameBugCheck _nullThreadNameBugCheck;
private MethodsSignature _methodsSignature;
private SigSegvHandlerExecution _sigsegvHandler;
private LinuxDlIteratePhdrDeadlock _linuxDlIteratePhdrDeadlock;

#if NET5_0_OR_GREATER
private OpenLdapCrash _openldapCrash;
Expand Down Expand Up @@ -181,6 +182,10 @@ public void StartService(Scenario scenario, int nbThreads, int parameter)
StartStringConcat(parameter);
break;

case Scenario.LinuxDlIteratePhdrDeadlock:
StartLinuxDlIteratePhdrDeadlock();
break;

default:
throw new ArgumentOutOfRangeException(nameof(scenario), $"Unsupported scenario #{_scenario}");
}
Expand Down Expand Up @@ -311,6 +316,10 @@ public void StopService()
case Scenario.StringConcat:
StopStringConcat();
break;

case Scenario.LinuxDlIteratePhdrDeadlock:
StopLinuxDlIteratePhdrDeadlock();
break;
}
}

Expand Down Expand Up @@ -575,6 +584,12 @@ private void StartLinuxMallocDeadlock()
_linuxMallockDeadlock.Start();
}

private void StartLinuxDlIteratePhdrDeadlock()
{
_linuxDlIteratePhdrDeadlock = new LinuxDlIteratePhdrDeadlock();
_linuxDlIteratePhdrDeadlock.Start();
}

private void StartMeasureAllocations()
{
_measureAllocations = new MeasureAllocations();
Expand Down Expand Up @@ -749,6 +764,11 @@ private void StopLinuxMallocDeadlock()
_linuxMallockDeadlock.Stop();
}

private void StopLinuxDlIteratePhdrDeadlock()
{
_linuxDlIteratePhdrDeadlock.Stop();
}

private void StopMeasureAllocations()
{
_measureAllocations.Stop();
Expand Down
124 changes: 124 additions & 0 deletions profiler/src/Demos/Samples.Computer01/LinuxDlIteratePhdrDeadlock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// <copyright file="LinuxDlIteratePhdrDeadlock.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2022 Datadog, Inc.
// </copyright>

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;

namespace Samples.Computer01
{
internal class LinuxDlIteratePhdrDeadlock
{
private ManualResetEvent _stopEvent;
private Task _exceptionTask;
private Thread _worker;

public void Start()
{
if (_stopEvent != null)
{
throw new InvalidOperationException("Already running...");
}

_stopEvent = new ManualResetEvent(false);

_worker = new Thread(ExecuteCallToDlOpenDlClose)
{
IsBackground = false // set to false to prevent the app from shutting down. The test will fail
};
_worker.Start();

_exceptionTask = Task.Factory.StartNew(
() =>
{
var nbException = 0;
var loggingClock = Stopwatch.StartNew();
while (!IsEventSet())
{
if (loggingClock.ElapsedMilliseconds >= 1000)
{
Console.WriteLine($"* Nb thrown exception {nbException}");
Thread.Sleep(TimeSpan.FromMilliseconds(500));
nbException = 0;
loggingClock.Restart();
}

for (var i = 0; i < 20; i++)
{
try
{
throw new Exception("dl_iterate_phdr deadlock exception");
}
catch { }
nbException++;
}

// wait a bit randomly (23 is a prime number chosen randomly)
Thread.Sleep(TimeSpan.FromMilliseconds(23));
}
},
TaskCreationOptions.LongRunning);
}

public void Run()
{
Start();
Thread.Sleep(TimeSpan.FromSeconds(10));
Stop();
}

public void Stop()
{
if (_stopEvent == null)
{
throw new InvalidOperationException("Not running...");
}

_stopEvent.Set();

_worker.Join();
_exceptionTask.Wait();

_stopEvent.Dispose();
_stopEvent = null;
}

[DllImport("libdl.so", EntryPoint = "dlopen")]
private static extern IntPtr Dlopen(string filename, int flags);

[DllImport("libdl.so", EntryPoint = "dlclose")]
private static extern void DlClose(IntPtr handle);

private void ExecuteCallToDlOpenDlClose()
{
var loggingClock = Stopwatch.StartNew();
var counter = 0;

while (!IsEventSet())
{
if (loggingClock.ElapsedMilliseconds >= 1000)
{
Console.WriteLine($"* Nb execution {counter}");
Thread.Sleep(TimeSpan.FromMilliseconds(500));
counter = 0;
loggingClock.Restart();
}

var handle = Dlopen("libc.so.6", 2);
Thread.Sleep(TimeSpan.FromMilliseconds(10));
DlClose(handle);

counter++;
}
}

private bool IsEventSet()
{
return _stopEvent.WaitOne(0);
}
}
}
2 changes: 2 additions & 0 deletions profiler/src/Demos/Samples.Computer01/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public enum Scenario
Obfuscation,
ThreadSpikes,
StringConcat, // parameter = number of strings to concatenate
LinuxDlIteratePhdrDeadlock,
}

public class Program
Expand Down Expand Up @@ -76,6 +77,7 @@ public static void Main(string[] args)
// 24: use an obfuscated library
// 25: create thread spikes
// 26: string concatenation
// 27: custom dl_iterate_phdr deadlock
//
Console.WriteLine($"{Environment.NewLine}Usage:{Environment.NewLine} > {Process.GetCurrentProcess().ProcessName} " +
$"[--service] [--iterations <number of iterations to execute>] " +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// <copyright file="DlIteratePhdrDeadlock.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2022 Datadog, Inc.
// </copyright>

using Datadog.Profiler.IntegrationTests.Helpers;
using Datadog.Profiler.SmokeTests;
using Xunit;
using Xunit.Abstractions;

namespace Datadog.Profiler.IntegrationTests.LinuxOnly
{
[Trait("Category", "LinuxOnly")]
public class DlIteratePhdrDeadlock
{
private const string ScenarioLinuxDliteratePhdrDeadlock = "--scenario 27";
private readonly ITestOutputHelper _output;

public DlIteratePhdrDeadlock(ITestOutputHelper output)
{
_output = output;
}

[TestAppFact("Samples.Computer01")]
public void CheckApplicationDoesNotEndUpInDeadlock(string appName, string framework, string appAssembly)
{
var runner = new SmokeTestRunner(appName, framework, appAssembly, ScenarioLinuxDliteratePhdrDeadlock, _output);
runner.RunAndCheck();
}
}
}

0 comments on commit 1ad93b5

Please sign in to comment.