From: Josef Weidendorfer Date: Fri, 31 Mar 2006 19:34:51 +0000 (+0000) Subject: Simple regression test for callgrind: X-Git-Tag: svn/VALGRIND_3_2_0~152 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a0cfdcaa35bf75b48531cea8c489e8c20bd1a34;p=thirdparty%2Fvalgrind.git Simple regression test for callgrind: run a custom client request. By doing this, I found out that callgrind.h still defined client requests for VG 2 :-( Obviously, nobody was using them. This is fixed, and other small things to make the test run, too. Notice for myself: regression tests are needed. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5807 --- diff --git a/callgrind/callgrind.h b/callgrind/callgrind.h index b8a8e049e6..bac93926aa 100644 --- a/callgrind/callgrind.h +++ b/callgrind/callgrind.h @@ -13,7 +13,7 @@ This file is part of callgrind, a valgrind skin for cache simulation and call tree tracing. - Copyright (C) 2003,2004 Josef Weidendorfer. All rights reserved. + Copyright (C) 2003-2006 Josef Weidendorfer. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -61,6 +61,16 @@ #include "valgrind.h" +/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! + This enum comprises an ABI exported by Valgrind to programs + which use client requests. DO NOT CHANGE THE ORDER OF THESE + ENTRIES, NOR DELETE ANY -- add new ones at the end. + + The identification ('C','T') for Callgrind has historical + reasons: it was called "Calltree" before. Besides, ('C','G') would + clash with cachegrind. + */ + typedef enum { VG_USERREQ__DUMP_STATS = VG_USERREQ_TOOL_BASE('C','T'), @@ -69,63 +79,69 @@ typedef VG_USERREQ__DUMP_STATS_AT, VG_USERREQ__START_INSTRUMENTATION, VG_USERREQ__STOP_INSTRUMENTATION - } Vg_CalltreeClientRequest; - -/* Dump current state of cost centers. - This will also atomically zero the cost centers */ -#define CALLGRIND_DUMP_STATS() \ - do { \ - unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__DUMP_STATS, \ - 0, 0, 0, 0); \ - (void)0; \ - } while(0) - -/* Dump current state of cost centers. - This will also atomically zero the cost centers */ -#define CALLGRIND_DUMP_STATS_AT(pos_str) \ - do { \ - unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__DUMP_STATS_AT, \ - pos_str, 0, 0, 0); \ - (void)0; \ - } while(0) + } Vg_CallgrindClientRequest; + +/* Dump current state of cost centers, and zero them afterwards */ +#define CALLGRIND_DUMP_STATS \ + {unsigned int _qzz_res; \ + VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VG_USERREQ__DUMP_STATS, \ + 0, 0, 0, 0, 0); \ + } + +/* Dump current state of cost centers, and zero them afterwards. + The argument is appended to a string stating the reason which triggered + the dump. This string is written as a description field into the + profile data dump. */ +#define CALLGRIND_DUMP_STATS_AT(pos_str) \ + {unsigned int _qzz_res; \ + VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VG_USERREQ__DUMP_STATS_AT, \ + pos_str, 0, 0, 0, 0); \ + } /* Zero cost centers */ -#define CALLGRIND_ZERO_STATS() \ - do { \ - unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__ZERO_STATS, \ - 0, 0, 0, 0); \ - (void)0; \ - } while(0) - -/* Toggle collection state, - * i.e. if events happening are collected into cost centers */ -#define CALLGRIND_TOGGLE_COLLECT() \ - do { \ - unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__TOGGLE_COLLECT, \ - 0, 0, 0, 0); \ - (void)0; \ - } while(0) - -/* Start instrumentation if not already on */ -#define CALLGRIND_START_INSTRUMENTATION() \ - do { \ - unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__START_INSTRUMENTATION,\ - 0, 0, 0, 0); \ - (void)0; \ - } while(0) - -/* Stop instrumentation if not already off */ -#define CALLGRIND_STOP_INSTRUMENTATION() \ - do { \ - unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__STOP_INSTRUMENTATION,\ - 0, 0, 0, 0); \ - (void)0; \ - } while(0) +#define CALLGRIND_ZERO_STATS \ + {unsigned int _qzz_res; \ + VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VG_USERREQ__ZERO_STATS, \ + 0, 0, 0, 0, 0); \ + } + +/* Toggles collection state. + The collection state specifies whether the happening of events + should be noted or if they are to be ignored. Events are noted + by increment of counters in a cost center */ +#define CALLGRIND_TOGGLE_COLLECT \ + {unsigned int _qzz_res; \ + VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VG_USERREQ__TOGGLE_COLLECT, \ + 0, 0, 0, 0, 0); \ + } + +/* Start full callgrind instrumentation if not already switched on. + When cache simulation is done, it will flush the simulated cache; + this will lead to an artifical cache warmup phase afterwards with + cache misses which would not have happened in reality. */ +#define CALLGRIND_START_INSTRUMENTATION \ + {unsigned int _qzz_res; \ + VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VG_USERREQ__START_INSTRUMENTATION, \ + 0, 0, 0, 0, 0); \ + } + +/* Stop full callgrind instrumentation if not already switched off. + This flushes Valgrinds translation cache, and does no additional + instrumentation afterwards, which effectivly will run at the same + speed as the "none" tool (ie. at minimal slowdown). + Use this to bypass Callgrind aggregation for uninteresting code parts. + To start Callgrind in this mode to ignore the setup phase, use + the option "--instr-atstart=no". */ +#define CALLGRIND_STOP_INSTRUMENTATION \ + {unsigned int _qzz_res; \ + VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VG_USERREQ__STOP_INSTRUMENTATION, \ + 0, 0, 0, 0, 0); \ + } #endif /* __CALLGRIND_H */ diff --git a/callgrind/main.c b/callgrind/main.c index dd19b3b338..bdd406f8d1 100644 --- a/callgrind/main.c +++ b/callgrind/main.c @@ -801,7 +801,7 @@ Bool CLG_(handle_client_request)(ThreadId tid, UWord *args, UWord *ret) case VG_USERREQ__DUMP_STATS_AT: { Char buf[512]; - VG_(sprintf)(buf,"Client Request: %d", args[1]); + VG_(sprintf)(buf,"Client Request: %s", args[1]); CLG_(dump_profile)(buf, True); *ret = 0; /* meaningless */ } @@ -1042,20 +1042,23 @@ void CLG_(post_clo_init)(void) CLG_(instrument_state) = CLG_(clo).instrument_atstart; - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, "For interactive control, run 'callgrind_control -h'."); + if (VG_(clo_verbosity > 0)) { + VG_(message)(Vg_UserMsg, ""); + VG_(message)(Vg_UserMsg, + "For interactive control, run 'callgrind_control -h'."); + } } static void CLG_(pre_clo_init)(void) { VG_(details_name) ("Callgrind"); - VG_(details_version) (VERSION); + VG_(details_version) (NULL); VG_(details_description) ("a call-graph generating cache profiler"); VG_(details_copyright_author)("Copyright (C) 2002-2006, and GNU GPL'd, " - "by J.Weidendorfer et al."); + "by Josef Weidendorfer et al."); VG_(details_bug_reports_to) ("Josef.Weidendorfer@gmx.de"); - VG_(details_avg_translation_sizeB) ( 155 ); + VG_(details_avg_translation_sizeB) ( 245 ); VG_(basic_tool_funcs) (CLG_(post_clo_init), CLG_(instrument), diff --git a/callgrind/tests/Makefile.am b/callgrind/tests/Makefile.am index bc7d201f4f..ce7337c0eb 100644 --- a/callgrind/tests/Makefile.am +++ b/callgrind/tests/Makefile.am @@ -4,11 +4,13 @@ include $(top_srcdir)/Makefile.flags.am SUBDIRS = . DIST_SUBDIRS = . -noinst_SCRIPTS = +noinst_SCRIPTS = filter_stderr -EXTRA_DIST = +EXTRA_DIST = clreq.vgtest clreq.stderr.exp -check_PROGRAMS = +check_PROGRAMS = clreq AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g $(AM_FLAG_M3264_PRI) + + diff --git a/callgrind/tests/clreq.c b/callgrind/tests/clreq.c new file mode 100644 index 0000000000..7a290c76fe --- /dev/null +++ b/callgrind/tests/clreq.c @@ -0,0 +1,13 @@ + +// Similar to Cachegrind, check if instrumentation works in the presence +// of a client request. Uses a Callgrind request to check this. + +#include "../callgrind.h" + +int main(void) +{ + CALLGRIND_ZERO_STATS; + + return RUNNING_ON_VALGRIND; +} + diff --git a/callgrind/tests/clreq.stderr.exp b/callgrind/tests/clreq.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/callgrind/tests/clreq.vgtest b/callgrind/tests/clreq.vgtest new file mode 100644 index 0000000000..2ec453a9d5 --- /dev/null +++ b/callgrind/tests/clreq.vgtest @@ -0,0 +1,3 @@ +prog: clreq +vgopts: -q +cleanup: rm callgrind.out.* diff --git a/callgrind/tests/filter_stderr b/callgrind/tests/filter_stderr new file mode 100755 index 0000000000..6e6000c1c4 --- /dev/null +++ b/callgrind/tests/filter_stderr @@ -0,0 +1,20 @@ +#! /bin/sh + +dir=`dirname $0` + +$dir/../../tests/filter_stderr_basic | + +# Remove "Callgrind, ..." line and the following copyright line. +sed "/^Callgrind, a call-graph generating cache profiler./ , /./ d" | + +# Remove numbers from I/D/L2 "refs:" lines +sed "s/\(\(I\|D\|L2\) *refs:\)[ 0-9,()+rdw]*$/\1/" | + +# Remove numbers from I1/D1/L2/L2i/L2d "misses:" and "miss rates:" lines +sed "s/\(\(I1\|D1\|L2\|L2i\|L2d\) *\(misses\|miss rate\):\)[ 0-9,()+rdw%\.]*$/\1/" | + +# Remove CPUID warnings lines for P4s and other machines +sed "/warning: Pentium 4 with 12 KB micro-op instruction trace cache/d" | +sed "/Simulating a 16 KB I-cache with 32 B lines/d" | +sed "/warning: L3 cache detected but ignored/d" | +sed "/Warning: Cannot auto-detect cache config on PPC.., using one or more defaults/d"