Revision: 708
http://www.exim.org/viewvc/pcre2?view=rev&revision=708
Author: ph10
Date: 2017-03-25 17:08:20 +0000 (Sat, 25 Mar 2017)
Log Message:
-----------
Improvements to the \=memory modifier in pcre2test.
Modified Paths:
--------------
code/trunk/ChangeLog
code/trunk/doc/pcre2test.1
code/trunk/src/pcre2test.c
Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog 2017-03-25 15:19:49 UTC (rev 707)
+++ code/trunk/ChangeLog 2017-03-25 17:08:20 UTC (rev 708)
@@ -92,7 +92,18 @@
memory allocation functions were used instead of whatever was used when the
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
------------------------------
Modified: code/trunk/doc/pcre2test.1
===================================================================
--- code/trunk/doc/pcre2test.1 2017-03-25 15:19:49 UTC (rev 707)
+++ code/trunk/doc/pcre2test.1 2017-03-25 17:08:20 UTC (rev 708)
@@ -1,4 +1,4 @@
-.TH PCRE2TEST 1 "24 March 2017" "PCRE 10.30"
+.TH PCRE2TEST 1 "25 March 2017" "PCRE 10.30"
.SH NAME
pcre2test - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS
@@ -1333,11 +1333,15 @@
.SS "Showing memory usage"
.rs
.sp
-The \fBmemory\fP modifier causes \fBpcre2test\fP to log all heap memory
-allocation and freeing calls that occur during a call to \fBpcre2_match()\fP.
-These occur only when a match requires a bigger vector than the default for
-remembering backtracking points. In many cases there will be none. No heap
-memory is allocated during matching with \fBpcre2_dfa_match\fP or with JIT.
+The \fBmemory\fP modifier causes \fBpcre2test\fP to log the sizes of all heap
+memory allocation and freeing calls that occur during a call to
+\fBpcre2_match()\fP. These occur only when a match requires a bigger vector
+than the default for remembering backtracking points. In many cases there will
+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"
@@ -1771,6 +1775,6 @@
.rs
.sp
.nf
-Last updated: 24 March 2017
+Last updated: 25 March 2017
Copyright (c) 1997-2017 University of Cambridge.
.fi
Modified: code/trunk/src/pcre2test.c
===================================================================
--- code/trunk/src/pcre2test.c 2017-03-25 15:19:49 UTC (rev 707)
+++ code/trunk/src/pcre2test.c 2017-03-25 17:08:20 UTC (rev 708)
@@ -78,6 +78,10 @@
#include <unistd.h>
#endif
+/* Debugging code enabler */
+
+// #define DEBUG_SHOW_MALLOC_ADDRESSES
+
/* Both libreadline and libedit are optionally supported. The user-supplied
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
@@ -188,6 +192,7 @@
#define JUNK_OFFSET 0xdeadbeef /* For initializing ovector */
#define LOCALESIZE 32 /* Size of locale name */
#define LOOPREPEAT 500000 /* Default loop count for timing */
+#define MALLOCLISTSIZE 20 /* For remembering mallocs */
#define PATSTACKSIZE 20 /* Pattern stack for save/restore testing */
#define REPLACE_MODSIZE 100 /* Field for reading 8-bit replacement */
#define VERSION_SIZE 64 /* Size of buffer for the version strings */
@@ -839,6 +844,10 @@
static void *patstack[PATSTACKSIZE];
static int patstacknext = 0;
+static void *malloclist[MALLOCLISTSIZE];
+static PCRE2_SIZE malloclistlength[MALLOCLISTSIZE];
+static uint32_t malloclistptr = 0;
+
#ifdef SUPPORT_PCRE2_8
static regex_t preg = { NULL, NULL, 0, 0, 0 };
#endif
@@ -2435,12 +2444,32 @@
/* 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)data;
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;
}
@@ -2448,7 +2477,32 @@
{
(void)data;
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);
}
@@ -6145,7 +6199,7 @@
fprintf(outfile, "** Replacement text is not supported with null_context.\n");
return PR_OK;
}
-
+
/* We now have the subject in dbuffer, with len containing the byte length, and
ulen containing the code unit length, with a copy in arg_ulen for use in match
function arguments (this gets changed to PCRE2_ZERO_TERMINATED when the
@@ -6288,10 +6342,16 @@
use_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)?
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;
+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. */
if (dat_datctl.jitstack != 0)