khjde1207 / tesseract_ocr

Tesseract OCR for flutter
BSD 3-Clause "New" or "Revised" License
64 stars 33 forks source link

Crashes when running in parallel #21

Closed BernardinD closed 3 years ago

BernardinD commented 3 years ago

I'm trying to run multiple extractText() in parallel (and eventually in batches, if needed) but the function crashes.

I'm using Future.foreach() for the parallel design

Code:

paths = Directory(_directoryPath).listSync(recursive: false, followLinks:false);
Future.forEach(paths, (f) async{
      FlutterTesseractOcr.extractText(f.path, language: 'eng');
});

Error:

Build fingerprint: 'samsung/beyond0qltesq/beyond0q:11/RP1A.200720.012/G970USQS6GUJ2:user/release-keys'
Revision: '17'
ABI: 'arm64'
Timestamp: 2021-10-30 03:00:17-0400
pid: 21801, tid: 26122, name: Thread-8  >>> com.example.PhotoWordFind <<<
uid: 10460
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x788566a003
    x0  0000000000000001  x1  000000788566a003  x2  00000000000000a4  x3  00000078842b2dc0
    x4  00000078842b2e38  x5  0000000000000004  x6  0000007895567c20  x7  0a2e64616574736e
    x8  00000000000014c2  x9  000000000000001f  x10 0000000000000004  x11 0000000080000000
    x12 0000000000000358  x13 00000078842b2e38  x14 00000078856692a0  x15 0000000000000080
    x16 000000000000001a  x17 0000000000000000  x18 00000078760d8000  x19 000000792df4aaf0
    x20 000000792de74e70  x21 0000000000000004  x22 000000795de7be70  x23 0000007884212040
    x24 00000000000003cc  x25 00000078842b5040  x26 000000795de71010  x27 0000007b4defa6e0
    x28 000000795deccf00  x29 00000078955680a0
    lr  000000789135cf64  sp  0000007895568040  pc  000000789135d034  pst 0000000020000000
backtrace:
      #00 pc 000000000014f034  /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/lib/arm64/libtesseract.so (tesseract::ImageThresholder::ThresholdRectToPix(Pix*, int, int const*, int const*, Pix**) const+384) (BuildId: 0cacc3ca42dd4e1a324de02484b5e6450c729bc9)
      #01 pc 000000000014eb44  /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/lib/arm64/libtesseract.so (tesseract::ImageThresholder::ThresholdToPix(tesseract::PageSegMode, Pix**)+116) (BuildId: 0cacc3ca42dd4e1a324de02484b5e6450c729bc9)
      #02 pc 00000000000e6628  /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/lib/arm64/libtesseract.so (tesseract::TessBaseAPI::Threshold(Pix**)+388) (BuildId: 0cacc3ca42dd4e1a324de02484b5e6450c729bc9)
      #03 pc 00000000000e21c0  /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/lib/arm64/libtesseract.so (tesseract::TessBaseAPI::FindLines()+196) (BuildId: 0cacc3ca42dd4e1a324de02484b5e6450c729bc9)
      #04 pc 00000000000e2864  /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/lib/arm64/libtesseract.so (tesseract::TessBaseAPI::Recognize(ETEXT_DESC*)+56) (BuildId: 0cacc3ca42dd4e1a324de02484b5e6450c729bc9)
      #05 pc 00000000000e163c  /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/lib/arm64/libtesseract.so (tesseract::TessBaseAPI::GetUTF8Text()+60) (BuildId: 0cacc3ca42dd4e1a324de02484b5e6450c729bc9)
      #06 pc 00000000002a4038  /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/lib/arm64/libtesseract.so (Java_com_googlecode_tesseract_android_TessBaseAPI_nativeGetUTF8Text+64) (BuildId: 0cacc3ca42dd4e1a324de02484b5e6450c729bc9)
      #07 pc 000000000013ded4  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #08 pc 0000000000134564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #09 pc 0000000000198e94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+204) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #10 pc 000000000030c254  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #11 pc 000000000030736c  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+884) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #12 pc 000000000063d5fc  /apex/com.android.art/lib64/libart.so (MterpInvokeDirect+592) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #13 pc 000000000012e914  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #14 pc 00000000001de0c8  [anon:dalvik-classes.dex extracted in memory from /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/base.apk] (com.googlecode.tesseract.android.TessBaseAPI.getUTF8Text+12)
      #15 pc 000000000063b310  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1440) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #16 pc 000000000012e814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #17 pc 000000000020b4e2  [anon:dalvik-classes.dex extracted in memory from /data/app/~~RRPLCPC3X9M4EWNOw2dY4w==/com.example.PhotoWordFind-sZBYRbZKHG8UiWE4orGkjw==/base.apk] (io.paratoner.flutter_tesseract_ocr.MyRunnable.run+54)
      #18 pc 000000000063cca4  /apex/com.android.art/lib64/libart.so (MterpInvokeInterface+1840) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #19 pc 000000000012ea14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #20 pc 00000000000eb8c8  /apex/com.android.art/javalib/core-oj.jar (java.lang.Thread.run+8)
      #21 pc 00000000002fed48  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7983234147973590803)+268) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #22 pc 0000000000629a84  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+796) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #23 pc 000000000013dff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #24 pc 0000000000134564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #25 pc 0000000000198e94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+204) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #26 pc 0000000000532198  /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #27 pc 0000000000533398  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+440) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #28 pc 00000000005808b8  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1272) (BuildId: 590bc1a07a50a63c196efb048a7125f4)
      #29 pc 00000000000b6234  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: a9be8f8e3ba7df39d3fe4858932ef34b)
      #30 pc 0000000000050e64  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a9be8f8e3ba7df39d3fe4858932ef34b)
Lost connection to device.

Update: Similar issue when using Isolates as the parallel structure that doesn't happen when running the same code in serial main thread/isolate. Not sure if they're related. If not, I will create a new issue for the second one

Code (Partially pseudo code):

void threadFunction(testy message) {
  SendPort sendPortOfOldIsolate = message.sendPortOfOldIsolate;
  dynamic f = message.f;
  String name = message.name;
  ui.Size size = message.screenSize;

  FlutterTesseractOcr.extractText(path, language: 'eng').then((result){
      // Send signals to end all running search thread
      sendPortOfOldIsolate.send(result);
  });
}

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Isolate isolate=await Isolate.spawn(threadFunction, test);
  runApp(MyApp());
}

Error:

E/flutter (28590): [ERROR:flutter/runtime/dart_isolate.cc(1137)] Unhandled exception:
E/flutter (28590): Null check operator used on a null value
E/flutter (28590): #0      MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:142:86)
E/flutter (28590): #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:148:36)
E/flutter (28590): #2      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:331:12)
E/flutter (28590): #3      MethodChannelPathProvider.getApplicationDocumentsPath (package:path_provider_platform_interface/src/method_channel_path_provider.dart:50:10)
E/flutter (28590): #4      getApplicationDocumentsDirectory (package:path_provider/path_provider.dart:138:40)
E/flutter (28590): #5      FlutterTesseractOcr._loadTessData (package:flutter_tesseract_ocr/android_ios.dart:66:42)
E/flutter (28590): #6      FlutterTesseractOcr.extractText (package:flutter_tesseract_ocr/android_ios.dart:25:35)
E/flutter (28590): <asynchronous suspension>
E/flutter (28590): #7      OCR (package:PhotoWordFind/main.dart:29:10)
E/flutter (28590): <asynchronous suspension>
khjde1207 commented 3 years ago

paths = Directory(_directoryPath).listSync(recursive: false, followLinks:false); Future.forEach(paths, (f) async{ await FlutterTesseractOcr.extractText(f.path, language: 'eng'); }); Does this cause an error?

BernardinD commented 3 years ago

paths = Directory(_directoryPath).listSync(recursive: false, followLinks:false); Future.forEach(paths, (f) async{ await FlutterTesseractOcr.extractText(f.path, language: 'eng'); }); Does this cause an error?

@khjde1207 ~Yeah it does~ Sorry I meant no, there is no error with this

khjde1207 commented 3 years ago

https://pub.dev/packages/google_ml_kit this is faster Consider using google_ml_kit