NoName, /* Error case */
ObjName, /* Name is of an shared object file. */
FunName, /* Name is of a function. */
- DotDotDot /* Frame-level wildcard */
+ DotDotDot, /* Frame-level wildcard */
+ SrcName /* Name is of a src file. */
}
SuppLocTy;
Bool name_is_simple_str; /* True if name is a string without
'?' and '*' wildcard characters. */
HChar* name; /* NULL for NoName and DotDotDot */
+ UInt lineno; /* Valid for SrcName. */
}
SuppLoc;
/* buf contains the raw name of a caller, supposedly either
fun:some_function_name or
obj:some_object_name or
+ fun:some_file_name or
+ fun:some_file_name:line# or
...
Set p->ty and p->name accordingly.
p->name is allocated and set to the string
- after the descriptor (fun: or obj:) part.
+ after the descriptor (fun:, obj:, or src: san line#) part.
+ p->lineno is set to non-zero if line# specified; 0 otherwise.
Returns False if failed.
*/
static Bool setLocationTy ( SuppLoc* p, const HChar *buf )
p->ty = ObjName;
return True;
}
+ if (VG_(strncmp)(buf, "src:", 4) == 0) {
+ p->name = VG_(strdup)("errormgr.sLTy.3", buf+4);
+ p->name_is_simple_str = is_simple_str (p->name);
+ p->ty = SrcName;
+ HChar *s = VG_(strchr)(p->name, ':');
+ if (s != NULL) {
+ *s++ = '\0'; // trim colon
+ p->lineno = (UInt) VG_(strtoll10)(s, NULL);
+ } else {
+ p->lineno = 0;
+ }
+ return True;
+ }
if (VG_(strcmp)(buf, "...") == 0) {
p->name = NULL;
p->name_is_simple_str = False;
return True;
}
VG_(printf)("location should be \"...\", or should start "
- "with \"fun:\" or \"obj:\"\n");
+ "with \"fun:\", \"obj:\", or \"src:\"\n");
return False;
}
break;
if (!setLocationTy(&(tmp_callers[i]), buf))
BOMB("location should be \"...\", or should start "
- "with \"fun:\" or \"obj:\"");
+ "with \"fun:\", \"obj:\", or \"src:\"");
i++;
}
// level wildcards.
vg_assert(i > 0); // guaranteed by frame-descriptor reading loop
for (j = 0; j < i; j++) {
- if (tmp_callers[j].ty == FunName || tmp_callers[j].ty == ObjName)
+ if (tmp_callers[j].ty == FunName || tmp_callers[j].ty == ObjName ||
+ tmp_callers[j].ty == SrcName) {
break;
+ }
vg_assert(tmp_callers[j].ty == DotDotDot);
}
vg_assert(j >= 0 && j <= i);
{
const SuppLoc* supploc = (const SuppLoc*)supplocV; /* PATTERN */
IPtoFunOrObjCompleter* ip2fo = (IPtoFunOrObjCompleter*)inputCompleterV;
- HChar* funobj_name; // Fun or Obj name.
+ const HChar* funobjsrc_name; // Fun, Obj, or src file name.
+ UInt src_lineno;
Bool ret;
expandInput(ip2fo, ixInput);
this can't happen. */
vg_assert(0);
case ObjName:
- funobj_name = foComplete(ip2fo, ixInput, False /*needFun*/);
+ funobjsrc_name = foComplete(ip2fo, ixInput, False /*needFun*/);
break;
case FunName:
- funobj_name = foComplete(ip2fo, ixInput, True /*needFun*/);
+ funobjsrc_name = foComplete(ip2fo, ixInput, True /*needFun*/);
+ break;
+ case SrcName: {
+ const HChar* src_dirname; // placeholder only
+ ret = VG_(get_filename_linenum)(VG_(current_DiEpoch)(),
+ ip2fo->ips[ixInput], &funobjsrc_name, &src_dirname, &src_lineno);
+ if (!ret) {
+ /* No file name found for location so no way this is a match. */
+ return ret;
+ }
break;
+ }
default:
vg_assert(0);
}
- /* So now we have the function or object name in funobj_name, and
+ /* So now we have the function or object name in funobjsrc_name, and
the pattern (at the character level) to match against is in
supploc->name. Hence (and leading to a re-entrant call of
VG_(generic_match) if there is a wildcard character): */
if (supploc->name_is_simple_str)
- ret = VG_(strcmp) (supploc->name, funobj_name) == 0;
+ ret = VG_(strcmp) (supploc->name, funobjsrc_name) == 0;
else
- ret = VG_(string_match)(supploc->name, funobj_name);
+ ret = VG_(string_match)(supploc->name, funobjsrc_name);
+ if (ret && supploc->ty == SrcName && supploc->lineno != 0) {
+ ret = (supploc->lineno == src_lineno);
+ }
if (DEBUG_ERRORMGR)
- VG_(printf) ("supp_pattEQinp %s patt %s ixUnput %lu value:%s match:%s\n",
- supploc->ty == FunName ? "fun" : "obj",
- supploc->name, ixInput, funobj_name,
+ VG_(printf) ("supp_pattEQinp %s patt %s ixInput %lu value:%s (lineno:%u vs %u) match:%s\n",
+ supploc->ty == FunName ? "fun" : (supploc->ty == SrcName ? "src" : "obj"),
+ supploc->name, ixInput, funobjsrc_name,
+ supploc->ty == SrcName ? supploc->lineno : 0,
+ supploc->ty == SrcName ? src_lineno : 0,
ret ? "yes" : "no");
return ret;
}
the chain of function calls that led to it. There can be up to 24
of these lines.</para>
- <para>Locations may be names of either shared objects or
- functions. They begin
- <computeroutput>obj:</computeroutput> and
- <computeroutput>fun:</computeroutput> respectively. Function and
- object names to match against may use the wildcard characters
+ <para>Locations may be names of either shared objects, functions,
+ or source lines. They begin with
+ <computeroutput>obj:</computeroutput>,
+ <computeroutput>fun:</computeroutput>, or
+ <computeroutput>src:</computeroutput> respectively. Function,
+ object, and file names to match against may use the wildcard characters
<computeroutput>*</computeroutput> and
- <computeroutput>?</computeroutput>.</para>
+ <computeroutput>?</computeroutput>. Source lines are specified
+ using the form <filename>filename[:lineNumber]</filename>.</para>
<para><command>Important note: </command> C++ function names must be
<command>mangled</command>. If you are writing suppressions by
the X11 libraries shipped on the Linux distro on which this example
was made have had their symbol tables removed.</para>
+<para>An example of the src: specification, again for the Memcheck tool:</para>
+
+<programlisting><![CDATA[
+{
+ libX11.so.6.2/libX11.so.6.2/libXaw.so.7.0
+ Memcheck:Value4
+ src:valid.c:321
+}]]></programlisting>
+
+<para>This suppresses any size-4 uninitialised-value error which occurs
+at line 321 in <filename>valid.c</filename>.</para>
+
<para>Although the above two examples do not make this clear, you can
-freely mix <computeroutput>obj:</computeroutput> and
-<computeroutput>fun:</computeroutput> lines in a suppression.</para>
+freely mix <computeroutput>obj:</computeroutput>,
+<computeroutput>fun:</computeroutput>, and
+<computeroutput>src:</computeroutput>
+lines in a suppression.</para>
<para>Finally, here's an example using three frame-level wildcards:</para>