【问题标题】:App Crash instantly without exception or log (seems like xamarin/mono bug)应用程序立即崩溃,没有异常或日志(看起来像 xamarin/mono 错误)
【发布时间】:2017-10-23 17:26:57
【问题描述】:

这是一个奇怪的情况:),我已经在我的片段中实现了这个代码来扫描 multithread environment 中的 TCP Ports ,它是 crash when debugging ,有时还有 crash in release mode 也带有 thoose 消息:

E/art (12972): Nested signal detected - original signal being reported

F/art (12972): art/runtime/fault_handler.cc:117] Check failed: !initialized_

尝试设置 Target Android to 23 无效。

尝试运行adb shell setprop debug.mono.env MONO_DEBUG=soft-breakpoints,但没有成功。

尝试使用不同的Android API's Versions进行编译

知道为什么会这样吗??

这是我的代码:

    public void start()
    {
        for (int i = 0; i < 50; i++)
        {
            Task.Run(() => RunScanTcp());
            //ThreadPool.QueueUserWorkItem(RunScanTcp);
            //Thread thread = new Thread(new ThreadStart(RunScanTcp));
            //thread.Start();
        }
    }


    public void RunScanTcp()
    {
        while (abort != true)
        {
                port = port + 1;
                Log.Info("PORT SCANNER", port.ToString());
        }
    }

    public class PortList
    {
        private int start;
        private int stop;
        private int ports;
        private static readonly object _syncRoot = new object();

        public PortList(int starts, int stops)
        {
            start = starts;
            stop = stops;
            ports = start;
        }

        public bool MorePorts()
        {
            lock (_syncRoot)
            {
                return (stop - ports) >= 0;
            }
        }

        public int NextPort()
        {
            lock (_syncRoot)
            {
                if (MorePorts())
                {
                    return ports++;
                }
                return -1;
            }
        }
    }

我正在编译使用:

Android Version (Android 7.1 Nougat)

最低安卓版本:

Android 4.1 (API Level 16 - Jelly Bean)

目标安卓版本:

Compile Using SDK Version

更新:

Visual Studio Update 15.2 (26430.12)Xamarin 4.5.0.476 - 30/05/2017(dd/mm/yyyy) 之后,应用程序 crashed 同时也是 connected to debugger...

这是调试器的输出:

referenceTable GDEF length=814 1
referenceTable GSUB length=11364 1
referenceTable GPOS length=47302 1
referenceTable head length=54 1
referenceTable GDEF length=428 1
referenceTable GSUB length=2302 1
referenceTable GPOS length=43252 1
referenceTable head length=54 1
referenceTable GDEF length=808 1
referenceTable GSUB length=11364 1
referenceTable GPOS length=49128 1
referenceTable head length=54 1
referenceTable GDEF length=808 1
referenceTable GSUB length=11364 1
referenceTable GPOS length=47320 1
referenceTable head length=54 1
05-31 04:31:51.590 F/art     (17427): art/runtime/fault_handler.cc:117] Check failed: !initialized_ 

谢谢大家...

【问题讨论】:

  • 您是否尝试在 Android 构建选项的高级选项卡中检查“arm64-v8a”?
  • @GraceFeng-MSFT 是的,我试过了,又是同样的情况......
  • 您是否为您的发布版本启用了 proguard?
  • @HarisQureshi,我试过启用和禁用proguard,它是一样的,它仍然崩溃......
  • 如果你只创建 1 个任务而不是 50 个呢?此外,在你的任务循环中添加一个 Thread.Sleep() 怎么样?

标签: c# android xamarin mono xamarin.android


【解决方案1】:

正如你所描述的,它在没有你的代码部分的情况下工作......所以错误必须在你的代码中的某个地方。

让我们看看。

public void start()
{
    for (int i = 0; i < 50; i++)
    {
        Task.Run(() => RunScanTcp());
    }
}


public void RunScanTcp()
{
    while (abort != true)
    {
            port = port + 1;
            Log.Info("PORT SCANNER", port.ToString());
    }
}

start 方法中,您启动 50 个任务 - 而不是 awaiting 其中任何一个 - 这意味着可能所有任务都并行运行(至少肯定某些任务尝试访问port 同时)。

这些任务执行的是访问port 的方法,port 必须是包含类的字段。

如果没有锁,从多个任务/线程访问共享字段绝不是一个好主意。

尝试改用以下代码(如果您出于某种原因确实需要并行任务)。

public class YourClass
{

    private bool abort;
    private int port;
    private object portLock = new object();

    public void start()
    {
        for (int i = 0; i < 50; i++)
        {
            Task.Run(() => RunScanTcp());
        }
    }


    public void RunScanTcp()
    {
        while (abort != true && this.port < int.MaxValue)
        {
            lock (this.portLock) {
                port = port + 1;
                Log.Info("PORT SCANNER", port.ToString());
            }
        }
    }

}

可能更好的方法是只使用一个任务并在某处await 它。

public class YourClass
{

    private bool abort;
    private int port;
    private object portLock = new object();

    public Task start()
    {
        return Task.Run(() => RunScanTcp());
    }


    public void RunScanTcp()
    {
        lock (this.portLock) {
            while (abort != true && this.port < int.MaxValue)
            {
                port = port + 1;
                Log.Info("PORT SCANNER", port.ToString());
            }
        }
    }

}

如果这解决了您当前的问题,您可能需要添加另一个关于如何正确解决您实际尝试解决的问题的问题(因为您当前的代码基本上只是增加 port 直到它被中止或应用程序崩溃(因为它高于Int32 MaxValue)

【讨论】:

  • 实际上在portlist class 中使用锁(见上文)...问题似乎出在 xamarin.android 平台上,因为在上次更新 6/9/2017 Visual Studio 2017 version 15.2 (26430.13) 之后它不会崩溃不再...无论如何感谢您的时间,并且该代码仅用于演示,我不只是增加端口号
【解决方案2】:

所以我遇到了与 Xamarin 和 VS 类似的问题。事实证明,并非所有错误都记录到 VS 调试控制台中,但它们都在设备日志中。那段时间我要做的就是在我的机器上使用模拟器并在设备登录的同时运行它。并在崩溃后立即停止记录。在那个日志中很清楚问题是什么(在我的情况下是错误配置的权限)。希望对您有所帮助。

【讨论】:

  • 我没有尝试使用模拟器,我会尝试,希望以这种方式工作......
  • 它没有帮助我...... :(
  • 我真的不是说要使用模拟器,而是使用与VS调试控制台不同的“设备日志”。那件事记录了android机器中发生的所有事情(有明显的例外)。您可以从管理 a​​ndroid 设备按钮旁边的工具栏中打开它。
  • 它在 logcat 中也说同样的异常
【解决方案3】:
【解决方案4】:

问题似乎出在xamarin.android platform,因为在上次更新后6/9/2017Visual Studio 2017 version 15.2 (26430.13) 它不再崩溃...无论如何感谢您的时间.. 这个错误发生在尝试创建 (n) 线程数/任务...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 2018-08-27
    相关资源
    最近更新 更多