Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf probe: Check the return value of strbuf APIs

Check the return value of strbuf APIs in perf-probe
related code, so that it can handle errors in strbuf.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20160510054707.6158.69861.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Masami Hiramatsu and committed by
Arnaldo Carvalho de Melo
bf4d5f25 5cea57f3

+129 -98
+24 -28
tools/perf/util/dwarf-aux.c
··· 915 915 tmp = "*"; 916 916 else if (tag == DW_TAG_subroutine_type) { 917 917 /* Function pointer */ 918 - strbuf_add(buf, "(function_type)", 15); 919 - return 0; 918 + return strbuf_add(buf, "(function_type)", 15); 920 919 } else { 921 920 if (!dwarf_diename(&type)) 922 921 return -ENOENT; ··· 926 927 else if (tag == DW_TAG_enumeration_type) 927 928 tmp = "enum "; 928 929 /* Write a base name */ 929 - strbuf_addf(buf, "%s%s", tmp, dwarf_diename(&type)); 930 - return 0; 930 + return strbuf_addf(buf, "%s%s", tmp, dwarf_diename(&type)); 931 931 } 932 932 ret = die_get_typename(&type, buf); 933 - if (ret == 0) 934 - strbuf_addstr(buf, tmp); 935 - 936 - return ret; 933 + return ret ? ret : strbuf_addstr(buf, tmp); 937 934 } 938 935 939 936 /** ··· 946 951 ret = die_get_typename(vr_die, buf); 947 952 if (ret < 0) { 948 953 pr_debug("Failed to get type, make it unknown.\n"); 949 - strbuf_add(buf, " (unknown_type)", 14); 954 + ret = strbuf_add(buf, " (unknown_type)", 14); 950 955 } 951 956 952 - strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); 953 - 954 - return 0; 957 + return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); 955 958 } 956 959 957 960 #ifdef HAVE_DWARF_GETLOCATIONS ··· 992 999 } 993 1000 994 1001 while ((offset = dwarf_ranges(&scopes[1], offset, &base, 995 - &start, &end)) > 0) { 1002 + &start, &end)) > 0) { 996 1003 start -= entry; 997 1004 end -= entry; 998 1005 999 1006 if (first) { 1000 - strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64, 1001 - name, start, end); 1007 + ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64, 1008 + name, start, end); 1002 1009 first = false; 1003 1010 } else { 1004 - strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64, 1005 - start, end); 1011 + ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64, 1012 + start, end); 1006 1013 } 1014 + if (ret < 0) 1015 + goto out; 1007 1016 } 1008 1017 1009 1018 if (!first) 1010 - strbuf_add(buf, "]>", 2); 1019 + ret = strbuf_add(buf, "]>", 2); 1011 1020 1012 1021 out: 1013 1022 free(scopes); ··· 1049 1054 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) 1050 1055 return -EINVAL; 1051 1056 1052 - while ((offset = dwarf_getlocations( 1053 - &attr, offset, &base, 1054 - &start, &end, &op, &nops)) > 0) { 1057 + while ((offset = dwarf_getlocations(&attr, offset, &base, 1058 + &start, &end, &op, &nops)) > 0) { 1055 1059 if (start == 0) { 1056 1060 /* Single Location Descriptions */ 1057 1061 ret = die_get_var_innermost_scope(sp_die, vr_die, buf); 1058 - return ret; 1062 + goto out; 1059 1063 } 1060 1064 1061 1065 /* Location Lists */ 1062 1066 start -= entry; 1063 1067 end -= entry; 1064 1068 if (first) { 1065 - strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64, 1066 - name, start, end); 1069 + ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64, 1070 + name, start, end); 1067 1071 first = false; 1068 1072 } else { 1069 - strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64, 1070 - start, end); 1073 + ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64, 1074 + start, end); 1071 1075 } 1076 + if (ret < 0) 1077 + goto out; 1072 1078 } 1073 1079 1074 1080 if (!first) 1075 - strbuf_add(buf, "]>", 2); 1076 - 1081 + ret = strbuf_add(buf, "]>", 2); 1082 + out: 1077 1083 return ret; 1078 1084 } 1079 1085 #else
+87 -58
tools/perf/util/probe-event.c
··· 1677 1677 { 1678 1678 struct perf_probe_arg_field *field = pa->field; 1679 1679 struct strbuf buf; 1680 - char *ret; 1680 + char *ret = NULL; 1681 + int err; 1681 1682 1682 - strbuf_init(&buf, 64); 1683 + if (strbuf_init(&buf, 64) < 0) 1684 + return NULL; 1685 + 1683 1686 if (pa->name && pa->var) 1684 - strbuf_addf(&buf, "%s=%s", pa->name, pa->var); 1687 + err = strbuf_addf(&buf, "%s=%s", pa->name, pa->var); 1685 1688 else 1686 - strbuf_addstr(&buf, pa->name ?: pa->var); 1689 + err = strbuf_addstr(&buf, pa->name ?: pa->var); 1690 + if (err) 1691 + goto out; 1687 1692 1688 1693 while (field) { 1689 1694 if (field->name[0] == '[') 1690 - strbuf_addstr(&buf, field->name); 1695 + err = strbuf_addstr(&buf, field->name); 1691 1696 else 1692 - strbuf_addf(&buf, "%s%s", field->ref ? "->" : ".", 1693 - field->name); 1697 + err = strbuf_addf(&buf, "%s%s", field->ref ? "->" : ".", 1698 + field->name); 1694 1699 field = field->next; 1700 + if (err) 1701 + goto out; 1695 1702 } 1696 1703 1697 1704 if (pa->type) 1698 - strbuf_addf(&buf, ":%s", pa->type); 1705 + if (strbuf_addf(&buf, ":%s", pa->type) < 0) 1706 + goto out; 1699 1707 1700 1708 ret = strbuf_detach(&buf, NULL); 1701 - 1709 + out: 1710 + strbuf_release(&buf); 1702 1711 return ret; 1703 1712 } 1704 1713 ··· 1715 1706 static char *synthesize_perf_probe_point(struct perf_probe_point *pp) 1716 1707 { 1717 1708 struct strbuf buf; 1718 - char *tmp; 1719 - int len; 1709 + char *tmp, *ret = NULL; 1710 + int len, err = 0; 1720 1711 1721 - strbuf_init(&buf, 64); 1712 + if (strbuf_init(&buf, 64) < 0) 1713 + return NULL; 1714 + 1722 1715 if (pp->function) { 1723 - strbuf_addstr(&buf, pp->function); 1716 + if (strbuf_addstr(&buf, pp->function) < 0) 1717 + goto out; 1724 1718 if (pp->offset) 1725 - strbuf_addf(&buf, "+%lu", pp->offset); 1719 + err = strbuf_addf(&buf, "+%lu", pp->offset); 1726 1720 else if (pp->line) 1727 - strbuf_addf(&buf, ":%d", pp->line); 1721 + err = strbuf_addf(&buf, ":%d", pp->line); 1728 1722 else if (pp->retprobe) 1729 - strbuf_addstr(&buf, "%return"); 1723 + err = strbuf_addstr(&buf, "%return"); 1724 + if (err) 1725 + goto out; 1730 1726 } 1731 1727 if (pp->file) { 1732 1728 tmp = pp->file; ··· 1740 1726 tmp = strchr(pp->file + len - 30, '/'); 1741 1727 tmp = tmp ? tmp + 1 : pp->file + len - 30; 1742 1728 } 1743 - strbuf_addf(&buf, "@%s", tmp); 1744 - if (!pp->function && pp->line) 1745 - strbuf_addf(&buf, ":%d", pp->line); 1729 + err = strbuf_addf(&buf, "@%s", tmp); 1730 + if (!err && !pp->function && pp->line) 1731 + err = strbuf_addf(&buf, ":%d", pp->line); 1746 1732 } 1747 - 1748 - return strbuf_detach(&buf, NULL); 1733 + if (!err) 1734 + ret = strbuf_detach(&buf, NULL); 1735 + out: 1736 + strbuf_release(&buf); 1737 + return ret; 1749 1738 } 1750 1739 1751 1740 #if 0 ··· 1779 1762 static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref, 1780 1763 struct strbuf *buf, int depth) 1781 1764 { 1765 + int err; 1782 1766 if (ref->next) { 1783 1767 depth = __synthesize_probe_trace_arg_ref(ref->next, buf, 1784 1768 depth + 1); 1785 1769 if (depth < 0) 1786 - goto out; 1770 + return depth; 1787 1771 } 1788 - strbuf_addf(buf, "%+ld(", ref->offset); 1789 - out: 1790 - return depth; 1772 + err = strbuf_addf(buf, "%+ld(", ref->offset); 1773 + return (err < 0) ? err : depth; 1791 1774 } 1792 1775 1793 1776 static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, 1794 1777 struct strbuf *buf) 1795 1778 { 1796 1779 struct probe_trace_arg_ref *ref = arg->ref; 1797 - int depth = 0; 1780 + int depth = 0, err; 1798 1781 1799 1782 /* Argument name or separator */ 1800 1783 if (arg->name) 1801 - strbuf_addf(buf, " %s=", arg->name); 1784 + err = strbuf_addf(buf, " %s=", arg->name); 1802 1785 else 1803 - strbuf_addch(buf, ' '); 1786 + err = strbuf_addch(buf, ' '); 1787 + if (err) 1788 + return err; 1804 1789 1805 1790 /* Special case: @XXX */ 1806 1791 if (arg->value[0] == '@' && arg->ref) ··· 1817 1798 1818 1799 /* Print argument value */ 1819 1800 if (arg->value[0] == '@' && arg->ref) 1820 - strbuf_addf(buf, "%s%+ld", arg->value, arg->ref->offset); 1801 + err = strbuf_addf(buf, "%s%+ld", arg->value, arg->ref->offset); 1821 1802 else 1822 - strbuf_addstr(buf, arg->value); 1803 + err = strbuf_addstr(buf, arg->value); 1823 1804 1824 1805 /* Closing */ 1825 - while (depth--) 1826 - strbuf_addch(buf, ')'); 1827 - /* Print argument type */ 1828 - if (arg->type) 1829 - strbuf_addf(buf, ":%s", arg->type); 1806 + while (!err && depth--) 1807 + err = strbuf_addch(buf, ')'); 1830 1808 1831 - return 0; 1809 + /* Print argument type */ 1810 + if (!err && arg->type) 1811 + err = strbuf_addf(buf, ":%s", arg->type); 1812 + 1813 + return err; 1832 1814 } 1833 1815 1834 1816 char *synthesize_probe_trace_command(struct probe_trace_event *tev) ··· 1837 1817 struct probe_trace_point *tp = &tev->point; 1838 1818 struct strbuf buf; 1839 1819 char *ret = NULL; 1840 - int i; 1820 + int i, err; 1841 1821 1842 1822 /* Uprobes must have tp->module */ 1843 1823 if (tev->uprobes && !tp->module) 1844 1824 return NULL; 1845 1825 1846 - strbuf_init(&buf, 32); 1847 - strbuf_addf(&buf, "%c:%s/%s ", tp->retprobe ? 'r' : 'p', 1848 - tev->group, tev->event); 1826 + if (strbuf_init(&buf, 32) < 0) 1827 + return NULL; 1828 + 1829 + if (strbuf_addf(&buf, "%c:%s/%s ", tp->retprobe ? 'r' : 'p', 1830 + tev->group, tev->event) < 0) 1831 + goto error; 1849 1832 /* 1850 1833 * If tp->address == 0, then this point must be a 1851 1834 * absolute address uprobe. ··· 1862 1839 1863 1840 /* Use the tp->address for uprobes */ 1864 1841 if (tev->uprobes) 1865 - strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address); 1842 + err = strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address); 1866 1843 else if (!strncmp(tp->symbol, "0x", 2)) 1867 1844 /* Absolute address. See try_to_find_absolute_address() */ 1868 - strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "", 1869 - tp->module ? ":" : "", tp->address); 1845 + err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "", 1846 + tp->module ? ":" : "", tp->address); 1870 1847 else 1871 - strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "", 1872 - tp->module ? ":" : "", tp->symbol, tp->offset); 1848 + err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "", 1849 + tp->module ? ":" : "", tp->symbol, tp->offset); 1850 + if (err) 1851 + goto error; 1873 1852 1874 1853 for (i = 0; i < tev->nargs; i++) 1875 1854 if (synthesize_probe_trace_arg(&tev->args[i], &buf) < 0) ··· 1985 1960 if (tev->args[i].name) 1986 1961 pev->args[i].name = strdup(tev->args[i].name); 1987 1962 else { 1988 - strbuf_init(&buf, 32); 1963 + if ((ret = strbuf_init(&buf, 32)) < 0) 1964 + goto error; 1989 1965 ret = synthesize_probe_trace_arg(&tev->args[i], &buf); 1990 1966 pev->args[i].name = strbuf_detach(&buf, NULL); 1991 1967 } 1992 1968 if (pev->args[i].name == NULL && ret >= 0) 1993 1969 ret = -ENOMEM; 1994 1970 } 1995 - 1971 + error: 1996 1972 if (ret < 0) 1997 1973 clear_perf_probe_event(pev); 1998 1974 ··· 2166 2140 const char *module, 2167 2141 struct strbuf *result) 2168 2142 { 2169 - int i; 2143 + int i, ret; 2170 2144 char *buf; 2171 2145 2172 2146 if (asprintf(&buf, "%s:%s", group, event) < 0) 2173 2147 return -errno; 2174 - strbuf_addf(result, " %-20s (on ", buf); 2148 + ret = strbuf_addf(result, " %-20s (on ", buf); 2175 2149 free(buf); 2150 + if (ret) 2151 + return ret; 2176 2152 2177 2153 /* Synthesize only event probe point */ 2178 2154 buf = synthesize_perf_probe_point(&pev->point); 2179 2155 if (!buf) 2180 2156 return -ENOMEM; 2181 - strbuf_addstr(result, buf); 2157 + ret = strbuf_addstr(result, buf); 2182 2158 free(buf); 2183 2159 2184 - if (module) 2185 - strbuf_addf(result, " in %s", module); 2160 + if (!ret && module) 2161 + ret = strbuf_addf(result, " in %s", module); 2186 2162 2187 - if (pev->nargs > 0) { 2188 - strbuf_add(result, " with", 5); 2189 - for (i = 0; i < pev->nargs; i++) { 2163 + if (!ret && pev->nargs > 0) { 2164 + ret = strbuf_add(result, " with", 5); 2165 + for (i = 0; !ret && i < pev->nargs; i++) { 2190 2166 buf = synthesize_perf_probe_arg(&pev->args[i]); 2191 2167 if (!buf) 2192 2168 return -ENOMEM; 2193 - strbuf_addf(result, " %s", buf); 2169 + ret = strbuf_addf(result, " %s", buf); 2194 2170 free(buf); 2195 2171 } 2196 2172 } 2197 - strbuf_addch(result, ')'); 2173 + if (!ret) 2174 + ret = strbuf_addch(result, ')'); 2198 2175 2199 - return 0; 2176 + return ret; 2200 2177 } 2201 2178 2202 2179 /* Show an event */
+18 -12
tools/perf/util/probe-finder.c
··· 1294 1294 { 1295 1295 struct available_var_finder *af = data; 1296 1296 struct variable_list *vl; 1297 + struct strbuf buf = STRBUF_INIT; 1297 1298 int tag, ret; 1298 1299 1299 1300 vl = &af->vls[af->nvls - 1]; ··· 1308 1307 if (ret == 0 || ret == -ERANGE) { 1309 1308 int ret2; 1310 1309 bool externs = !af->child; 1311 - struct strbuf buf; 1312 1310 1313 - strbuf_init(&buf, 64); 1311 + if (strbuf_init(&buf, 64) < 0) 1312 + goto error; 1314 1313 1315 1314 if (probe_conf.show_location_range) { 1316 - if (!externs) { 1317 - if (ret) 1318 - strbuf_add(&buf, "[INV]\t", 6); 1319 - else 1320 - strbuf_add(&buf, "[VAL]\t", 6); 1321 - } else 1322 - strbuf_add(&buf, "[EXT]\t", 6); 1315 + if (!externs) 1316 + ret2 = strbuf_add(&buf, 1317 + ret ? "[INV]\t" : "[VAL]\t", 6); 1318 + else 1319 + ret2 = strbuf_add(&buf, "[EXT]\t", 6); 1320 + if (ret2) 1321 + goto error; 1323 1322 } 1324 1323 1325 1324 ret2 = die_get_varname(die_mem, &buf); 1326 1325 1327 1326 if (!ret2 && probe_conf.show_location_range && 1328 1327 !externs) { 1329 - strbuf_addch(&buf, '\t'); 1328 + if (strbuf_addch(&buf, '\t') < 0) 1329 + goto error; 1330 1330 ret2 = die_get_var_range(&af->pf.sp_die, 1331 1331 die_mem, &buf); 1332 1332 } ··· 1336 1334 if (ret2 == 0) { 1337 1335 strlist__add(vl->vars, 1338 1336 strbuf_detach(&buf, NULL)); 1339 - } else 1340 - strbuf_release(&buf); 1337 + } 1338 + strbuf_release(&buf); 1341 1339 } 1342 1340 } 1343 1341 ··· 1345 1343 return DIE_FIND_CB_CONTINUE; 1346 1344 else 1347 1345 return DIE_FIND_CB_SIBLING; 1346 + error: 1347 + strbuf_release(&buf); 1348 + pr_debug("Error in strbuf\n"); 1349 + return DIE_FIND_CB_END; 1348 1350 } 1349 1351 1350 1352 /* Add a found vars into available variables list */