Skip to content

Commit a378f34

Browse files
committed
hunting heap memory leakages in & around tesseract; turns out in the end it's easier to dig them up via the MSVC memory profiler, but DO REMEMBER to run that one as follows, or it will all bee for naught:
- put breakpoint at start of app; preferably beyond the initialization of the global fz_context() as that one will linger until the very eend and thus show as leakage. - run in debugger until first breakpoint. - create heap memory snapshot in the right-side panel - make sure the exit of the app has a breakpoint too! - run until the very end: it doesn't matter if it's not symmetrical: best to place the end breakpoint as late as possible. - create second memory snapshot once you get there in the debugger. - click in right-side panel on second snapshot memory leakage amount to get the diagnostics window. - once that one is visible, you can stop the debugger: it should remain, so you can click on lines and inspect leakage & reported callstacks / source code.
1 parent 85fe24d commit a378f34

File tree

11 files changed

+53
-17
lines changed

11 files changed

+53
-17
lines changed

include/tesseract/baseapi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,8 +826,10 @@ class TESS_API TessBaseAPI {
826826

827827
protected:
828828
Tesseract *tesseract_; ///< The underlying data object.
829+
#if !DISABLED_LEGACY_ENGINE
829830
Tesseract *osd_tesseract_; ///< For orientation & script detection.
830831
EquationDetect *equ_detect_; ///< The equation detector.
832+
#endif
831833
FileReader reader_; ///< Reads files from any filesystem.
832834
ImageThresholder *thresholder_; ///< Image thresholding module.
833835
std::vector<ParagraphModel *> *paragraph_models_;

src/api/baseapi.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,10 +1483,10 @@ bool TessBaseAPI::ProcessPage(Pix *pix, int page_index, const char *filename,
14831483
monitor.set_deadline_msecs(timeout_millisec);
14841484

14851485
// Now run the main recognition.
1486-
failed = Recognize(&monitor) < 0;
1486+
failed = (Recognize(&monitor) < 0);
14871487
} else {
14881488
// Normal layout and character recognition with no timeout.
1489-
failed = Recognize(nullptr) < 0;
1489+
failed = (Recognize(nullptr) < 0);
14901490
}
14911491

14921492
if (tesseract_->tessedit_write_images) {
@@ -2401,6 +2401,9 @@ bool TessBaseAPI::Threshold(Pix **pix) {
24012401
tesseract_->AddPixDebugPage(tesseract_->pix_thresholds(), "Otsu (tesseract) : Thresholds");
24022402
tesseract_->AddPixDebugPage(pix_binary, "Otsu (tesseract) : Binary = post-image");
24032403
}
2404+
2405+
if (!go)
2406+
pix_binary.destroy();
24042407
} else {
24052408
auto [ok, pix_grey, pix_binary, pix_thresholds] = thresholder_->Threshold(thresholding_method);
24062409

@@ -2421,7 +2424,10 @@ bool TessBaseAPI::Threshold(Pix **pix) {
24212424
tesseract_->AddPixDebugPage(tesseract_->pix_thresholds(), (caption + " : Thresholds").c_str());
24222425
tesseract_->AddPixDebugPage(pix_binary, (caption + " : Binary = post-image").c_str());
24232426
}
2424-
}
2427+
2428+
if (!go)
2429+
pix_binary.destroy();
2430+
}
24252431
}
24262432

24272433
thresholder_->GetImageSizes(&rect_left_, &rect_top_, &rect_width_, &rect_height_, &image_width_,

src/ccmain/pgedit.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,8 @@ void Tesseract::display_current_page_result(PAGE_RES* page_res) {
974974
//boxaDestroy(BOXA * *pboxa);
975975
l_uint32 bordercolor;
976976
composeRGBAPixel(255, 32, 32, 255, &bordercolor);
977-
pixDrawBoxa(pix, boxlist, 2, bordercolor);
977+
pix = pixDrawBoxa(pix, boxlist, 2, bordercolor);
978+
boxaDestroy(&boxlist);
978979

979980
int block_count = 1;
980981

@@ -1009,6 +1010,8 @@ void Tesseract::display_current_page_result(PAGE_RES* page_res) {
10091010
}
10101011
//image_win->Update();
10111012
}
1013+
1014+
this->AddPixDebugPage(pix, "current page results", false);
10121015
}
10131016

10141017
#endif // !GRAPHICS_DISABLED

src/ccmain/tesseractclass.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,11 +501,14 @@ Tesseract::Tesseract()
501501

502502
Tesseract::~Tesseract() {
503503
Clear();
504-
pix_original_.destroy();
505504
end_tesseract();
506505
for (auto *lang : sub_langs_) {
507506
delete lang;
508507
}
508+
#if !DISABLED_LEGACY_ENGINE
509+
delete equ_detect_;
510+
equ_detect_ = nullptr;
511+
#endif // !DISABLED_LEGACY_ENGINE
509512
delete lstm_recognizer_;
510513
lstm_recognizer_ = nullptr;
511514
}
@@ -535,6 +538,7 @@ void Tesseract::Clear() {
535538
#endif
536539
pixa_debug__.WritePNGs(file_path.c_str());
537540
}
541+
pix_original_.destroy();
538542
pixa_debug__.Clear();
539543
pix_binary_.destroy();
540544
pix_grey_.destroy();

src/ccstruct/debugpixa.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace tesseract {
4040
int color = depth < 8 ? 1 : (depth > 8 ? 0x00ff0000 : 0x80);
4141
Image pix_debug =
4242
pixAddSingleTextblock(pix, fonts_, caption, color, L_ADD_BELOW, nullptr);
43-
if (keep_a_copy)
43+
if (!keep_a_copy)
4444
pix.destroy();
4545
pixaAddPix(pixa_, pix_debug, L_INSERT);
4646
#endif

src/ccstruct/image.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ bool Image::isZero() const {
3939
return r == 1;
4040
}
4141

42+
Image& Image::operator =(Pix* pix) {
43+
if (pix_ != nullptr) {
44+
pixDestroy(&pix_);
45+
}
46+
pix_ = pix;
47+
return *this;
48+
}
49+
4250
Image Image::operator|(Image i) const {
4351
return pixOr(nullptr, pix_, i);
4452
}

src/ccstruct/image.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ class TESS_API Image {
3737
operator Pix *() const { return pix_; }
3838
explicit operator Pix **() { return &pix_; }
3939
Pix *operator->() const { return pix_; }
40+
Image& operator =(Pix* pix);
4041

4142
// api
4243
Image clone() const; // increases refcount
4344
Image copy() const; // does full copy
4445
void destroy();
4546
bool isZero() const;
47+
void replace(Pix* pix);
4648

4749
// ops
4850
Image operator|(Image) const;

src/dict/dict.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,13 @@ void Dict::End() {
385385
delete dawg;
386386
}
387387
}
388-
dawg_cache_->FreeDawg(bigram_dawg_);
388+
if (dawg_cache_ != nullptr) {
389+
dawg_cache_->FreeDawg(bigram_dawg_);
390+
}
389391
if (dawg_cache_is_ours_) {
390392
delete dawg_cache_;
391-
dawg_cache_ = nullptr;
392393
}
394+
dawg_cache_ = nullptr;
393395
for (auto successor : successors_) {
394396
delete successor;
395397
}

src/textord/colfind.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ void ColumnFinder::SetupAndFilterNoise(PageSegMode pageseg_mode, Image photo_mas
189189
//boxaDestroy(BOXA * *pboxa);
190190
l_uint32 bordercolor;
191191
composeRGBAPixel(255, 32, 32, 255, &bordercolor);
192-
pixDrawBoxa(pix, boxlist, 2, bordercolor);
192+
pix = pixDrawBoxa(pix, boxlist, 2, bordercolor);
193+
boxaDestroy(&boxlist);
193194

194195
input_block->plot_graded_blobs(pix);
195196

@@ -429,7 +430,8 @@ int ColumnFinder::FindBlocks(PageSegMode pageseg_mode, Image scaled_color, int s
429430
//boxaDestroy(BOXA * *pboxa);
430431
l_uint32 bordercolor;
431432
composeRGBAPixel(255, 32, 32, 255, &bordercolor);
432-
pixDrawBoxa(pix, boxlist, 2, bordercolor);
433+
pix = pixDrawBoxa(pix, boxlist, 2, bordercolor);
434+
boxaDestroy(&boxlist);
433435

434436
input_block->plot_graded_blobs(pix);
435437

@@ -479,7 +481,8 @@ int ColumnFinder::FindBlocks(PageSegMode pageseg_mode, Image scaled_color, int s
479481
//boxaDestroy(BOXA * *pboxa);
480482
l_uint32 bordercolor;
481483
composeRGBAPixel(255, 32, 32, 255, &bordercolor);
482-
pixDrawBoxa(pix, boxlist, 2, bordercolor);
484+
pix = pixDrawBoxa(pix, boxlist, 2, bordercolor);
485+
boxaDestroy(&boxlist);
483486

484487
part_grid_.DisplayBoxes(pix);
485488
DisplayTabVectors(pix);
@@ -544,7 +547,8 @@ int ColumnFinder::FindBlocks(PageSegMode pageseg_mode, Image scaled_color, int s
544547
//boxaDestroy(BOXA * *pboxa);
545548
l_uint32 bordercolor;
546549
composeRGBAPixel(255, 32, 32, 255, &bordercolor);
547-
pixDrawBoxa(pix, boxlist, 2, bordercolor);
550+
pix = pixDrawBoxa(pix, boxlist, 2, bordercolor);
551+
boxaDestroy(&boxlist);
548552

549553
part_grid_.DisplayBoxes(pix);
550554
if (!textord_debug_printable) {
@@ -660,7 +664,8 @@ void ColumnFinder::DisplayBlocks(BLOCK_LIST *blocks) {
660664
//boxaDestroy(BOXA * *pboxa);
661665
l_uint32 bordercolor;
662666
composeRGBAPixel(255, 32, 32, 255, &bordercolor);
663-
pixDrawBoxa(pix, boxlist, 2, bordercolor);
667+
pix = pixDrawBoxa(pix, boxlist, 2, bordercolor);
668+
boxaDestroy(&boxlist);
664669

665670
DisplayBoxes(pix);
666671
BLOCK_IT block_it(blocks);
@@ -704,7 +709,8 @@ void ColumnFinder::DisplayColumnBounds(PartSetVector *sets) {
704709
//boxaDestroy(BOXA * *pboxa);
705710
l_uint32 bordercolor;
706711
composeRGBAPixel(255, 32, 32, 255, &bordercolor);
707-
pixDrawBoxa(pix, boxlist, 2, bordercolor);
712+
pix = pixDrawBoxa(pix, boxlist, 2, bordercolor);
713+
boxaDestroy(&boxlist);
708714

709715
DisplayBoxes(pix);
710716
//col_win->Pen(textord_debug_printable ? ScrollView::BLUE : ScrollView::GREEN);

src/textord/tabfind.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,8 @@ void TabFind::TidyBlobs(TO_BLOCK *block) {
495495
//boxaDestroy(BOXA * *pboxa);
496496
l_uint32 bordercolor;
497497
composeRGBAPixel(255, 32, 32, 255, &bordercolor);
498-
pixDrawBoxa(pix, boxlist, 2, bordercolor);
498+
pix = pixDrawBoxa(pix, boxlist, 2, bordercolor);
499+
boxaDestroy(&boxlist);
499500

500501
block->plot_graded_blobs(pix);
501502
block->plot_noise_blobs(pix);

0 commit comments

Comments
 (0)