Hi, On Fri, 9 Aug 2019, René Scharfe wrote: > Am 09.08.19 um 13:24 schrieb Carlo Arenas: > > disregard this version, it still broken (and wouldn't even build on > > some cases), the reasons why are still unclear though but at least it > > might > > seem from the last known run in windows that segfaults were prevented > > at last and something was still off enough to trigger a BUG (shouldn't > > be a concern with V6 or later that do PCRE2 migration to NED fully, as > > agreed) > > So how about starting stupidly simple? FWIW I am very much in favor of this approach. Thanks, Dscho > You can test it everywhere, it just needs libpcre2. It works without > that library as well (tested with "make USE_LIBPCRE= USE_LIBPCRE2= > test"), but doesn't allocate anything in that case, of course. The > character tables leak fix should be safe on top. If you detect > performance issues then we can address them in additional patches. > > -- >8 -- > Subject: [PATCH] grep: use xmalloc() for all PCRE2 allocations > > Build a PCRE2 global custom context when compiling a pattern and use it > to tell the library to use xmalloc() for allocations. This provides > consistent out-of-memory handling and makes sure it uses a custom > allocator, e.g. with USE_NED_ALLOCATOR. > > Signed-off-by: René Scharfe <l.s.r@xxxxxx> > --- > The function names are ridiculously long, I tried to stay within 80 > characters per line but gave up in the end and just kept going without > line breaks. Fits the "stupidly simple" approach.. > > grep.c | 23 +++++++++++++++++------ > grep.h | 2 ++ > 2 files changed, 19 insertions(+), 6 deletions(-) > > diff --git a/grep.c b/grep.c > index cd952ef5d3..44f4e38657 100644 > --- a/grep.c > +++ b/grep.c > @@ -482,6 +482,16 @@ static void free_pcre1_regexp(struct grep_pat *p) > #endif /* !USE_LIBPCRE1 */ > > #ifdef USE_LIBPCRE2 > +static void *pcre2_malloc(PCRE2_SIZE size, MAYBE_UNUSED void *memory_data) > +{ > + return xmalloc(size); > +} > + > +static void pcre2_free(void *pointer, MAYBE_UNUSED void *memory_data) > +{ > + free(pointer); > +} > + > static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt) > { > int error; > @@ -495,12 +505,12 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt > > assert(opt->pcre2); > > - p->pcre2_compile_context = NULL; > + p->pcre2_general_context = pcre2_general_context_create(pcre2_malloc, pcre2_free, NULL); > + p->pcre2_compile_context = pcre2_compile_context_create(p->pcre2_general_context); > > if (opt->ignore_case) { > if (has_non_ascii(p->pattern)) { > - character_tables = pcre2_maketables(NULL); > - p->pcre2_compile_context = pcre2_compile_context_create(NULL); > + character_tables = pcre2_maketables(p->pcre2_general_context); > pcre2_set_character_tables(p->pcre2_compile_context, character_tables); > } > options |= PCRE2_CASELESS; > @@ -513,7 +523,7 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt > p->pcre2_compile_context); > > if (p->pcre2_pattern) { > - p->pcre2_match_data = pcre2_match_data_create_from_pattern(p->pcre2_pattern, NULL); > + p->pcre2_match_data = pcre2_match_data_create_from_pattern(p->pcre2_pattern, p->pcre2_general_context); > if (!p->pcre2_match_data) > die("Couldn't allocate PCRE2 match data"); > } else { > @@ -550,10 +560,10 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt > return; > } > > - p->pcre2_jit_stack = pcre2_jit_stack_create(1, 1024 * 1024, NULL); > + p->pcre2_jit_stack = pcre2_jit_stack_create(1, 1024 * 1024, p->pcre2_general_context); > if (!p->pcre2_jit_stack) > die("Couldn't allocate PCRE2 JIT stack"); > - p->pcre2_match_context = pcre2_match_context_create(NULL); > + p->pcre2_match_context = pcre2_match_context_create(p->pcre2_general_context); > if (!p->pcre2_match_context) > die("Couldn't allocate PCRE2 match context"); > pcre2_jit_stack_assign(p->pcre2_match_context, NULL, p->pcre2_jit_stack); > @@ -605,6 +615,7 @@ static void free_pcre2_pattern(struct grep_pat *p) > pcre2_match_data_free(p->pcre2_match_data); > pcre2_jit_stack_free(p->pcre2_jit_stack); > pcre2_match_context_free(p->pcre2_match_context); > + pcre2_general_context_free(p->pcre2_general_context); > } > #else /* !USE_LIBPCRE2 */ > static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt) > diff --git a/grep.h b/grep.h > index 1875880f37..73b8b87a3a 100644 > --- a/grep.h > +++ b/grep.h > @@ -28,6 +28,7 @@ typedef int pcre_jit_stack; > #else > typedef int pcre2_code; > typedef int pcre2_match_data; > +typedef int pcre2_general_context; > typedef int pcre2_compile_context; > typedef int pcre2_match_context; > typedef int pcre2_jit_stack; > @@ -93,6 +94,7 @@ struct grep_pat { > int pcre1_jit_on; > pcre2_code *pcre2_pattern; > pcre2_match_data *pcre2_match_data; > + pcre2_general_context *pcre2_general_context; > pcre2_compile_context *pcre2_compile_context; > pcre2_match_context *pcre2_match_context; > pcre2_jit_stack *pcre2_jit_stack; > -- > 2.22.0 >