diff -crN ltrace-0.5.3.orig/handle_event.c ltrace-0.5.3/handle_event.c
*** ltrace-0.5.3.orig/handle_event.c	2009-07-26 00:13:02.000000000 +0900
--- ltrace-0.5.3/handle_event.c	2013-08-26 16:04:51.400533658 +0900
***************
*** 6,12 ****
--- 6,15 ----
  #include <stdlib.h>
  #include <signal.h>
  #include <assert.h>
+ #include <unistd.h>
  #include <sys/time.h>
+ #include <sys/ptrace.h>
+ #include <errno.h>
  
  #include "common.h"
  
***************
*** 213,218 ****
--- 216,238 ----
  		} else {
  			p->state = STATE_IGNORED;
  		}
+ 
+ 		/* MP-ltrace */
+ 		if (options.mp) {
+ 			disable_all_breakpoints(p);
+ 			errno = 0;
+ 			ptrace(PTRACE_DETACH, p->pid, NULL, NULL);
+ 			if (fork() == 0) {
+ 				if (output_file[0] != '\0') {
+ 					fclose(options.output);
+ 					char outfile[256];
+ 					sprintf(outfile, "%s.%d", output_file, p->pid);
+ 					options.output = fopen(outfile, "w");
+ 				}
+ 				open_pid(p->pid);
+ 			}
+ 		}
+ 
  		continue_process(p->pid);
  		p->next = list_of_processes;
  		list_of_processes = p;
***************
*** 244,249 ****
--- 264,286 ----
  		} else {
  			proc->state = STATE_IGNORED;
  		}
+ 
+ 		/* MP-ltrace */
+ 		if (options.mp) {
+ 			disable_all_breakpoints(proc);
+ 			errno = 0;
+ 			ptrace(PTRACE_DETACH, proc->pid, NULL, NULL);
+ 			if (fork() == 0) {
+ 				if (output_file[0] != '\0') {
+ 					fclose(options.output);
+ 					char outfile[256];
+ 					sprintf(outfile, "%s.%d", output_file, proc->pid);
+ 					options.output = fopen(outfile, "w");
+ 				}
+ 				open_pid(proc->pid);
+ 			}
+ 		}
+ 
  		continue_process(proc->pid);
  	}
  }
diff -crN ltrace-0.5.3.orig/options.c ltrace-0.5.3/options.c
*** ltrace-0.5.3.orig/options.c	2009-07-26 00:13:02.000000000 +0900
--- ltrace-0.5.3/options.c	2013-08-26 16:13:28.760541471 +0900
***************
*** 34,41 ****
--- 34,45 ----
  	.arraylen = DEFAULT_ARRAYLEN, /* maximum # array elements to print */
  	.strlen = DEFAULT_STRLEN,     /* maximum # of bytes printed in strings */
  	.follow = 0,                  /* trace child processes */
+ 	.mp = 0,                      /* MP-ltrace */
+ 	.output_max = 0,              /* max size of output file */
  };
  
+ char output_file[256] = "";
+ 
  char *library[MAX_LIBRARIES];
  int library_num = 0;
  static char *progname;		/* Program name (`ltrace') */
***************
*** 88,93 ****
--- 92,99 ----
  		"  -i                  print instruction pointer at time of library call.\n"
  		"  -l, --library=FILE  print library calls from this library only.\n"
  		"  -L                  do NOT display library calls.\n"
+ 		"  -m size             specify the maximum size (KB) of output file.\n"
+ 		"  -M                  fork ltrace for multi processes. (-f is assumed)\n"
  		"  -n, --indent=NR     indent output by NR spaces for each call level nesting.\n"
  		"  -o, --output=FILE   write the trace output to that file.\n"
  		"  -p PID              attach to the process with the process ID pid.\n"
***************
*** 200,210 ****
  			{"version", 0, 0, 'V'},
  			{0, 0, 0, 0}
  		};
! 		c = getopt_long(argc, argv, "+cfhiLrStTV"
  # ifdef USE_DEMANGLE
  				"C"
  # endif
! 				"a:A:D:e:F:l:n:o:p:s:u:x:X:", long_options,
  				&option_index);
  		if (c == -1) {
  			break;
--- 206,216 ----
  			{"version", 0, 0, 'V'},
  			{0, 0, 0, 0}
  		};
! 		c = getopt_long(argc, argv, "+cfhiLMrStTV"
  # ifdef USE_DEMANGLE
  				"C"
  # endif
! 				"a:A:D:e:F:l:m:n:o:p:s:u:x:X:", long_options,
  				&option_index);
  		if (c == -1) {
  			break;
***************
*** 301,306 ****
--- 307,326 ----
  		case 'L':
  			options.libcalls = 0;
  			break;
+ 		case 'm':
+ 			options.output_max = atol(optarg);
+ 			if (options.output_max <= 0) {
+ 				fprintf(stderr,
+ 					"output file max size must be more than 0 (KB)\n");
+ 				exit(1);
+ 			}
+ 			options.output_max *= 1000L; /* KB */
+ 			options.output_max -= 100L; /* 100 bytes to spare */
+ 			break;
+ 		case 'M':
+ 			options.mp = 1;
+ 			options.follow = 1; /* -f is assumed */
+ 			break;
  		case 'n':
  			options.indent = atoi(optarg);
  			break;
***************
*** 312,317 ****
--- 332,338 ----
  					optarg, strerror(errno));
  				exit(1);
  			}
+ 			strcpy(output_file, optarg);
  			setvbuf(options.output, (char *)NULL, _IOLBF, 0);
  			fcntl(fileno(options.output), F_SETFD, FD_CLOEXEC);
  			break;
diff -crN ltrace-0.5.3.orig/options.h ltrace-0.5.3/options.h
*** ltrace-0.5.3.orig/options.h	2009-07-26 00:13:02.000000000 +0900
--- ltrace-0.5.3/options.h	2013-08-26 15:52:27.224523963 +0900
***************
*** 14,22 ****
--- 14,26 ----
  	int arraylen; /* default maximum # of array elements printed */
  	int strlen;   /* default maximum # of bytes printed in strings */
  	int follow;   /* trace child processes */
+ 	int mp;       /* MP-ltrace */
+ 	long output_max;   /* max size of output file */
  };
  extern struct options_t options;
  
+ extern char output_file[256];
+ 
  extern int opt_i;		/* instruction pointer */
  extern int opt_r;		/* print relative timestamp */
  extern int opt_t;		/* print absolute timestamp */
diff -crN ltrace-0.5.3.orig/output.c ltrace-0.5.3/output.c
*** ltrace-0.5.3.orig/output.c	2009-07-26 00:13:02.000000000 +0900
--- ltrace-0.5.3/output.c	2013-08-26 14:49:46.696475607 +0900
***************
*** 26,31 ****
--- 26,42 ----
  }
  
  static void
+ return_beginning() {
+ 	if (options.output_max == 0) {  // no limit
+ 		return;
+ 	}
+ 	long loc = ftell(options.output);
+ 	if (loc >= options.output_max) {
+ 		fseek(options.output, 0, SEEK_SET);
+ 	}
+ }
+ 
+ static void
  begin_of_line(enum tof type, Process *proc) {
  	current_column = 0;
  	if (!proc) {
***************
*** 128,135 ****
--- 139,148 ----
  	if (current_proc) {
  		if (current_proc->callstack[current_depth].return_addr) {
  			fprintf(options.output, " <unfinished ...>\n");
+ 			return_beginning();
  		} else {
  			fprintf(options.output, " <no return ...>\n");
+ 			return_beginning();
  		}
  	}
  	current_proc = 0;
***************
*** 141,146 ****
--- 154,160 ----
  	va_start(args, fmt);
  	vfprintf(options.output, fmt, args);
  	fprintf(options.output, "\n");
+ 	return_beginning();
  	va_end(args);
  	current_column = 0;
  }
***************
*** 164,169 ****
--- 178,184 ----
  	}
  	if (current_proc) {
  		fprintf(options.output, " <unfinished ...>\n");
+ 		return_beginning();
  		current_proc = 0;
  		current_column = 0;
  	}
***************
*** 252,257 ****
--- 267,273 ----
  	if (current_proc && (current_proc != proc ||
  			    current_depth != proc->callstack_depth)) {
  		fprintf(options.output, " <unfinished ...>\n");
+ 		return_beginning();
  		current_proc = 0;
  	}
  	if (current_proc != proc) {
***************
*** 298,303 ****
--- 314,320 ----
  			(int)current_time_spent.tv_usec);
  	}
  	fprintf(options.output, "\n");
+ 	return_beginning();
  	current_proc = 0;
  	current_column = 0;
  }
diff -crN ltrace-0.5.3.orig/proc.c ltrace-0.5.3/proc.c
*** ltrace-0.5.3.orig/proc.c	2009-07-26 00:13:02.000000000 +0900
--- ltrace-0.5.3/proc.c	2013-08-26 14:49:46.696475607 +0900
***************
*** 46,51 ****
--- 46,52 ----
  	}
  
  	proc = open_program(filename, pid);
+         trace_set_options(proc, pid);
  	continue_process(pid);
  	proc->breakpoints_enabled = 1;
  }
