Xamarin物理设备调试执行HttpClient.PostAsync时触发SIGSEGV异常
物理设备调试应用时,搭建的视图页面包含2个Entry输入框、1个绑定REST API调用逻辑的按钮,调试过程中触发native崩溃,日志如下:
[System.out] [OkHttp] sendRequest<<
[apitrace] apitrace: warning: caught signal 11
[apitrace] call flush from exceptionCallback
[libc] Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7ffaf31ff0 in tid 15432 (companyname.add), pid 15432 (companyname.add)
经初步定位,崩溃触发点在MachineService类的PostAsync请求执行行,相关关联代码包含页面XAML、ViewModel逻辑、服务层请求逻辑三部分。
共4个直接触发问题的代码错误,按影响优先级排序:
- 属性无限递归导致栈溢出:ViewModel中
Machine_Qr、Machine_Name两个属性的getter错误返回属性自身,而非对应的私有后备字段,一旦绑定机制访问属性就会触发无限递归,线程栈被打满后直接触发SIGSEGV native崩溃,这是崩溃的核心诱因。 - 命令未实例化、请求时机错误:
Ajout命令只声明未初始化,且ViewModel构造函数中直接调用SaveMachine(),页面刚初始化、输入框未完成绑定、字段全为null时就会触发API请求,完全不符合点击按钮提交的交互预期。 - Android明文HTTP请求被系统拦截:接口地址使用
http://非加密协议,Android 9.0及以上版本默认禁止应用发起明文HTTP请求,请求被系统网络栈拦截时会触发native层异常。 - HttpClient用法不规范:每次发起请求都新建HttpClient实例,高频调用时会耗尽socket资源,容易触发底层网络库异常。
1. 修复属性递归问题
将两个属性的getter改为返回对应私有后备字段,修正后代码:
public string Machine_Qr { get => machine_Qr; // 原代码误写为返回Machine_Qr属性自身,触发无限递归 set { machine_Qr = value; NotifyPropertyChanged(nameof(Machine_Qr)); } } public string Machine_Name { get => machine_Name; // 原代码误写为返回Machine_Name属性自身,触发无限递归 set { machine_Name = value; NotifyPropertyChanged(nameof(Machine_Name)); } }
2. 正确初始化命令、修正请求触发时机
删除构造函数中直接调用SaveMachine()的代码,实例化Ajout命令绑定提交逻辑,异步调用避免阻塞UI线程:
public AjoutMachineVM() { // 删除原构造函数中直接调用SaveMachine()的逻辑,禁止在构造函数发起页面提交请求 Ajout = new Command(async () => await SaveMachine()); }
3. 配置Android允许明文HTTP请求
在Android项目的Resources/xml目录下新建network_security_config.xml文件,添加本地调试网段的明文放行规则:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">192.168.1.112</domain> </domain-config> </network-security-config>
在Android项目的AndroidManifest.xml的application标签下添加配置引用:
<application android:networkSecurityConfig="@xml/network_security_config" <!-- 保留原有其他属性配置 --> > <!-- 保留原有其他组件配置 --> </application>
4. 优化HttpClient用法
全局复用HttpClient实例,避免每次请求新建对象消耗资源:
public class MachineService : IMachineService { public const string Base_url = "http://192.168.1.112:45455/api/"; // 全局复用静态HttpClient实例 private static readonly HttpClient _client = new HttpClient(); public async Task AddMachine(Machine machine) { string url = Base_url + "machine/creation"; var response = await _client.PostAsync(url, new StringContent(JsonConvert.SerializeObject(machine), Encoding.UTF8, "application/json")); // 添加响应状态校验,请求失败时抛出异常方便上层捕获处理 response.EnsureSuccessStatusCode(); } }
完成以上修复后重新部署到物理设备调试,即可解决SIGSEGV崩溃问题,点击按钮可正常发起接口提交请求。
内容的提问来源于stack exchange,提问作者Gazdallah Amira

