View Issue Details

IDProjectCategoryView StatusLast Update
0000474XdebugFeature/Change requestpublic2017-12-02 18:36
ReporterjacobweberAssigned Toderick 
PrioritynormalSeveritymajorReproducibilityN/A
Status closedResolutionfixed 
Product Version2.0.0dev 
Target Version2.6.0Fixed in Version2.6.0alpha1 
Summary0000474: Implement memory profiling
DescriptionAny change we can get this patch folded into an Xdebug release? It seems to work for me.
http://xdebug.org/archives/xdebug-general/1228.html
TagsNo tags attached.
Operating System
PHP Version5.3.0

Activities

atis

2011-10-06 18:55

reporter  

xdebug_mem.patch (5,602 bytes)
diff --git a/xdebug_private.h b/xdebug_private.h
index 624ff48..c0fe898 100644
--- a/xdebug_private.h
+++ b/xdebug_private.h
@@ -136,6 +136,7 @@ typedef struct _xdebug_call_entry {
 	char       *function;
 	int         lineno;
 	double      time_taken;
+	long        mem_used;
 } xdebug_call_entry;
 
 typedef struct xdebug_aggregate_entry {
@@ -146,6 +147,7 @@ typedef struct xdebug_aggregate_entry {
 	int         call_count;
 	double      time_own;
 	double      time_inclusive;
+	long        mem_used;
 	HashTable  *call_list;
 } xdebug_aggregate_entry;
 
@@ -153,6 +155,7 @@ typedef struct xdebug_profile {
 	double        time;
 	double        mark;
 	long          memory;
+	long          mem_mark;
 	xdebug_llist *call_list;
 } xdebug_profile;
 
diff --git a/xdebug_profiler.c b/xdebug_profiler.c
index c8768be..dc16103 100644
--- a/xdebug_profiler.c
+++ b/xdebug_profiler.c
@@ -84,7 +84,11 @@ int xdebug_profiler_init(char *script_name TSRMLS_DC)
 	}
 	fprintf(XG(profile_file), "version: 1\ncreator: xdebug %s\n", XDEBUG_VERSION);
 	fprintf(XG(profile_file), "cmd: %s\npart: 1\npositions: line\n\n", script_name);
+#if HAVE_PHP_MEMORY_USAGE
+	fprintf(XG(profile_file), "events: Time Memory\n\n");
+#else
 	fprintf(XG(profile_file), "events: Time\n\n");
+#endif
 	fflush(XG(profile_file));
 	return SUCCESS;
 }
@@ -109,6 +113,11 @@ static inline void xdebug_profiler_function_push(function_stack_entry *fse)
 	fse->profile.time += xdebug_get_utime();
 	fse->profile.time -= fse->profile.mark;
 	fse->profile.mark = 0;
+#if HAVE_PHP_MEMORY_USAGE
+	fse->profile.memory += XG_MEMORY_USAGE();
+	fse->profile.memory -= fse->profile.mem_mark;
+	fse->profile.mem_mark = 0;
+#endif
 }
 
 void xdebug_profiler_function_continue(function_stack_entry *fse)
@@ -125,6 +134,10 @@ void xdebug_profiler_function_user_begin(function_stack_entry *fse TSRMLS_DC)
 {
 	fse->profile.time = 0;
 	fse->profile.mark = xdebug_get_utime();
+#if HAVE_PHP_MEMORY_USAGE
+	fse->profile.memory = 0;
+	fse->profile.mem_mark = XG_MEMORY_USAGE();
+#endif
 }
 
 
@@ -172,6 +185,9 @@ void xdebug_profiler_function_user_end(function_stack_entry *fse, zend_op_array*
 		ce->time_taken = fse->profile.time;
 		ce->lineno = fse->lineno;
 		ce->user_defined = fse->user_defined;
+#if HAVE_PHP_MEMORY_USAGE
+		ce->mem_used = fse->profile.memory;
+#endif
 
 		xdebug_llist_insert_next(fse->prev->profile.call_list, NULL, ce);
 	}
@@ -189,7 +205,11 @@ void xdebug_profiler_function_user_end(function_stack_entry *fse, zend_op_array*
 	xdfree(tmp_name);
 
 	if (fse->function.function && strcmp(fse->function.function, "{main}") == 0) {
+#if HAVE_PHP_MEMORY_USAGE
+		fprintf(XG(profile_file), "\nsummary: %lu %u\n\n", (unsigned long) (fse->profile.time * 1000000), (fse->profile.memory));
+#else
 		fprintf(XG(profile_file), "\nsummary: %lu\n\n", (unsigned long) (fse->profile.time * 1000000));
+#endif
 	}
 	fflush(XG(profile_file));
 
@@ -204,12 +224,22 @@ void xdebug_profiler_function_user_end(function_stack_entry *fse, zend_op_array*
 	{
 		xdebug_call_entry *call_entry = XDEBUG_LLIST_VALP(le);
 		fse->profile.time -= call_entry->time_taken;
+#if HAVE_PHP_MEMORY_USAGE
+		fse->profile.memory -= call_entry->mem_used;
+#endif
 	}
+#if HAVE_PHP_MEMORY_USAGE
+	fprintf(XG(profile_file), "%d %lu %ld\n", default_lineno, (unsigned long) (fse->profile.time * 1000000), (fse->profile.memory));
+#else
 	fprintf(XG(profile_file), "%d %lu\n", default_lineno, (unsigned long) (fse->profile.time * 1000000));
+#endif
 
 	/* update aggregate data */
 	if (XG(profiler_aggregate)) {
 		fse->aggr_entry->time_own += fse->profile.time;
+#if HAVE_PHP_MEMORY_USAGE
+		fse->aggr_entry->mem_used += fse->profile.memory;
+#endif
 	}
 
 	/* dump call list */
@@ -226,7 +256,11 @@ void xdebug_profiler_function_user_end(function_stack_entry *fse, zend_op_array*
 		}
 		
 		fprintf(XG(profile_file), "calls=1 0 0\n");
+#if HAVE_PHP_MEMORY_USAGE
+		fprintf(XG(profile_file), "%d %lu %ld\n", call_entry->lineno, (unsigned long) (call_entry->time_taken * 1000000), (call_entry->mem_used));
+#else
 		fprintf(XG(profile_file), "%d %lu\n", call_entry->lineno, (unsigned long) (call_entry->time_taken * 1000000));
+#endif
 	}
 	fprintf(XG(profile_file), "\n");
 	fflush(XG(profile_file));
@@ -251,9 +285,17 @@ static int xdebug_print_aggr_entry(void *pDest, void *argument TSRMLS_DC)
 
 	fprintf(fp, "fl=%s\n", xae->filename);
 	fprintf(fp, "fn=%s\n", xae->function);
+#if HAVE_PHP_MEMORY_USAGE
+	fprintf(fp, "%d %lu %ld\n", 0, (unsigned long) (xae->time_own * 1000000), (xae->mem_used));
+#else
 	fprintf(fp, "%d %lu\n", 0, (unsigned long) (xae->time_own * 1000000));
+#endif
 	if (strcmp(xae->function, "{main}") == 0) {
+#if HAVE_PHP_MEMORY_USAGE
+		fprintf(fp, "\nsummary: %lu %lu\n\n", (unsigned long) (xae->time_inclusive * 1000000), (xae->mem_used));
+#else
 		fprintf(fp, "\nsummary: %lu\n\n", (unsigned long) (xae->time_inclusive * 1000000));
+#endif
 	}
 	if (xae->call_list) {
 		xdebug_aggregate_entry **xae_call;
@@ -262,7 +304,11 @@ static int xdebug_print_aggr_entry(void *pDest, void *argument TSRMLS_DC)
 		while (zend_hash_get_current_data(xae->call_list, (void**)&xae_call) == SUCCESS) {
 			fprintf(fp, "cfn=%s\n", (*xae_call)->function);
 			fprintf(fp, "calls=%d 0 0\n", (*xae_call)->call_count);
+#if HAVE_PHP_MEMORY_USAGE
+			fprintf(fp, "%d %lu %ld\n", (*xae_call)->lineno, (unsigned long) ((*xae_call)->time_inclusive * 1000000), ((*xae_call)->mem_used));
+#else
 			fprintf(fp, "%d %lu\n", (*xae_call)->lineno, (unsigned long) ((*xae_call)->time_inclusive * 1000000));
+#endif
 			zend_hash_move_forward(xae->call_list);
 		}
 	}
xdebug_mem.patch (5,602 bytes)

atis

2011-10-06 18:55

reporter   ~0001835

With minor changes working on 2.1.2 version and KCacheGrind.

Original author "Benson, Geoff" as mentioned in link

atis

2011-10-06 20:26

reporter   ~0001836

Added pull request on github.

derick

2012-02-29 13:15

administrator   ~0001938

Even though the patch is correct, the results will not be. PHP's memory manager is quite unreliable for when it frees up memory. I don't quite know whether I want to add something that I know will confuse people...

atis

2012-02-29 17:25

reporter   ~0001942

This helped me to see most memory used, optimize, etc.

It actually doesn't matter for me to see correct numbers - when debugging memory usage all you need is allocations and percentage of total usage.

pounard

2015-12-03 15:19

reporter   ~0003282

Last edited: 2015-12-03 15:20

View 2 revisions

I do agree with atis, memory is important even if the numbers are not correct. That's a feature I've been waiting for a few years now, a profiler without memory information is only half-complete.

Issue History

Date Modified Username Field Change
2009-09-24 18:32 jacobweber New Issue
2009-09-24 18:32 jacobweber Operating System => N/A
2009-09-24 18:32 jacobweber PHP Version => 5.3.0
2009-09-24 18:32 jacobweber Xdebug Version => 2.0.4
2011-10-06 18:55 atis File Added: xdebug_mem.patch
2011-10-06 18:55 atis Note Added: 0001835
2011-10-06 20:26 atis Note Added: 0001836
2012-02-29 13:15 derick Note Added: 0001938
2012-02-29 17:25 atis Note Added: 0001942
2015-12-03 15:19 pounard Note Added: 0003282
2015-12-03 15:20 pounard Note Edited: 0003282 View Revisions
2016-12-11 15:58 derick Status new => confirmed
2016-12-11 15:58 derick Target Version => 2.6.0dev
2017-06-23 06:32 fitzs Operating System N/A =>
2017-11-18 15:00 derick Status confirmed => closed
2017-11-18 15:00 derick Assigned To => derick
2017-11-18 15:00 derick Resolution open => fixed
2017-11-18 15:00 derick Fixed in Version => 2.6.0dev
2017-12-02 15:57 derick Fixed in Version 2.6.0dev => 2.6.0alpha1
2017-12-02 18:34 derick Target Version 2.6.0dev => 2.6.0alpha1
2017-12-02 18:36 derick Target Version 2.6.0alpha1 => 2.6.0