aspect_frontend_server icon indicating copy to clipboard operation
aspect_frontend_server copied to clipboard

mixin类注入代码失败

Open fengguangbo opened this issue 3 years ago • 3 comments

做全埋点时,需要hook GestureBinding类的dispatchevent方法,这个类是mixin类,注入代码虽然提示成功,实际没效果,打断点,也没有看到注入的逻辑

fengguangbo avatar Mar 02 '22 12:03 fengguangbo

这个时候可能需要用isRegex了,以下是一个例子: @pragma('vm:entry-point') @pragma("aopd:inject", { "importUri": "package:example/main.dart", "clsName": r"__.+MixinHomePageState", "methodName": "-_test6", "isRegex": true })

lancexin avatar Mar 25 '22 10:03 lancexin

@pragma('vm:entry-point')
  @pragma("aopd:inject", {
    "importUri": "package:flutter/src/gestures/binding.dart",
    "clsName": r"__.+GestureBinding",
    "methodName": "-dispatchEvent",
    "isRegex": true
  })
  //必须是static,不然不起作用
  static void hookHitTest(
      Object target,
      String functionName,
      List<dynamic> positionalParams,
      Map<String, dynamic> namedParams,
      Function proceed) {
        debugPrint('hookHitTest - start');
        "[Inject] $functionName start ${positionalParams[0]} ${positionalParams[1]} ${namedParams["key3"]}");
        debugPrint('hookHitTest - end');
      Function.apply(proceed, positionalParams, _transToNamedParams(namedParams));
  }

为啥我加上这个后,run就失败了呢。这个问题有解决吗? image

WillieWu avatar Apr 27 '22 03:04 WillieWu

如果不起作用,可能是因为Mixin是基于某个Interface的,这个时候Mixin会抽转换成abstruct class,那用下面的试试: @pragma('vm:entry-point') @pragma("aopd:inject", { "importUri": "package:flutter/src/gestures/binding.dart", "clsName": "GestureBinding", "methodName": "-dispatchEvent", "isRegex": false }) //必须是static,不然不起作用 static void hookHitTest( Object target, String functionName, List positionalParams, Map<String, dynamic> namedParams, Function proceed) { debugPrint('hookHitTest - start'); "[Inject] $functionName start ${positionalParams[0]} ${positionalParams[1]} ${namedParams["key3"]}"); debugPrint('hookHitTest - end'); Function.apply(proceed, positionalParams, _transToNamedParams(namedParams)); }

如果发现注入不起作用,可以用dump_kernal工具dump处注入后的dill文件查看是否已经注入成功: 首先通过工具注入原始的dill文件: dart run frontend_server.dart.snapshot --sdk-root /Users/lixin/Documents/flutter_macos_stable/bin/cache/artifacts/engine/common/flutter_patched_sdk/ --target=flutter --no-print-incremental-dependencies -Dflutter.inspector.structuredErrors=true -DFLUTTER_WEB_AUTO_DETECT=true -Ddart.vm.profile=false -Ddart.vm.product=false --enable-asserts --track-widget-creation --packages /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/package_config.json --output-dill app.dill --depfile /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/flutter_build/77af0f210cf497f2ec8c2faa230bd8ab/kernel_snapshot.d package:example/main.dart

然后查看注入后的dill文件是否已经注入成功: dart /Users/lixin/Documents/FlutterWorkspace/dart_sdk/sdk/pkg/vm/bin/dump_kernel.dart app.dill injected.out.dill.txt

查看injected.out.dill.txt,查找关键字 "method dispatchEvent"观察这个方法体里是否已经存在注入的代码,如果已经存在则表示注入是成功的,但是触发不了函数,可能是其它原因

lancexin avatar May 14 '22 05:05 lancexin