Improvements to the \=memory modifier in pcre2test.

This commit is contained in:
Philip.Hazel 2017-03-25 17:08:20 +00:00
parent 649ae8f6d5
commit 08543d4a74
3 changed files with 87 additions and 12 deletions

View File

@ -92,6 +92,17 @@ matching to find the minimum value for this limit.
memory allocation functions were used instead of whatever was used when the memory allocation functions were used instead of whatever was used when the
pattern was compiled. pattern was compiled.
17. Changes to the pcre2test "memory" modifier on a subject line. These apply
only to pcre2_match():
(a) Warn if null_context is set on both pattern and subject, because the
memory details cannot then be shown.
(b) Remember (up to a certain number of) memory allocations and their
lengths, and list only the lengths, so as to be system-independent.
(In practice, the new interpreter never has more than 2 blocks allocated
simultaneously.)
Version 10.23 14-February-2017 Version 10.23 14-February-2017
------------------------------ ------------------------------

View File

@ -1,4 +1,4 @@
.TH PCRE2TEST 1 "24 March 2017" "PCRE 10.30" .TH PCRE2TEST 1 "25 March 2017" "PCRE 10.30"
.SH NAME .SH NAME
pcre2test - a program for testing Perl-compatible regular expressions. pcre2test - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS .SH SYNOPSIS
@ -1333,11 +1333,15 @@ is added to the non-match message.
.SS "Showing memory usage" .SS "Showing memory usage"
.rs .rs
.sp .sp
The \fBmemory\fP modifier causes \fBpcre2test\fP to log all heap memory The \fBmemory\fP modifier causes \fBpcre2test\fP to log the sizes of all heap
allocation and freeing calls that occur during a call to \fBpcre2_match()\fP. memory allocation and freeing calls that occur during a call to
These occur only when a match requires a bigger vector than the default for \fBpcre2_match()\fP. These occur only when a match requires a bigger vector
remembering backtracking points. In many cases there will be none. No heap than the default for remembering backtracking points. In many cases there will
memory is allocated during matching with \fBpcre2_dfa_match\fP or with JIT. be no heap memory used and therefore no additional output. No heap memory is
allocated during matching with \fBpcre2_dfa_match\fP or with JIT, so in those
cases the \fBmemory\fP modifier never has any effect. For this modifier to
work, the \fBnull_context\fP modifier must not be set on both the pattern and
the subject, though it can be set on one or the other.
. .
. .
.SS "Setting a starting offset" .SS "Setting a starting offset"
@ -1771,6 +1775,6 @@ Cambridge, England.
.rs .rs
.sp .sp
.nf .nf
Last updated: 24 March 2017 Last updated: 25 March 2017
Copyright (c) 1997-2017 University of Cambridge. Copyright (c) 1997-2017 University of Cambridge.
.fi .fi

View File

@ -78,6 +78,10 @@ from www.cbttape.org. */
#include <unistd.h> #include <unistd.h>
#endif #endif
/* Debugging code enabler */
// #define DEBUG_SHOW_MALLOC_ADDRESSES
/* Both libreadline and libedit are optionally supported. The user-supplied /* Both libreadline and libedit are optionally supported. The user-supplied
original patch uses readline/readline.h for libedit, but in at least one system original patch uses readline/readline.h for libedit, but in at least one system
it is installed as editline/readline.h, so the configuration code now looks for it is installed as editline/readline.h, so the configuration code now looks for
@ -188,6 +192,7 @@ void vms_setsymbol( char *, char *, int );
#define JUNK_OFFSET 0xdeadbeef /* For initializing ovector */ #define JUNK_OFFSET 0xdeadbeef /* For initializing ovector */
#define LOCALESIZE 32 /* Size of locale name */ #define LOCALESIZE 32 /* Size of locale name */
#define LOOPREPEAT 500000 /* Default loop count for timing */ #define LOOPREPEAT 500000 /* Default loop count for timing */
#define MALLOCLISTSIZE 20 /* For remembering mallocs */
#define PATSTACKSIZE 20 /* Pattern stack for save/restore testing */ #define PATSTACKSIZE 20 /* Pattern stack for save/restore testing */
#define REPLACE_MODSIZE 100 /* Field for reading 8-bit replacement */ #define REPLACE_MODSIZE 100 /* Field for reading 8-bit replacement */
#define VERSION_SIZE 64 /* Size of buffer for the version strings */ #define VERSION_SIZE 64 /* Size of buffer for the version strings */
@ -839,6 +844,10 @@ static datctl dat_datctl;
static void *patstack[PATSTACKSIZE]; static void *patstack[PATSTACKSIZE];
static int patstacknext = 0; static int patstacknext = 0;
static void *malloclist[MALLOCLISTSIZE];
static PCRE2_SIZE malloclistlength[MALLOCLISTSIZE];
static uint32_t malloclistptr = 0;
#ifdef SUPPORT_PCRE2_8 #ifdef SUPPORT_PCRE2_8
static regex_t preg = { NULL, NULL, 0, 0, 0 }; static regex_t preg = { NULL, NULL, 0, 0, 0 };
#endif #endif
@ -2435,12 +2444,32 @@ return sys_errlist[n];
/* Alternative memory functions, to test functionality. */ /* Alternative memory functions, to test functionality. */
static void *my_malloc(size_t size, void *data) static void *my_malloc(PCRE2_SIZE size, void *data)
{ {
void *block = malloc(size); void *block = malloc(size);
(void)data; (void)data;
if (show_memory) if (show_memory)
fprintf(outfile, "malloc %3d %p\n", (int)size, block); {
if (block == NULL)
{
fprintf(outfile, "** malloc() failed for %zd\n", size);
}
else
{
fprintf(outfile, "malloc %5zd", size);
#ifdef DEBUG_SHOW_MALLOC_ADDRESSES
fprintf(outfile, " %p", block); /* Not portable */
#endif
if (malloclistptr < MALLOCLISTSIZE)
{
malloclist[malloclistptr] = block;
malloclistlength[malloclistptr++] = size;
}
else
fprintf(outfile, " (not remembered)");
fprintf(outfile, "\n");
}
}
return block; return block;
} }
@ -2448,7 +2477,32 @@ static void my_free(void *block, void *data)
{ {
(void)data; (void)data;
if (show_memory) if (show_memory)
fprintf(outfile, "free %p\n", block); {
uint32_t i, j;
BOOL found = FALSE;
fprintf(outfile, "free");
for (i = 0; i < malloclistptr; i++)
{
if (block == malloclist[i])
{
fprintf(outfile, " %5zd", malloclistlength[i]);
malloclistptr--;
for (j = i; j < malloclistptr; j++)
{
malloclist[j] = malloclist[j+1];
malloclistlength[j] = malloclistlength[j+1];
}
found = TRUE;
break;
}
}
if (!found) fprintf(outfile, " unremembered block");
#ifdef DEBUG_SHOW_MALLOC_ADDRESSES
fprintf(outfile, " %p", block); /* Not portable */
#endif
fprintf(outfile, "\n");
}
free(block); free(block);
} }
@ -6288,10 +6342,16 @@ NULL context. */
use_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)? use_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)?
NULL : PTR(dat_context); NULL : PTR(dat_context);
/* Enable display of malloc/free if wanted. */ /* Enable display of malloc/free if wanted. We can do this only if either the
pattern or the subject is processed with a context. */
show_memory = (dat_datctl.control & CTL_MEMORY) != 0; show_memory = (dat_datctl.control & CTL_MEMORY) != 0;
if (show_memory &&
(pat_patctl.control & dat_datctl.control & CTL_NULLCONTEXT) != 0)
fprintf(outfile, "** \\=memory requires either a pattern or a subject "
"context: ignored\n");
/* Create and assign a JIT stack if requested. */ /* Create and assign a JIT stack if requested. */
if (dat_datctl.jitstack != 0) if (dat_datctl.jitstack != 0)