mcpField
1
1k-patching-native-modules

1k-patching-native-modules

github.com/onekeyhq開発2.5k59 回インストール今日更新
リポジトリ

1k-patching-native-modules について

クラッシュログの分析からネイティブモジュールの修正、パッチ生成までを案内するスキルです。iOS と Android の調査、ビルド生成物の削除、patch-package による確認を扱います。

主な機能

  1. 01iOS と Android のクラッシュログ分析
  2. 02ネイティブモジュールのソースと障害箇所の特定
  3. 03NULL とメモリ安全性の確認を適用
  4. 04パッチ生成前のビルド生成物削除
  5. 05パッチ内容の確認とコミット準備

活用シーン

  1. 01ネイティブモジュールが原因のアプリクラッシュ調査
  2. 02Swift または Kotlin の NULL 処理の修正
  3. 03Android のビルドファイルがパッチに入るのを防止
  4. 04依存モジュールの変更パッチを生成して検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/onekeyhq/app-monorepo --skill 1k-patching-native-modules

インストール後、Claude Code で/1k-patching-native-modulesを入力して読み込まれたか確認します。

詳細

ネイティブモジュールのパッチ適用

クラッシュログを分析し、ネイティブモジュールのバグを修正して、パッチを生成するには、次のワークフローに従ってください。

ワークフローの概要

1. Analyze Crash Log → 2. Locate Bug → 3. Fix Code → 4. Clean Build Artifacts → 5. Generate Patch → 6. Commit & PR

ステップ 1:クラッシュログを分析する

iOS のクラッシュ(EXC_BAD_ACCESS / KERN_INVALID_ADDRESS)

抽出する重要な情報:

  • 例外の種類:EXC_BAD_ACCESS、SIGABRT など
  • スタックトレース:クラッシュしている関数を特定します
  • メモリアドレス:nil ポインターの問題を特定するのに役立ちます
  • ライブラリ:クラッシュしているネイティブモジュールを確認します

クラッシュパターンの例:

EXC_BAD_ACCESS: KERN_INVALID_ADDRESS at 0x3c61c1a3b0d0
 objc_msgSend in unknown file
 -[SDWebImageManager cacheKeyForURL:context:]  ← Crashing function
 -[SDWebImageManager loadImageWithURL:options:context:progress:completed:]
Android のクラッシュ(NullPointerException / OOM)

次の点を確認します:

  • 例外クラス:NullPointerException、OutOfMemoryError
  • スタックトレース:Java/Kotlin のメソッドチェーン
  • スレッド情報:メインスレッドかバックグラウンドスレッドか

ステップ 2:バグの場所を特定する

ネイティブモジュールのソースを見つける
# iOS (Swift/Objective-C)
ls node_modules/<package>/ios/

# Android (Kotlin/Java)
ls node_modules/<package>/android/src/main/java/
よくあるクラッシュの原因
クラッシュの種類よくある原因修正パターン
EXC_BAD_ACCESSnil ポインターの参照解除guard let チェックを追加する
KERN_INVALID_ADDRESS解放済みメモリへのアクセス弱参照を使用する
NullPointerExceptionnull オブジェクトへのアクセスnull チェックを追加する
OutOfMemoryError大きな画像やデータの処理サイズ制限を追加する

ステップ 3:コードを修正する

iOS(Swift)- nil チェックパターン
// Before (crashes when uri is nil)
imageManager.loadImage(with: source.uri, ...)

// After (safe)
guard let sourceUri = source.uri, !sourceUri.absoluteString.isEmpty else {
  onError(["error": "Image source URI is nil or empty"])
  return
}
imageManager.loadImage(with: sourceUri, ...)
Android(Kotlin)- null チェックパターン
// Before
val uri = source.uri
loadImage(uri)

// After
val uri = source.uri ?: return
if (uri.toString().isEmpty()) return
loadImage(uri)

ステップ 4:ビルド成果物をクリーンアップする(重要)

パッチを生成する前に、必ず Android のビルドキャッシュをクリーンアップしてください:

# Remove Android build artifacts to avoid polluting the patch
rm -rf node_modules/<package>/android/build

# For expo-image specifically:
rm -rf node_modules/expo-image/android/build

重要な理由:

  • Android のビルドでは、.class、.jar、バイナリファイルが生成されます
  • これらがパッチファイルに混入し、ファイルが 5000 行以上になることがあります
  • patch-package にこれらの不要なファイルが含まれてしまいます

ステップ 5:パッチを生成する

# Generate patch file
npx patch-package <package-name>

# Example:
npx patch-package expo-image

パッチファイルの場所:patches/<package-name>+<version>.patch

パッチの内容を確認する
# Check patch doesn't include unwanted files
grep -c "android/build" patches/<package-name>*.patch
# Should return 0

# View actual changes
head -100 patches/<package-name>*.patch

ステップ 6:コミットして PR を作成する

# Stage patch file
git add patches/<package-name>*.patch

# Commit with descriptive message
git commit -m "fix(ios): prevent EXC_BAD_ACCESS crash in <package> when <condition>

Add guard checks in <package> native layer to prevent crash when <scenario>.

Fixes Sentry issue #XXXXX"

# Create PR
gh pr create --title "fix(ios): <description>" --base x

よく使われるパッケージとネイティブコードの場所

パッケージiOS ソースAndroid ソース
expo-imagenode_modules/expo-image/ios/node_modules/expo-image/android/src/
react-nativenode_modules/react-native/React/node_modules/react-native/ReactAndroid/
@react-native-async-storage/async-storagenode_modules/@react-native-async-storage/async-storage/ios/...android/src/
react-native-reanimatednode_modules/react-native-reanimated/ios/...android/src/

既存パッチの参照

パターンを確認するには、既存のパッチを参照してください:

ls patches/
cat patches/expo-image+3.0.10.patch

トラブルシューティング

パッチファイルのサイズが大きすぎる
# Clean all build artifacts
rm -rf node_modules/<package>/android/build
rm -rf node_modules/<package>/ios/build
rm -rf node_modules/<package>/.gradle

# Regenerate
npx patch-package <package>
パッチが適用されない
# Check package version matches
cat node_modules/<package>/package.json | grep version

# Rename patch if version changed
mv patches/<package>+old.patch patches/<package>+new.patch
Swift/Kotlin の構文について

Swift の guard let:

guard let value = optionalValue else {
  return  // Must exit scope
}
// value is now non-optional

Kotlin の null チェック:

val value = nullableValue ?: return
// value is now non-null

関連ファイル

  • パッチディレクトリ:patches/
  • expo-image の iOS:node_modules/expo-image/ios/ImageView.swift
  • expo-image の Android:node_modules/expo-image/android/src/main/java/expo/modules/image/

コメント