AccesViolation in tessdll.dll

112 views
Skip to first unread message

Luca

unread,
Jan 12, 2008, 5:10:58 PM1/12/08
to tesseract-ocr
Hi
i have faced an AV using tessdll.dll and it seems i get rid of it ...
so i want to notice about and also get your feedback if there could
be some drawbacks in the fix...
I have added an exported function to the dll that is

TESSDLL_API int __stdcall TessDllRecognize(const char*
inFilename,const char* outFilename,const char* lang);
this function implements the same code in the testdll main project
It happened that it was crashing as i called it twice
In fact , compare the 2 stacktraces and look for
"dawg_permute_and_select"
it have a null parameter (EDGE_ARRAY dawg) in the second place in the
av stack while is not null in the other stack


THIS IS AN ACCESS VIOLATION STACK
edge_char_of(unsigned __int64 * 0x00000000, __int64 0, int 67, int 0)
line 62 + 28 bytes
def_letter_is_okay(unsigned __int64 * 0x00000000, __int64 *
0x0013e3ec, int 0, char 0, const char * 0x0013e7c0, int 0) line 175 +
39 bytes
append_next_choice(unsigned __int64 * 0x00000000, __int64 0, char 5,
char * 0x0013e7c0, char * 0x0013e794, int * 0x0013e6f0, array_record *
0x01244ab0, int 0, choicestruct * 0x01242260, const char * 0x01132310
`string', float * 0x0013e5a4, float 54.9136, float -3.87398, float *
0x0013e5a8, float * 0x0013e64c, int 0, int 0, list_rec * * 0x0013e4b8)
line 206 + 96 bytes
dawg_permute(unsigned __int64 * 0x00000000, __int64 0, char 5,
array_record * 0x01244ab0, int 0, float * 0x0013e5a4, char *
0x0013e7c0, char * 0x0013e794, int * 0x0013e6f0, float 0.000000, float
0.000000, float * 0x0013e5a8, float * 0x0013e64c, int 0) line 285 +
125 bytes
dawg_permute_and_select(const char * 0x0113f808 `string', unsigned
__int64 * 0x00000000, char 5, array_record * 0x01244ab0, choicestruct
* 0x01247320, short 1) line 345 + 90 bytes
permute_words(array_record * 0x01244ab0, float 1000.00) line 1658 + 29
bytes
permute_all(array_record * 0x01244ab0, float 1000.00, choicestruct *
0x0013ec40) line 1067 + 13 bytes
permute_characters(array_record * 0x01244ab0, float 1000.00,
choicestruct * 0x0013ec54, choicestruct * 0x0013ec40) line 1119 + 17
bytes
chop_word_main(wordstruct * 0x01248360, int 1, choicestruct *
0x0013ec54, choicestruct * 0x0013ec40, unsigned char 0, unsigned char
0) line 443 + 21 bytes
cc_recog(wordstruct * 0x01248360, choicestruct * 0x0013ec54,
choicestruct * 0x0013ec40, unsigned char 0, unsigned char 0) line 253
+ 29 bytes
recog_word_recursive(WERD * 0x0124a930, DENORM * 0x012496a0, void
(PBLOB *, PBLOB *, PBLOB *, WERD *, DENORM *, BLOB_CHOICE_LIST &)*
0x00df4a07 tess_default_matcher(class PBLOB *,class PBLOB *,class
PBLOB *,class WERD *,class DENORM *,class BLOB_CHOICE_LIST &), void
(PBLOB *, DENORM *, unsigned char, char *, int, BLOB_CHOICE_LIST *)*
0x00000000, ...) line 170 + 112 bytes
recog_word(WERD * 0x0124a930, DENORM * 0x012496a0, void (PBLOB *,
PBLOB *, PBLOB *, WERD *, DENORM *, BLOB_CHOICE_LIST &)* 0x00df4a07
tess_default_matcher(class PBLOB *,class PBLOB *,class PBLOB *,class
WERD *,class DENORM *,class BLOB_CHOICE_LIST &), void (PBLOB *, DENORM
*, unsigned char, char *, int, BLOB_CHOICE_LIST *)* 0x00000000, ...)
line 77 + 41 bytes
tess_segment_pass1(WERD * 0x0124a930, DENORM * 0x012496a0, void (PBLOB
*, PBLOB *, PBLOB *, WERD *, DENORM *, BLOB_CHOICE_LIST &)* 0x00df4a07
tess_default_matcher(class PBLOB *,class PBLOB *,class PBLOB *,class
WERD *,class DENORM *,class BLOB_CHOICE_LIST &), WERD_CHOICE * &
0x00000000, BLOB_CHOICE_LIST_CLIST * 0x0013f244, WERD * & 0x00000000)
line 57 + 35 bytes
classify_word_pass1(WERD_RES * 0x01249690, ROW * 0x01249290, unsigned
char 0, CHAR_SAMPLES_LIST * 0x00000000, CHAR_SAMPLE_LIST * 0x00000000)
line 614 + 39 bytes
recog_all_words(PAGE_RES * 0x0124dad0, volatile ETEXT_STRUCT *
0x00000000, BOX * 0x00000000, short 1) line 308 + 36 bytes
TessDllAPI::ProcessPagePass1() line 167 + 21 bytes
TessDllAPI::BeginPageUpright(unsigned int 1217, unsigned int 950,
unsigned char * 0x02304eb0, unsigned char 1) line 149 + 8 bytes
TessDllRecognize(const char * 0x00bb8ec8, const char * 0x00bb8e98,
const char * 0x00b95118) line 322
PROJECTOCR! 0049fdf4()
------------------------------------------------------------------------------------------------
THIS IS OK
edge_char_of(unsigned __int64 * 0x023e0040, __int64 0, int 67, int 0)
line 62
def_letter_is_okay(unsigned __int64 * 0x023e0040, __int64 *
0x0013e3ec, int 0, char 0, const char * 0x0013e7c0, int 0) line 175 +
39 bytes
append_next_choice(unsigned __int64 * 0x023e0040, __int64 0, char 5,
char * 0x0013e7c0, char * 0x0013e794, int * 0x0013e6f0, array_record *
0x0122ecf0, int 0, choicestruct * 0x01243f90, const char * 0x01132310
`string', float * 0x0013e5a4, float 54.9136, float -3.87398, float *
0x0013e5a8, float * 0x0013e64c, int 0, int 0, list_rec * * 0x0013e4b8)
line 206 + 96 bytes
dawg_permute(unsigned __int64 * 0x023e0040, __int64 0, char 5,
array_record * 0x0122ecf0, int 0, float * 0x0013e5a4, char *
0x0013e7c0, char * 0x0013e794, int * 0x0013e6f0, float 0.000000, float
0.000000, float * 0x0013e5a8, float * 0x0013e64c, int 0) line 285 +
125 bytes
dawg_permute_and_select(const char * 0x0113f808 `string', unsigned
__int64 * 0x023e0040, char 5, array_record * 0x0122ecf0, choicestruct
* 0x012424e0, short 1) line 345 + 90 bytes
permute_words(array_record * 0x0122ecf0, float 1000.00) line 1658 + 29
bytes
permute_all(array_record * 0x0122ecf0, float 1000.00, choicestruct *
0x0013ec40) line 1067 + 13 bytes
permute_characters(array_record * 0x0122ecf0, float 1000.00,
choicestruct * 0x0013ec54, choicestruct * 0x0013ec40) line 1119 + 17
bytes
chop_word_main(wordstruct * 0x0124c1c0, int 1, choicestruct *
0x0013ec54, choicestruct * 0x0013ec40, unsigned char 0, unsigned char
0) line 443 + 21 bytes
cc_recog(wordstruct * 0x0124c1c0, choicestruct * 0x0013ec54,
choicestruct * 0x0013ec40, unsigned char 0, unsigned char 0) line 253
+ 29 bytes
recog_word_recursive(WERD * 0x0124a790, DENORM * 0x0124e3a0, void
(PBLOB *, PBLOB *, PBLOB *, WERD *, DENORM *, BLOB_CHOICE_LIST &)*
0x00df4a07 tess_default_matcher(class PBLOB *,class PBLOB *,class
PBLOB *,class WERD *,class DENORM *,class BLOB_CHOICE_LIST &), void
(PBLOB *, DENORM *, unsigned char, char *, int, BLOB_CHOICE_LIST *)*
0x00000000, ...) line 170 + 112 bytes
recog_word(WERD * 0x0124a790, DENORM * 0x0124e3a0, void (PBLOB *,
PBLOB *, PBLOB *, WERD *, DENORM *, BLOB_CHOICE_LIST &)* 0x00df4a07
tess_default_matcher(class PBLOB *,class PBLOB *,class PBLOB *,class
WERD *,class DENORM *,class BLOB_CHOICE_LIST &), void (PBLOB *, DENORM
*, unsigned char, char *, int, BLOB_CHOICE_LIST *)* 0x00000000, ...)
line 77 + 41 bytes
tess_segment_pass1(WERD * 0x0124a790, DENORM * 0x0124e3a0, void (PBLOB
*, PBLOB *, PBLOB *, WERD *, DENORM *, BLOB_CHOICE_LIST &)* 0x00df4a07
tess_default_matcher(class PBLOB *,class PBLOB *,class PBLOB *,class
WERD *,class DENORM *,class BLOB_CHOICE_LIST &), WERD_CHOICE * &
0x00000000, BLOB_CHOICE_LIST_CLIST * 0x0013f244, WERD * & 0x00000000)
line 57 + 35 bytes
classify_word_pass1(WERD_RES * 0x0124e390, ROW * 0x0124fdc0, unsigned
char 0, CHAR_SAMPLES_LIST * 0x00000000, CHAR_SAMPLE_LIST * 0x00000000)
line 614 + 39 bytes
recog_all_words(PAGE_RES * 0x0124fd20, volatile ETEXT_STRUCT *
0x00000000, BOX * 0x00000000, short 1) line 308 + 36 bytes
TessDllAPI::ProcessPagePass1() line 167 + 21 bytes
TessDllAPI::BeginPageUpright(unsigned int 1217, unsigned int 950,
unsigned char * 0x022e0068, unsigned char 1) line 149 + 8 bytes
TessDllRecognize(const char * 0x00c08ec8, const char * 0x00c08e98,
const char * 0x00be5118) line 322


so i have checked for dawg alloc and free and finally i discovered
that the reason is caused by the following code
void init_ms_debug() {
static int first_time = 1;

if (first_time) {
first_time = 0;
in wordrec/msmenus.cpp

this cause that init_permute() , that allocs EDGE_ARRAY dawg doesnt
get called the second time cauing the av

as i remark //first_time = 0; everything works great and i can
repeatly call the Recognize function for the peace of my mind
cheers

Ray Smith

unread,
Jan 12, 2008, 9:07:07 PM1/12/08
to tesser...@googlegroups.com
Yes I think that should fix it, as long as you only call init/end in matching pairs, so you can go happily on with that until the next release.
Ray.

Scan...@gmail.com

unread,
Jan 14, 2008, 7:34:48 AM1/14/08
to tesseract-ocr
The original ideas was for speed we only init once and then can rentry
different images. I believe this got broken in newer releases.

Luca

unread,
Jan 15, 2008, 5:17:01 AM1/15/08
to tesseract-ocr
i agree about the intention but actually some pointer are freed after
and realloc is not called the second time you alloc a TessDllAPI This
happens because of first_time static variable flag ...

As i'm newer to tesseract i choose to replicate the code in dlltest
main , that is passing an inputFilename,outFilename and language
parameters ... it works because of being a command line exe it only
instanciate TessDllAPI once then close ... it doesn't makes the bug
appears

as i rewrite it as exported function in a dll to be embedded in a
Delphi program and call it twice it get crashes

cheers

Scan...@gmail.com

unread,
Jan 15, 2008, 6:50:06 AM1/15/08
to tesseract-ocr
Don't forget the functions in are stddecl not _cdecl
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages