Skip to content

Commit 5747e41

Browse files
committed
xml-parser: go through valgrind's stack trace
1 parent b3aa4b8 commit 5747e41

File tree

1 file changed

+93
-1
lines changed

1 file changed

+93
-1
lines changed

src/xml-parser.cc

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,83 @@ std::string readMsg(const pt::ptree &defNode)
155155
return "<unknown>";
156156
}
157157

158+
/// return true if the given frame is internal to valgrind itself
159+
bool isInternalFrame(const pt::ptree &frameNode)
160+
{
161+
std::string obj = valueOf<std::string>(frameNode, "obj", "");
162+
if (obj.empty())
163+
return false;
164+
165+
static const std::string valgrindPrefix = "/usr/libexec/valgrind/";
166+
static const size_t valgrindPrefixLen = valgrindPrefix.size();
167+
if (obj.size() <= valgrindPrefixLen)
168+
return false;
169+
170+
obj.resize(valgrindPrefixLen);
171+
return (valgrindPrefix == obj);
172+
}
173+
174+
/// go through stack, append "note" events, and update the key event
175+
void readStack(Defect *pDef, const pt::ptree &stackNode)
176+
{
177+
int keyEventBestScore = -1;
178+
179+
for (const pt::ptree::value_type &frame : stackNode) {
180+
const pt::ptree &frameNode = frame.second;
181+
const bool intFrame = isInternalFrame(frameNode);
182+
int keyEventScore = 0;
183+
184+
// initialize "note" event
185+
DefEvent noteEvt("note");
186+
noteEvt.msg = "called from ";
187+
noteEvt.verbosityLevel = /* note */ 1 + static_cast<int>(intFrame);
188+
189+
// read function name if available
190+
const std::string fn = valueOf<std::string>(frameNode, "fn", "");
191+
noteEvt.msg += (fn.empty())
192+
? "here"
193+
: fn + "()";
194+
195+
const pt::ptree *fileNode;
196+
if (findChildOf(&fileNode, frameNode, "file")) {
197+
// read absolute path of the source file
198+
noteEvt.fileName = fileNode->get_value<std::string>();
199+
const std::string dir = valueOf<std::string>(frameNode, "dir", "");
200+
if (!dir.empty())
201+
noteEvt.fileName = dir + "/" + noteEvt.fileName;
202+
203+
// read line number
204+
noteEvt.line = valueOf<int>(frameNode, "line", 0);
205+
keyEventScore = 8;
206+
}
207+
else if (findChildOf(&fileNode, frameNode, "obj")) {
208+
// pick path of the object file
209+
noteEvt.fileName = fileNode->get_value<std::string>();
210+
keyEventScore = 4;
211+
}
212+
else if (findChildOf(&fileNode, frameNode, "ip")) {
213+
// pick address of the code in memory
214+
noteEvt.fileName = fileNode->get_value<std::string>();
215+
keyEventScore = 2;
216+
}
217+
else {
218+
// no location info found --> skip this frame
219+
continue;
220+
}
221+
222+
if (!intFrame && keyEventBestScore < keyEventScore) {
223+
// update key event
224+
keyEventBestScore = keyEventScore;
225+
DefEvent &keyEvent = pDef->events[pDef->keyEventIdx];
226+
keyEvent.fileName = noteEvt.fileName;
227+
keyEvent.line = noteEvt.line;
228+
}
229+
230+
// finally push the "note" event
231+
pDef->events.push_back(noteEvt);
232+
}
233+
}
234+
158235
bool ValgrindTreeDecoder::readNode(Defect *pDef, pt::ptree::const_iterator defIter)
159236
{
160237
static const std::string errorKey = "error";
@@ -181,7 +258,22 @@ bool ValgrindTreeDecoder::readNode(Defect *pDef, pt::ptree::const_iterator defIt
181258
if (defNode.not_found() != itKind)
182259
keyEvent.event += "[" + itKind->second.get_value<std::string>() + "]";
183260

184-
// TODO
261+
// go through stack trace
262+
const pt::ptree *stackNode;
263+
if (findChildOf(&stackNode, defNode, "stack"))
264+
// this invalidates &keyEvent !!!
265+
readStack(pDef, *stackNode);
266+
267+
// read aux valgrind's message if available and insert _after_ the key event
268+
const pt::ptree *auxwhat;
269+
if (findChildOf(&auxwhat, defNode, "auxwhat")) {
270+
DefEvent auxEvent = def.events[def.keyEventIdx];
271+
auxEvent.event = "note";
272+
auxEvent.verbosityLevel = /* note */ 1;
273+
auxEvent.msg = auxwhat->get_value<std::string>();
274+
def.events.insert(def.events.begin() + def.keyEventIdx + 1, auxEvent);
275+
}
276+
185277
return true;
186278
}
187279

0 commit comments

Comments
 (0)