Skip to content

Commit 765e12b

Browse files
fix: диагностика нативного crash в VPN сервисе + оптимизация multi-process
- V2RayVpnService.startService(): полностью обёрнут в try-catch(Throwable), пошаговый логгинг перед каждым потенциально опасным вызовом (fd access, startCoreLoop). - AngApplication: SmartConnect, WorkManager, Toasty, initRoutingRulesets теперь НЕ запускаются в сервисном процессе :RunSoLibV2RayDaemon. Раньше SmartConnect делал сетевые запросы при каждом перезапуске VPN сервиса. - Добавлен PID в логи onStartCommand и startService для отслеживания процессов.
1 parent a3a6718 commit 765e12b

2 files changed

Lines changed: 64 additions & 25 deletions

File tree

V2rayNG/app/src/main/java/com/kiktor/v2whitelist/AngApplication.kt

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.kiktor.v2whitelist
22

3+
import android.app.ActivityManager
34
import android.content.Context
5+
import android.os.Process
6+
import android.util.Log
47
import androidx.multidex.MultiDexApplication
58
import androidx.work.Configuration
69
import androidx.work.WorkManager
@@ -31,32 +34,50 @@ class AngApplication : MultiDexApplication() {
3134
.setDefaultProcessName("${ANG_PACKAGE}:bg")
3235
.build()
3336

37+
/**
38+
* Checks if the current process is the main application process.
39+
*/
40+
private fun isMainProcess(): Boolean {
41+
val pid = Process.myPid()
42+
val am = getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager ?: return false
43+
return am.runningAppProcesses?.any { it.pid == pid && it.processName == packageName } == true
44+
}
45+
3446
/**
3547
* Initializes the application.
3648
*/
3749
override fun onCreate() {
3850
super.onCreate()
3951

52+
val isMain = isMainProcess()
53+
Log.i(AppConfig.TAG, "AngApplication.onCreate: pid=${Process.myPid()}, isMainProcess=$isMain")
54+
4055
MMKV.initialize(this)
4156

4257
// Ensure critical preference defaults are present in MMKV early
4358
SettingsManager.ensureDefaultSettings()
44-
SettingsManager.setNightMode()
45-
// Initialize WorkManager with the custom configuration
46-
WorkManager.initialize(this, workManagerConfiguration)
4759

48-
// Initialize V2Ray core environment globally
60+
// Initialize V2Ray core environment globally (needed in all processes)
4961
V2RayNativeManager.initCoreEnv(this)
5062

51-
SettingsManager.initRoutingRulesets(this)
52-
SettingsManager.migrateHysteria2PinSHA256()
63+
// The rest only runs in the main process
64+
if (isMain) {
65+
SettingsManager.setNightMode()
66+
// Initialize WorkManager with the custom configuration
67+
WorkManager.initialize(this, workManagerConfiguration)
68+
69+
SettingsManager.initRoutingRulesets(this)
70+
SettingsManager.migrateHysteria2PinSHA256()
5371

54-
es.dmoral.toasty.Toasty.Config.getInstance()
55-
.setGravity(android.view.Gravity.BOTTOM, 0, 200)
56-
.apply()
72+
es.dmoral.toasty.Toasty.Config.getInstance()
73+
.setGravity(android.view.Gravity.BOTTOM, 0, 200)
74+
.apply()
5775

58-
CoroutineScope(Dispatchers.Main).launch {
59-
SmartConnectManager.checkAndSetupSubscription(this@AngApplication)
76+
CoroutineScope(Dispatchers.Main).launch {
77+
SmartConnectManager.checkAndSetupSubscription(this@AngApplication)
78+
}
79+
} else {
80+
Log.i(AppConfig.TAG, "AngApplication.onCreate: service process, skipping UI/SmartConnect init")
6081
}
6182
}
6283
}

V2rayNG/app/src/main/java/com/kiktor/v2whitelist/service/V2RayVpnService.kt

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,20 @@ class V2RayVpnService : VpnService(), ServiceControl {
9696
}
9797

9898
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
99-
Log.i(AppConfig.TAG, "onStartCommand: VPN service starting")
99+
Log.i(AppConfig.TAG, "onStartCommand: VPN service starting (pid=${android.os.Process.myPid()})")
100100
NotificationManager.showNotification(null)
101101

102102
if (!setupVpnService()) {
103103
Log.e(AppConfig.TAG, "onStartCommand: setupVpnService failed, service will stop")
104104
return START_NOT_STICKY
105105
}
106106

107-
startService()
107+
try {
108+
startService()
109+
} catch (t: Throwable) {
110+
Log.e(AppConfig.TAG, "onStartCommand: startService() threw exception", t)
111+
stopAllService()
112+
}
108113
return START_STICKY
109114
}
110115

@@ -113,20 +118,33 @@ class V2RayVpnService : VpnService(), ServiceControl {
113118
}
114119

115120
override fun startService() {
116-
val vpnInterface = mInterface
117-
if (vpnInterface == null) {
118-
Log.e(AppConfig.TAG, "startService: VPN interface is null — VPN not established, stopping service")
119-
// Останавливаем сервис явно, чтобы не оставаться в неопределённом состоянии
120-
stopAllService()
121-
return
122-
}
123-
Log.i(AppConfig.TAG, "startService: VPN interface OK (fd=${vpnInterface.fd}), starting core loop")
124-
if (!V2RayServiceManager.startCoreLoop(vpnInterface)) {
125-
Log.e(AppConfig.TAG, "startService: startCoreLoop returned false, stopping service")
121+
Log.i(AppConfig.TAG, "startService: entering method (pid=${android.os.Process.myPid()})")
122+
try {
123+
val vpnInterface = mInterface
124+
if (vpnInterface == null) {
125+
Log.e(AppConfig.TAG, "startService: VPN interface is null — VPN not established, stopping service")
126+
stopAllService()
127+
return
128+
}
129+
Log.i(AppConfig.TAG, "startService: mInterface is not null, about to access fd...")
130+
val fd = try { vpnInterface.fd } catch (e: Exception) {
131+
Log.e(AppConfig.TAG, "startService: vpnInterface.fd threw exception (fd already closed?)", e)
132+
stopAllService()
133+
return
134+
}
135+
Log.i(AppConfig.TAG, "startService: VPN interface OK (fd=$fd), calling startCoreLoop...")
136+
val result = V2RayServiceManager.startCoreLoop(vpnInterface)
137+
Log.i(AppConfig.TAG, "startService: startCoreLoop returned $result")
138+
if (!result) {
139+
Log.e(AppConfig.TAG, "startService: startCoreLoop returned false, stopping service")
140+
stopAllService()
141+
return
142+
}
143+
Log.i(AppConfig.TAG, "startService: core loop started successfully")
144+
} catch (t: Throwable) {
145+
Log.e(AppConfig.TAG, "startService: FATAL exception", t)
126146
stopAllService()
127-
return
128147
}
129-
Log.i(AppConfig.TAG, "startService: core loop started successfully")
130148
}
131149

132150
override fun stopService() {

0 commit comments

Comments
 (0)