@@ -155,6 +155,83 @@ std::string readMsg(const pt::ptree &defNode)
155
155
return " <unknown>" ;
156
156
}
157
157
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
+
158
235
bool ValgrindTreeDecoder::readNode (Defect *pDef, pt::ptree::const_iterator defIter)
159
236
{
160
237
static const std::string errorKey = " error" ;
@@ -181,7 +258,22 @@ bool ValgrindTreeDecoder::readNode(Defect *pDef, pt::ptree::const_iterator defIt
181
258
if (defNode.not_found () != itKind)
182
259
keyEvent.event += " [" + itKind->second .get_value <std::string>() + " ]" ;
183
260
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
+
185
277
return true ;
186
278
}
187
279
0 commit comments