perf tools: Fix snprint warnings for gcc 8
Jiri Olsa
reviewerPATCH 1/2 perf tools: Fix snprint warnings for gcc 8
From: root <[email protected]>
With gcc 8 we get new set of snprintf warnings that brakes the compilation, one example:
tests/mem.c: In function ‘check’:
tests/mem.c:19:48: error: ‘%s’ directive output may be truncated writing \
up to 99 bytes into a region of size 89 [-Werror=format-truncation=]
snprintf(failure, sizeof failure, "unexpected %s", out);
The gcc docs says:
To avoid the warning either use a bigger buffer or handle the function's return value which indicates whether or not its output has been truncated.
Given that all these warnings are harmless, because the code either properly fails due to uncomplete file path or we don't care for truncated output at all, I'm changing all those snprintf calls to scnprintf calls, which actually 'checks' for the snprint return value so the gcc stays silent.
--- tools/perf/builtin-script.c | 22 +++++++++++----------- tools/perf/tests/attr.c | 4 ++-- tools/perf/tests/mem.c | 2 +- tools/perf/tests/pmu.c | 2 +- tools/perf/util/cgroup.c | 2 +- tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/pmu.c | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-)
tools/perf/builtin-script.c +11 -11
@@ -2674,8 +2674,8 @@ static int list_available_scripts(const struct option *opt __maybe_unused, }for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, + lang_dirent->d_name); lang_dir =opendir (lang_path);if (!lang_dir)continue ;
@@ -2684,8 +2684,8 @@ static int list_available_scripts(const struct option *opt __maybe_unused, script_root =get_script_root (script_dirent,REPORT_SUFFIX );if (script_root) { desc =script_desc__findnew (script_root); -snprintf (script_path,MAXPATHLEN ,"%s/%s" , - lang_path, script_dirent->d_name); +scnprintf (script_path,MAXPATHLEN ,"%s/%s" , + lang_path, script_dirent->d_name);read_script_info (desc, script_path);free (script_root); }
@@ -2721,7 +2721,7 @@ static int check_ev_match(char *dir_name, char *scriptname,int match, len;FILE *fp; -sprintf (filename,"%s/bin/%s-record" , dir_name, scriptname); +scnprintf (filename,MAXPATHLEN ,"%s/bin/%s-record" , dir_name, scriptname); fp =fopen (filename,"r" );if (!fp)
@@ -2799,8 +2799,8 @@ int find_scripts(char **scripts_array, char **scripts_path_array) }for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s" , scripts_path, + lang_dirent->d_name);#ifdef NO_LIBPERL if (strstr (lang_path,"perl" ))continue ;
@@ -2855,8 +2855,8 @@ static char *get_script_path(const char *script_root, const char *suffix)return NULL ;for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, + lang_dirent->d_name); lang_dir =opendir (lang_path);if (!lang_dir)continue ;
@@ -2867,8 +2867,8 @@ static char *get_script_path(const char *script_root, const char *suffix)free (__script_root);closedir (lang_dir);closedir (scripts_dir); -snprintf (script_path,MAXPATHLEN ,"%s/%s" , - lang_path, script_dirent->d_name); +scnprintf (script_path,MAXPATHLEN ,"%s/%s" , + lang_path, script_dirent->d_name);return strdup (script_path); }free (__script_root);
tools/perf/tests/attr.c +2 -2
@@ -170,8 +170,8 @@ static int run_dir(const char *d, const char *perf)if (verbose >0 ) vcnt++; -snprintf (cmd,3 *PATH_MAX ,PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s" , - d, d, perf, vcnt, v); +scnprintf (cmd,3 *PATH_MAX ,PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s" , + d, d, perf, vcnt, v);return system (cmd) ?TEST_FAIL :TEST_OK ; }
tools/perf/tests/mem.c +1 -1
@@ -16,7 +16,7 @@ static int check(union perf_mem_data_src data_src, n =perf_mem__snp_scnprintf (out,sizeof out, &mi); n +=perf_mem__lvl_scnprintf (out + n,sizeof out - n, &mi); -snprintf (failure,sizeof failure,"unexpected %s" , out); +scnprintf (failure,sizeof failure,"unexpected %s" , out);TEST_ASSERT_VAL (failure, !strcmp (string, out));return 0 ; }
tools/perf/tests/pmu.c +1 -1
@@ -98,7 +98,7 @@ static char *test_format_dir_get(void)struct test_format *format = &test_formats[i];FILE *file; -snprintf (name,PATH_MAX ,"%s/%s" , dir, format->name); +scnprintf (name,PATH_MAX ,"%s/%s" , dir, format->name); file =fopen (name,"w" );if (!file)
tools/perf/util/cgroup.c +1 -1
@@ -81,7 +81,7 @@ static int open_cgroup(const char *name)if (cgroupfs_find_mountpoint (mnt,PATH_MAX +1 ))return -1 ; -snprintf (path,PATH_MAX ,"%s/%s" , mnt, name); +scnprintf (path,PATH_MAX ,"%s/%s" , mnt, name); fd =open (path,O_RDONLY );if (fd ==-1 )
tools/perf/util/parse-events.c +2 -2
@@ -206,8 +206,8 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)for_each_event (sys_dirent, evt_dir, evt_dirent) { -snprintf (evt_path,MAXPATHLEN ,"%s/%s/id" , dir_path, - evt_dirent->d_name); +scnprintf (evt_path,MAXPATHLEN ,"%s/%s/id" , dir_path, + evt_dirent->d_name); fd =open (evt_path,O_RDONLY );if (fd <0 )continue ;
tools/perf/util/pmu.c +1 -1
@@ -351,7 +351,7 @@ static int pmu_aliases_parse(char *dir, struct list_head *head)if (pmu_alias_info_file (name))continue ; -snprintf (path,PATH_MAX ,"%s/%s" , dir, name); +scnprintf (path,PATH_MAX ,"%s/%s" , dir, name); file =fopen (path,"r" );if (!file) {
Signature · 1 line
2.13.6
Jiri Olsa
reviewerPATCH 2/2 perf tools: Fix python extension build for gcc 8
From: root <[email protected]>
The gcc 8 won't compile python extension code with following errors (one example):
python.c:830:15: error: cast between incompatible function types from \
‘PyObject * (*)(struct pyrf_evsel *, PyObject *, PyObject *)’ \
uct _object * (*)(struct pyrf_evsel *, struct _object *, struct _object *)’} to \
‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _objeuct \
_object *)’} [-Werror=cast-function-type]
.ml_meth = (PyCFunction)pyrf_evsel__open,The problem with PyMethodDef::ml_meth callback is that its type is determined based on PyMethodDef::ml_flags value, which we set as METH_VARARGS | METH_KEYWORDS.
That indicates that the callback is expecting extra PyObject* arg, and is actually PyCFunctionWithKeywords type, but the base PyMethodDef::ml_meth type stays PyCFunction.
Previous gccs did not find this, gcc8 now does. Fixing this by silencing this warning for python.c build.
--- tools/perf/util/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/setup.py +1 -1
@@ -27,7 +27,7 @@ class install_lib(_install_lib): cflags = getenv('CFLAGS', '').split() # switch off several checks (need to be at the end of cflags list) -cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ] +cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-cast-function-type' ] src_perf = getenv('srctree') + '/tools/perf' build_lib = getenv('PYTHON_EXTBUILD_LIB')
Signature · 1 line
2.13.6
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Fix python extension build for gcc 8
perf tools: Fix python extension build for gcc 8
Commit-ID: b7a313d84e853049062011d78cb04b6decd12f5c Gitweb: https://git.kernel.org/tip/b7a313d84e853049062011d78cb04b6decd12f5c Author: Jiri Olsa <[email protected]> AuthorDate: Mon, 19 Mar 2018 09:29:02 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Mar 2018 13:39:46 -0300
perf tools: Fix python extension build for gcc 8
The gcc 8 compiler won't compile the python extension code with the following errors (one example):
python.c:830:15: error: cast between incompatible function types from \
‘PyObject * (*)(struct pyrf_evsel *, PyObject *, PyObject *)’ \
uct _object * (*)(struct pyrf_evsel *, struct _object *, struct _object *)’} to \
‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _objeuct \
_object *)’} [-Werror=cast-function-type]
.ml_meth = (PyCFunction)pyrf_evsel__open,The problem with the PyMethodDef::ml_meth callback is that its type is determined based on the PyMethodDef::ml_flags value, which we set as METH_VARARGS | METH_KEYWORDS.
That indicates that the callback is expecting an extra PyObject* arg, and is actually PyCFunctionWithKeywords type, but the base PyMethodDef::ml_meth type stays PyCFunction.
Previous gccs did not find this, gcc8 now does. Fixing this by silencing this warning for python.c build.
Commiter notes:
Do not do that for CC=clang, as it breaks the build in some clang versions, like the ones in fedora up to fedora27:
fedora:25:error: unknown warning option '-Wno-cast-function-type'; did you mean '-Wno-bad-function-cast'? [-Werror,-Wunknown-warning-option] fedora:26:error: unknown warning option '-Wno-cast-function-type'; did you mean '-Wno-bad-function-cast'? [-Werror,-Wunknown-warning-option] fedora:27:error: unknown warning option '-Wno-cast-function-type'; did you mean '-Wno-bad-function-cast'? [-Werror,-Wunknown-warning-option] #
those have:
clang version 3.9.1 (tags/RELEASE_391/final)
The one in rawhide accepts that:
clang version 6.0.0 (tags/RELEASE_600/final)
--- tools/perf/util/setup.py | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/setup.py +2 -0
@@ -28,6 +28,8 @@ class install_lib(_install_lib): cflags = getenv('CFLAGS', '').split() # switch off several checks (need to be at the end of cflags list) cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ] +if cc != "clang": + cflags += ['-Wno-cast-function-type' ] src_perf = getenv('srctree') + '/tools/perf' build_lib = getenv('PYTHON_EXTBUILD_LIB')
tip-bot for Jiri Olsa
merge botperf tools: Fix snprint warnings for gcc 8
Commit-ID: 77f18153c080855e1c3fb520ca31a4e61530121d Gitweb: https://git.kernel.org/tip/77f18153c080855e1c3fb520ca31a4e61530121d Author: Jiri Olsa <[email protected]> AuthorDate: Mon, 19 Mar 2018 09:29:01 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Mar 2018 10:00:43 -0300
perf tools: Fix snprint warnings for gcc 8
With gcc 8 we get new set of snprintf() warnings that breaks the compilation, one example:
tests/mem.c: In function ‘check’:
tests/mem.c:19:48: error: ‘%s’ directive output may be truncated writing \
up to 99 bytes into a region of size 89 [-Werror=format-truncation=]
snprintf(failure, sizeof failure, "unexpected %s", out);
The gcc docs says:
To avoid the warning either use a bigger buffer or handle the function's return value which indicates whether or not its output has been truncated.
Given that all these warnings are harmless, because the code either properly fails due to uncomplete file path or we don't care for truncated output at all, I'm changing all those snprintf() calls to scnprintf(), which actually 'checks' for the snprint return value so the gcc stays silent.
--- tools/perf/builtin-script.c | 22 +++++++++++----------- tools/perf/tests/attr.c | 4 ++-- tools/perf/tests/mem.c | 2 +- tools/perf/tests/pmu.c | 2 +- tools/perf/util/cgroup.c | 2 +- tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/pmu.c | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-)
tools/perf/builtin-script.c +11 -11
@@ -2674,8 +2674,8 @@ static int list_available_scripts(const struct option *opt __maybe_unused, }for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, + lang_dirent->d_name); lang_dir =opendir (lang_path);if (!lang_dir)continue ;
@@ -2684,8 +2684,8 @@ static int list_available_scripts(const struct option *opt __maybe_unused, script_root =get_script_root (script_dirent,REPORT_SUFFIX );if (script_root) { desc =script_desc__findnew (script_root); -snprintf (script_path,MAXPATHLEN ,"%s/%s" , - lang_path, script_dirent->d_name); +scnprintf (script_path,MAXPATHLEN ,"%s/%s" , + lang_path, script_dirent->d_name);read_script_info (desc, script_path);free (script_root); }
@@ -2721,7 +2721,7 @@ static int check_ev_match(char *dir_name, char *scriptname,int match, len;FILE *fp; -sprintf (filename,"%s/bin/%s-record" , dir_name, scriptname); +scnprintf (filename,MAXPATHLEN ,"%s/bin/%s-record" , dir_name, scriptname); fp =fopen (filename,"r" );if (!fp)
@@ -2799,8 +2799,8 @@ int find_scripts(char **scripts_array, char **scripts_path_array) }for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s" , scripts_path, + lang_dirent->d_name);#ifdef NO_LIBPERL if (strstr (lang_path,"perl" ))continue ;
@@ -2855,8 +2855,8 @@ static char *get_script_path(const char *script_root, const char *suffix)return NULL ;for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, + lang_dirent->d_name); lang_dir =opendir (lang_path);if (!lang_dir)continue ;
@@ -2867,8 +2867,8 @@ static char *get_script_path(const char *script_root, const char *suffix)free (__script_root);closedir (lang_dir);closedir (scripts_dir); -snprintf (script_path,MAXPATHLEN ,"%s/%s" , - lang_path, script_dirent->d_name); +scnprintf (script_path,MAXPATHLEN ,"%s/%s" , + lang_path, script_dirent->d_name);return strdup (script_path); }free (__script_root);
tools/perf/tests/attr.c +2 -2
@@ -170,8 +170,8 @@ static int run_dir(const char *d, const char *perf)if (verbose >0 ) vcnt++; -snprintf (cmd,3 *PATH_MAX ,PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s" , - d, d, perf, vcnt, v); +scnprintf (cmd,3 *PATH_MAX ,PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s" , + d, d, perf, vcnt, v);return system (cmd) ?TEST_FAIL :TEST_OK ; }
tools/perf/tests/mem.c +1 -1
@@ -16,7 +16,7 @@ static int check(union perf_mem_data_src data_src, n =perf_mem__snp_scnprintf (out,sizeof out, &mi); n +=perf_mem__lvl_scnprintf (out + n,sizeof out - n, &mi); -snprintf (failure,sizeof failure,"unexpected %s" , out); +scnprintf (failure,sizeof failure,"unexpected %s" , out);TEST_ASSERT_VAL (failure, !strcmp (string, out));return 0 ; }
tools/perf/tests/pmu.c +1 -1
@@ -98,7 +98,7 @@ static char *test_format_dir_get(void)struct test_format *format = &test_formats[i];FILE *file; -snprintf (name,PATH_MAX ,"%s/%s" , dir, format->name); +scnprintf (name,PATH_MAX ,"%s/%s" , dir, format->name); file =fopen (name,"w" );if (!file)
tools/perf/util/cgroup.c +1 -1
@@ -81,7 +81,7 @@ static int open_cgroup(const char *name)if (cgroupfs_find_mountpoint (mnt,PATH_MAX +1 ))return -1 ; -snprintf (path,PATH_MAX ,"%s/%s" , mnt, name); +scnprintf (path,PATH_MAX ,"%s/%s" , mnt, name); fd =open (path,O_RDONLY );if (fd ==-1 )
tools/perf/util/parse-events.c +2 -2
@@ -206,8 +206,8 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)for_each_event (sys_dirent, evt_dir, evt_dirent) { -snprintf (evt_path,MAXPATHLEN ,"%s/%s/id" , dir_path, - evt_dirent->d_name); +scnprintf (evt_path,MAXPATHLEN ,"%s/%s/id" , dir_path, + evt_dirent->d_name); fd =open (evt_path,O_RDONLY );if (fd <0 )continue ;
tools/perf/util/pmu.c +1 -1
@@ -351,7 +351,7 @@ static int pmu_aliases_parse(char *dir, struct list_head *head)if (pmu_alias_info_file (name))continue ; -snprintf (path,PATH_MAX ,"%s/%s" , dir, name); +scnprintf (path,PATH_MAX ,"%s/%s" , dir, name); file =fopen (path,"r" );if (!file) {