53
53
/* Definitions of arguments for argp functions. */
54
54
static const struct argp_option options[] =
56
{ "output", 'o', N_("FILE"), 0, N_("Name output file") },
57
{ "string", 's', N_("STRING"), 0, N_("Title string used in output graphic") },
58
{ "time", 't', NULL, 0, N_("\
56
{ "output", 'o', N_ ("FILE"), 0, N_ ("Name output file") },
57
{ "string", 's', N_ ("STRING"), 0, N_ ("Title string used in output graphic") },
58
{ "time", 't', NULL, 0, N_ (" \
59
59
Generate output linear to time (default is linear to number of function calls)\
61
61
{ "total", 'T', NULL, 0,
62
N_("Also draw graph for total memory consumption") },
63
{ "x-size", 'x', N_("VALUE"), 0,
64
N_("Make output graphic VALUE pixels wide") },
65
{ "y-size", 'y', "VALUE", 0, N_("Make output graphic VALUE pixels high") },
62
N_ ("Also draw graph for total memory consumption") },
63
{ "x-size", 'x', N_ ("VALUE"), 0,
64
N_ ("Make output graphic VALUE pixels wide") },
65
{ "y-size", 'y', "VALUE", 0, N_ ("Make output graphic VALUE pixels high") },
66
66
{ NULL, 0, NULL, 0, NULL }
69
69
/* Short description of program. */
70
static const char doc[] = N_("Generate graphic from memory profiling data");
70
static const char doc[] = N_ ("Generate graphic from memory profiling data");
72
72
/* Strings for arguments in help texts. */
73
static const char args_doc[] = N_("DATAFILE [OUTFILE]");
73
static const char args_doc[] = N_ ("DATAFILE [OUTFILE]");
75
75
/* Prototype for option handler. */
76
76
static error_t parse_opt (int key, char *arg, struct argp_state *state);
294
294
gdImageString (im_out, gdFontSmall, 38, ysize - 14, (unsigned char *) "0",
296
296
snprintf (buf, sizeof (buf), heap_format, 0);
297
297
gdImageString (im_out, gdFontSmall, maxsize_heap < 1024 ? 32 : 26,
298
ysize - 26, (unsigned char *) buf, red);
298
ysize - 26, (unsigned char *) buf, red);
299
299
snprintf (buf, sizeof (buf), stack_format, 0);
300
300
gdImageString (im_out, gdFontSmall, xsize - 37, ysize - 26,
301
(unsigned char *) buf, green);
301
(unsigned char *) buf, green);
303
303
if (string != NULL)
304
304
gdImageString (im_out, gdFontLarge, (xsize - strlen (string) * 8) / 2,
305
2, (unsigned char *) string, green);
305
2, (unsigned char *) string, green);
307
307
gdImageStringUp (im_out, gdFontSmall, 1, ysize / 2 - 10,
308
(unsigned char *) "allocated", red);
308
(unsigned char *) "allocated", red);
309
309
gdImageStringUp (im_out, gdFontSmall, 11, ysize / 2 - 10,
310
(unsigned char *) "memory", red);
310
(unsigned char *) "memory", red);
312
312
gdImageStringUp (im_out, gdFontSmall, xsize - 39, ysize / 2 - 10,
313
(unsigned char *) "used", green);
313
(unsigned char *) "used", green);
314
314
gdImageStringUp (im_out, gdFontSmall, xsize - 27, ysize / 2 - 10,
315
(unsigned char *) "stack", green);
315
(unsigned char *) "stack", green);
317
317
snprintf (buf, sizeof (buf), heap_format, maxsize_heap / heap_scale);
318
318
gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6, 14,
319
(unsigned char *) buf, red);
319
(unsigned char *) buf, red);
320
320
snprintf (buf, sizeof (buf), stack_format, maxsize_stack / stack_scale);
321
321
gdImageString (im_out, gdFontSmall, xsize - 37, 14,
322
(unsigned char *) buf, green);
322
(unsigned char *) buf, green);
324
324
for (line = 1; line <= 3; ++line)
326
326
if (maxsize_heap > 0)
328
cnt = (((ysize - 40) * (maxsize_heap / 4 * line / heap_scale))
329
/ (maxsize_heap / heap_scale));
330
gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
331
ysize - 20 - cnt, red);
332
snprintf (buf, sizeof (buf), heap_format,
333
maxsize_heap / 4 * line / heap_scale);
334
gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
335
ysize - 26 - cnt, (unsigned char *) buf, red);
328
cnt = (((ysize - 40) * (maxsize_heap / 4 * line / heap_scale))
329
/ (maxsize_heap / heap_scale));
330
gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
331
ysize - 20 - cnt, red);
332
snprintf (buf, sizeof (buf), heap_format,
333
maxsize_heap / 4 * line / heap_scale);
334
gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
335
ysize - 26 - cnt, (unsigned char *) buf, red);
340
340
if (maxsize_stack > 0)
341
cnt2 = (((ysize - 40) * (maxsize_stack / 4 * line / stack_scale))
342
/ (maxsize_stack / stack_scale));
341
cnt2 = (((ysize - 40) * (maxsize_stack / 4 * line / stack_scale))
342
/ (maxsize_stack / stack_scale));
347
gdImageDashedLine (im_out, 40, ysize - 20 - cnt2, xsize - 40,
348
ysize - 20 - cnt2, green);
347
gdImageDashedLine (im_out, 40, ysize - 20 - cnt2, xsize - 40,
348
ysize - 20 - cnt2, green);
349
349
snprintf (buf, sizeof (buf), stack_format, maxsize_stack / 4 * line /
351
351
gdImageString (im_out, gdFontSmall, xsize - 37, ysize - 26 - cnt2,
352
(unsigned char *) buf, green);
352
(unsigned char *) buf, green);
355
355
snprintf (buf, sizeof (buf), "%llu", (unsigned long long) total);
356
356
gdImageString (im_out, gdFontSmall, xsize - 50, ysize - 14,
357
(unsigned char *) buf, blue);
357
(unsigned char *) buf, blue);
361
361
uint64_t previously = start_time;
363
363
gdImageString (im_out, gdFontSmall, 40 + (xsize - 32 * 6 - 80) / 2,
365
(unsigned char *) "# memory handling function calls",
365
(unsigned char *) "# memory handling function calls",
369
369
last_stack = last_heap = last_total = ysize - 20;
370
370
for (cnt = 1; cnt <= total; ++cnt)
376
read (fd, &entry, sizeof (entry));
378
now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
380
if ((((previously - start_time) * 100) / total_time) % 10 < 5)
381
gdImageFilledRectangle (im_out,
382
40 + ((cnt - 1) * (xsize - 80)) / total,
384
39 + (cnt * (xsize - 80)) / total,
388
if (also_total && maxsize_heap > 0)
392
new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
393
* (entry.heap + entry.stack))
395
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
397
40 + ((xsize - 80) * cnt) / total, new3,
402
if (maxsize_heap > 0)
404
new[0] = ((ysize - 20)
405
- ((((unsigned long long int) (ysize - 40))
406
* entry.heap) / maxsize_heap));
407
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
408
last_heap, 40 + ((xsize - 80) * cnt) / total,
413
if (maxsize_stack > 0)
415
new[1] = ((ysize - 20)
416
- ((((unsigned long long int) (ysize - 40))
417
* entry.stack) / maxsize_stack));
418
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
419
last_stack, 40 + ((xsize - 80) * cnt) / total,
376
read (fd, &entry, sizeof (entry));
378
now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
380
if ((((previously - start_time) * 100) / total_time) % 10 < 5)
381
gdImageFilledRectangle (im_out,
382
40 + ((cnt - 1) * (xsize - 80)) / total,
384
39 + (cnt * (xsize - 80)) / total,
388
if (also_total && maxsize_heap > 0)
392
new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
393
* (entry.heap + entry.stack))
395
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
397
40 + ((xsize - 80) * cnt) / total, new3,
402
if (maxsize_heap > 0)
404
new[0] = ((ysize - 20)
405
- ((((unsigned long long int) (ysize - 40))
406
* entry.heap) / maxsize_heap));
407
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
408
last_heap, 40 + ((xsize - 80) * cnt) / total,
413
if (maxsize_stack > 0)
415
new[1] = ((ysize - 20)
416
- ((((unsigned long long int) (ysize - 40))
417
* entry.stack) / maxsize_stack));
418
gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
419
last_stack, 40 + ((xsize - 80) * cnt) / total,
426
426
while (cnt < total)
428
gdImageLine (im_out, 40 + ((xsize - 80) * cnt) / total, ysize - 20,
429
40 + ((xsize - 80) * cnt) / total, ysize - 15, blue);
430
cnt += MAX (1, total / 20);
428
gdImageLine (im_out, 40 + ((xsize - 80) * cnt) / total, ysize - 20,
429
40 + ((xsize - 80) * cnt) / total, ysize - 15, blue);
430
cnt += MAX (1, total / 20);
432
432
gdImageLine (im_out, xsize - 40, ysize - 20, xsize - 40, ysize - 15,
438
438
size_t last_xpos = 40;
440
440
gdImageString (im_out, gdFontSmall, 40 + (xsize - 39 * 6 - 80) / 2,
442
(unsigned char *) " \
443
443
# memory handling function calls / time", blue);
445
445
for (cnt = 0; cnt < 20; cnt += 2)
446
gdImageFilledRectangle (im_out,
447
40 + (cnt * (xsize - 80)) / 20, ysize - 19,
448
39 + ((cnt + 1) * (xsize - 80)) / 20,
446
gdImageFilledRectangle (im_out,
447
40 + (cnt * (xsize - 80)) / 20, ysize - 19,
448
39 + ((cnt + 1) * (xsize - 80)) / 20,
451
451
last_stack = last_heap = last_total = ysize - 20;
452
452
for (cnt = 1; cnt <= total; ++cnt)
459
read (fd, &entry, sizeof (entry));
461
now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
462
xpos = 40 + ((xsize - 80) * (now - start_time)) / total_time;
464
if (cnt == next_tick)
466
gdImageLine (im_out, xpos, ysize - 20, xpos, ysize - 15, blue);
467
next_tick += MAX (1, total / 20);
470
if (also_total && maxsize_heap > 0)
474
new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
475
* (entry.heap + entry.stack))
477
gdImageLine (im_out, last_xpos, last_total, xpos, new3, black);
481
if (maxsize_heap > 0)
483
new[0] = ((ysize - 20)
484
- ((((unsigned long long int) (ysize - 40))
485
* entry.heap) / maxsize_heap));
486
gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red);
490
if (maxsize_stack > 0)
492
new[1] = ((ysize - 20)
493
- ((((unsigned long long int) (ysize - 40))
494
* entry.stack) / maxsize_stack));
495
gdImageLine (im_out, last_xpos, last_stack, xpos, new[1],
459
read (fd, &entry, sizeof (entry));
461
now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
462
xpos = 40 + ((xsize - 80) * (now - start_time)) / total_time;
464
if (cnt == next_tick)
466
gdImageLine (im_out, xpos, ysize - 20, xpos, ysize - 15, blue);
467
next_tick += MAX (1, total / 20);
470
if (also_total && maxsize_heap > 0)
474
new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
475
* (entry.heap + entry.stack))
477
gdImageLine (im_out, last_xpos, last_total, xpos, new3, black);
481
if (maxsize_heap > 0)
483
new[0] = ((ysize - 20)
484
- ((((unsigned long long int) (ysize - 40))
485
* entry.heap) / maxsize_heap));
486
gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red);
490
if (maxsize_stack > 0)
492
new[1] = ((ysize - 20)
493
- ((((unsigned long long int) (ysize - 40))
494
* entry.stack) / maxsize_stack));
495
gdImageLine (im_out, last_xpos, last_stack, xpos, new[1],
504
504
/* Write out the result. */