summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2006-12-04 16:20:02 +0000
committerDmitry Stogov <dmitry@php.net>2006-12-04 16:20:02 +0000
commitf7bc5165025959d91cd1dd686c8190464c61169d (patch)
treefa22c8b3d9d090fe11f20d4a6e8a92686ead6c42
parentbcf457d828f0634b8c3fbcd4236c64f3b06e60b1 (diff)
downloadphp-git-f7bc5165025959d91cd1dd686c8190464c61169d.tar.gz
Fixed bug #38274 (Memlimit fatal error sent to "wrong" stderr when using fastcgi)
-rw-r--r--NEWS2
-rw-r--r--Zend/zend_alloc.c37
2 files changed, 35 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index d432ec17ef..90986d8e31 100644
--- a/NEWS
+++ b/NEWS
@@ -133,6 +133,8 @@ PHP NEWS
ErrorDocument). (Ilia)
- Fixed bug #38319 (Remove bogus warnings from persistent PDO connections).
(Ilia)
+- Fixed bug #38274 (Memlimit fatal error sent to "wrong" stderr when using
+ fastcgi). (Dmitry)
- Fixed bug #38252 (Incorrect PDO error message on invalid default fetch
mode). (Ilia)
- Fixed bug #37773 (iconv_substr() gives "Unknown error" when string length = 1").
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index d3f5d836da..1c81eeb79a 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -327,6 +327,7 @@ struct _zend_mm_heap {
size_t limit;
size_t size;
size_t peak;
+ void *reserve;
#endif
#if ZEND_USE_MALLOC_MM
int use_zend_alloc;
@@ -339,6 +340,9 @@ struct _zend_mm_heap {
zend_mm_free_block free_buckets[ZEND_MM_NUM_BUCKETS];
};
+/* Reserved space for error reporting in case of memory overflow */
+#define ZEND_MM_RESERVE_SIZE 8*1024
+
#define ZEND_MM_TYPE_MASK 0x3L
#define ZEND_MM_FREE_BLOCK 0x0L
@@ -630,15 +634,17 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers,
#endif
heap->real_size = 0;
+ heap->overflow = 0;
+
#if MEMORY_LIMIT
heap->real_peak = 0;
heap->limit = 1<<30;
heap->size = 0;
heap->peak = 0;
+ heap->reserve = NULL;
+ heap->reserve = zend_mm_alloc(heap, ZEND_MM_RESERVE_SIZE);
#endif
- heap->overflow = 0;
-
return heap;
}
@@ -1014,6 +1020,13 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent
zend_mm_segment *segment;
zend_mm_segment *prev;
+#if MEMORY_LIMIT
+ if (heap->reserve) {
+ zend_mm_free(heap, heap->reserve);
+ heap->reserve = NULL;
+ }
+#endif
+
#if ZEND_DEBUG
if (!silent) {
zend_mm_check_leaks(heap);
@@ -1037,6 +1050,7 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent
heap->real_peak = 0;
heap->size = 0;
heap->peak = 0;
+ heap->reserve = zend_mm_alloc(heap, ZEND_MM_RESERVE_SIZE);
#endif
heap->overflow = 0;
}
@@ -1051,6 +1065,12 @@ static void zend_mm_safe_error(zend_mm_heap *heap,
#endif
size_t size)
{
+#if MEMORY_LIMIT
+ if (heap->reserve) {
+ zend_mm_free(heap, heap->reserve);
+ heap->reserve = NULL;
+ }
+#endif
if (heap->overflow == 0) {
char *error_filename;
uint error_lineno;
@@ -1210,10 +1230,15 @@ zend_mm_finished_searching_for_block:
segment_size = heap->block_size;
}
+ HANDLE_BLOCK_INTERRUPTIONS();
#if MEMORY_LIMIT
if (heap->real_size + segment_size > heap->limit) {
/* Memory limit overflow */
+#if ZEND_MM_CACHE
+ zend_mm_free_cache(heap);
+#endif
+ HANDLE_UNBLOCK_INTERRUPTIONS();
#if ZEND_DEBUG
zend_mm_safe_error(heap, "Allowed memory size of %d bytes exhausted at %s:%d (tried to allocate %d bytes)", heap->limit, __zend_filename, __zend_lineno, size);
#else
@@ -1222,8 +1247,6 @@ zend_mm_finished_searching_for_block:
}
#endif
- HANDLE_BLOCK_INTERRUPTIONS();
-
segment = (zend_mm_segment *) ZEND_MM_STORAGE_ALLOC(segment_size);
if (!segment) {
@@ -1513,6 +1536,9 @@ realloc_segment:
segment_copy = (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE);
#if MEMORY_LIMIT
if (heap->real_size + segment_size - segment_copy->size > heap->limit) {
+#if ZEND_MM_CACHE
+ zend_mm_free_cache(heap);
+#endif
HANDLE_UNBLOCK_INTERRUPTIONS();
#if ZEND_DEBUG
zend_mm_safe_error(heap, "Allowed memory size of %d bytes exhausted at %s:%d (tried to allocate %d bytes)", heap->limit, __zend_filename, __zend_lineno, size);
@@ -1524,6 +1550,9 @@ realloc_segment:
#endif
segment = ZEND_MM_STORAGE_REALLOC(segment_copy, segment_size);
if (!segment) {
+#if ZEND_MM_CACHE
+ zend_mm_free_cache(heap);
+#endif
HANDLE_UNBLOCK_INTERRUPTIONS();
#if ZEND_DEBUG
zend_mm_safe_error(heap, "Out of memory (allocated %d) at %s:%d (tried to allocate %d bytes)", heap->real_size, __zend_filename, __zend_lineno, size);