Home > Blockchain >  How to get a useful error message when a dart:ffi method fails?
How to get a useful error message when a dart:ffi method fails?

Time:01-14

I have a dart method that invokes some C code using dart:ffi. When the C code fails (for example due to some memory violation), I don't get any error message to indicate what's wrong, but only the whole process exits immediately with these messages:

[ 41627 ms] Service protocol connection closed.
[        ] Lost connection to device.
[    1 ms] DevFS: Deleting filesystem on the device (file:...)

I am not asking about catching the error, as I know these kinds of errors are fatal, I just want some useful logs to see whats happening.

Can I debug the native code somehow or at least get useful error messages about the reason/location of the crash?

CodePudding user response:

Assumptions: debugging a Windows DLL on Windows using a pure Dart test harness. It should work pretty much the same for a Flutter test harness (i.e. the example app in a Flutter plugin project), but in all likelihood you'll want to do much of the testing in as simple a test environment as you can.

You are going to need two projects: a Visual Studio DLL project and a pure Dart command line. (In what follows my examples are in d:\vcc\Dll2\ and d:\source\testffi2\ respectively. The Dart project has a main function in bin\testffi2.dart.)

For testing I removed the VS C DLL project boilerplate and replaced it with:

#include "pch.h"
#include "framework.h"
#include "Dll2.h"

#include <cstdint>

extern "C" __declspec(dllexport) int32_t sum(int32_t a, int32_t b) {
    return a   b;
}

and checked that it compiled OK (in Debug/x64 configuration). This built: D:\vcc\Dll2\x64\Debug\Dll2.dll as expected.

In the Dart project I created a simple test harness to load the DLL and the function and call it.

import 'dart:ffi';
import 'dart:io';

void main() {
  final dll = DynamicLibrary.open('D:\\vcc\\Dll2\\x64\\Debug\\Dll2.dll');
  final sumFunction = dll.lookupFunction<
      Int32 Function(
    Int32 a,
    Int32 b,
  ),
      int Function(
    int a,
    int b,
  )>('sum');

  print(sumFunction(123, 321));

  sleep(Duration(seconds: 5)); // this is just there so that the VCC debug
                               // window doesn't immediately close
}

Running this is the Dart IDE or from the command line does, indeed, print 444 as expected, but doesn't give you an opportunity to debug the C.

Finally, back in the Visual Studio project, change the debugging properties to launch the Dart test harness. Set the exe path to the Dart sdk binary, the command line to the Dart main file, and the working folder to the Dart project folder.

VS debug properties

Finally, set a breakpoint on the return a b line and click the Local Windows Debugger button. Execution pauses as expected in the Visual Studio debugger and the values of local variables a and b are visible, etc.

  • Related