Number: 879
Title: agnode twice with same arguments returns different pointers
Submitter: Ludo Van Put
Date: Tue Feb 7 10:24:45 2006
Subsys: Lib(a)graph
Version: 2.6
System: PowerPC-Linux-Ubuntu (Linux minimac 2.6.12-10-powerpc)
Severity: major
Problem:
When calling agnode twice with the same arguments, with other calls to agnode in between, I get different pointers as a result, in some cases. However, when I run the same program with the valgrind memcheck tool attached, it goes well.

I will give a listing below that is the output from gdb (6.3). Note that gdb wrongly thinks that the arguments to agnode are on the stack, that's why you will see all those 'up', 'down', and 'finish' commands. I've checked the assembly code to see if parameters are passed well and this seems ok. In the listing there is one example that goes wrong and another that goes well.


Breakpoint 1, agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44
44          if ((n = agfindnode(g->root, name)) == NULL) {
(gdb) up
#1  0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154
154           graphviz_node = agnode(graphviz_fg,pointer);
(gdb) p pointer
$25 = "0x111c4744"
(gdb) down
#0  agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44
44          if ((n = agfindnode(g->root, name)) == NULL) {
(gdb) finish
Run till exit from #0  agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44
0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154
154           graphviz_node = agnode(graphviz_fg,pointer);
Value returned is $26 = (Agnode_t *) 0x111e7e90
(gdb) c
Continuing.
Inserting bbl 0x111c4744 - gv 0x111e7e90
Setting label of node 0x111e7e90 to bbl at 0x1000012c (in foo at 0x1000012c)
instructions:
0x1000012c :  stwu       ...
0x10000130 :  stw        ...
0x10000134 :  or         ...
0x10000138 :  stw        ...
0x1000013c :  lwz        ...
0x10000140 :  srawi      ...
0x10000144 :  addze      ...
0x10000148 :  stw        ...
0x1000014c :  lwz        ...
0x10000150 :  cmpw       cr7,r0,0
0x10000154 :  bc         12,30,16

Breakpoint 1, agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) up #1 0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154 154 graphviz_node = agnode(graphviz_fg,pointer); (gdb) p pointer $27 = "0x111c4864" (gdb) down #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) finish Run till exit from #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154 154 graphviz_node = agnode(graphviz_fg,pointer); Value returned is $28 = (Agnode_t *) 0x111e8998 (gdb) c Continuing. Inserting bbl 0x111c4864 - gv 0x111e8998 Setting label of node 0x111e8998 to bbl at 0x10000158 (in foo at 0x1000012c) instructions: 0x10000158 : li r0,0 0x1000015c : stw ... 0x10000160 : b 12

Breakpoint 1, agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) up #1 0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154 154 graphviz_node = agnode(graphviz_fg,pointer); (gdb) p pointer $29 = "0x111c4aa4" (gdb) down #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) finish Run till exit from #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154 154 graphviz_node = agnode(graphviz_fg,pointer); Value returned is $30 = (Agnode_t *) 0x111e82e8 (gdb) c Continuing. Inserting bbl 0x111c4aa4 - gv 0x111e82e8 Setting label of node 0x111e82e8 to bbl at 0x1000016c (in foo at 0x1000012c) instructions: 0x1000016c : lwz ... 0x10000170 : or ... 0x10000174 : lwz ... 0x10000178 : lwz ... 0x1000017c : or ... 0x10000180 : bclr ...

Breakpoint 1, agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) up #1 0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154 154 graphviz_node = agnode(graphviz_fg,pointer); (gdb) p pointer $31 = "0x111c4984" (gdb) down #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) finish Run till exit from #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154 154 graphviz_node = agnode(graphviz_fg,pointer); Value returned is $32 = (Agnode_t *) 0x111e8ed0 (gdb) c Continuing. Inserting bbl 0x111c4984 - gv 0x111e8ed0 Setting label of node 0x111e8ed0 to bbl at 0x10000164 (in foo at 0x1000012c) instructions: 0x10000164 : li r0,1 0x10000168 : stw ...

Breakpoint 1, agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) up #1 0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154 154 graphviz_node = agnode(graphviz_fg,pointer); (gdb) p pointer $33 = "0x111bc3e4" (gdb) down #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) finish Run till exit from #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 0x1019e5b0 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:154 154 graphviz_node = agnode(graphviz_fg,pointer); Value returned is $34 = (Agnode_t *) 0x111e8ff8 (gdb) c Continuing. Inserting bbl 0x111bc3e4 - gv 0x111e8ff8 Setting label of node 0x111e8ff8 to RETURN (0)

Breakpoint 1, agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) up #1 0x1019efdc in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:274 274 insert1 = agnode(graphviz_fg,pointer); (gdb) p pointer $35 = "0x111c4744" (gdb) down #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) finish Run till exit from #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 0x1019efdc in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:274 274 insert1 = agnode(graphviz_fg,pointer); Value returned is $36 = (Agnode_t *) 0x111e9120 -------------------------------------^^^^^^^^^^ wrong! previously agnode returned 0x111e7e90 for this!

(gdb) c Continuing.

Breakpoint 1, agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) up #1 0x1019eff4 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:275 275 insert2 = agnode(graphviz_fg,pointer2); (gdb) p pointer2 $37 = "0x111c4864" (gdb) down #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 44 if ((n = agfindnode(g->root, name)) == NULL) { (gdb) finish Run till exit from #0 agnode (g=0x111e6f00, name=0x111cacd0 "021001�") at node.c:44 0x1019eff4 in gui_flowgraph_build (canvas_window=0x11162324) at lancet_flowgraph.c:275 275 insert2 = agnode(graphviz_fg,pointer2); Value returned is $38 = (Agnode_t *) 0x111e8998 -------------------------------------^^^^^^^^^^

ok! this return value is the same as before!
Comments:
The code seems to work fine on a i386 architecture, we never had an issue with agnode on that platform. Some endianess thing?

[ludo]Yes, but I have mentioned in the bug report that you cannot trust those values. Gdb mistakenly thinks that the arguments are on the stack and it prints the arguments wrong (probably the dwarf debug info is wrong or gdb misinterpretes it). In fact, the arguments passed are in register r3 (g) and r4 (name), and I've checked that they are passed correctly by studying the assembly code and printing the contents of the registers and the stack in gdb.

[erg] Sorry, I didn't realize that gdb was lying that much. That means that the non-ascii characters may not be relevant.

Does gdb usually work better than this? Any chance the funny gdb values indicate a binary that has some significant problems, with the agnode() being just one indication of this? Is there any chance any of the pieces were compiled with different compilers? We've noticed that gcc doesn't necessarily play well with other compilers. Sometimes turning off optimization can also help.

[ludo] We just started working on this machine, it's a mac mini with Ubuntu Linux installed. So I can't tell if gdb usually does a better job. Anyhow I've compiled both graphviz and my own code with the same compiler (gcc (GCC) 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)). So that excludes another possibility. Graphviz was compiled with giving special CFLAGS, so I guess it was -O2, the default.

I've recorded a sequence of calls to graphviz. I will check if it goes ok on our minimac tomorrow morning (it's getting late here in Belgium :-) ). I'll let you know the outcome of this experiment, but i will attach the sequence, so you can have a look (if you've got the time for it, remember no hurry!).

Thanks again for your help, and I sincerely hope this is not going to show that there is some memory corruption in our code, I really don't want to waste your time on this.


graphviz_fg = agopen("main",AGDIGRAPH);
agraphattr(graphviz_fg,"fontname","Arial");
agraphattr(graphviz_fg,"fontsize","12");
agnodeattr(graphviz_fg,"fontname","Arial");
agnodeattr(graphviz_fg,"fontsize","12");
agnodeattr(graphviz_fg,"shape","box");
attrib_node_style = agnodeattr(graphviz_fg,"style","");
attrib_node_fillcolor = agnodeattr(graphviz_fg,"fillcolor","white");
attrib_edge_color = agedgeattr(graphviz_fg,"color","blue");
attrib_edge_style = agedgeattr(graphviz_fg,"style","dashed");
graphviz_node = agnode(graphviz_fg,"0x111d629c");
agxset (graphviz_node,attrib_node_fillcolor->index,"white");
agset(graphviz_node,"label","bbl at 0x10000094 (in main at 0x10000094)ninstructions:n0x10000094 :  stwu       ...n0x10000098 :  mfspr      ...n0x1000009c :  stw        ...n0x100000a0 :  stw        ...n0x100000a4 :  or         ...");
graphviz_node = agnode(graphviz_fg,"0x111d63bc");
agxset (graphviz_node,attrib_node_fillcolor->index,"white");
agset(graphviz_node,"label","bbl at 0x100000c4 (in main at 0x10000094)ninstructions:n0x100000c4 :  lis        r9,4097n0x100000c8 :  li         r0,2n0x100000cc :  stw        ...");
graphviz_node = agnode(graphviz_fg,"0x111d64dc");
agxset (graphviz_node,attrib_node_fillcolor->index,"white");
agset(graphviz_node,"label","bbl at 0x100000d0 (in main at 0x10000094)ninstructions:n0x100000d0 :  lis        r9,4097n0x100000d4 :  lwz        ...n0x100000d8 :  or         ...n0x100000dc :  crxor      ...n0x100000e0 :  bl        ");
graphviz_node = agnode(graphviz_fg,"0x111d65fc");
agxset (graphviz_node,attrib_node_fillcolor->index,"white");
agset(graphviz_node,"label","bbl at 0x100000e4 (in main at 0x10000094)ninstructions:n0x100000e4 :  or         ...n0x100000e8 :  cmpw       cr7,r0,0n0x100000ec :  bc         12,30,16");
graphviz_node = agnode(graphviz_fg,"0x111d671c");
agxset (graphviz_node,attrib_node_fillcolor->index,"white");
agset(graphviz_node,"label","bbl at 0x100000f0 (in main at 0x10000094)ninstructions:n0x100000f0 :  li         r0,1024n0x100000f4 :  stw        ...n0x100000f8 :  b          20");
graphviz_node = agnode(graphviz_fg,"0x111d695c");
agxset (graphviz_node,attrib_node_fillcolor->index,"white");
agset(graphviz_node,"label","bbl at 0x1000010c (in main at 0x10000094)ninstructions:n0x1000010c :  lwz        ...n0x10000110 :  or         ...n0x10000114 :  lwz        ...n0x10000118 :  lwz        ...n0x1000011c :  mtspr      ...");
graphviz_node = agnode(graphviz_fg,"0x111d683c");
agxset (graphviz_node,attrib_node_fillcolor->index,"white");
agset(graphviz_node,"label","bbl at 0x100000fc (in main at 0x10000094)ninstructions:n0x100000fc :  lwz        ...n0x10000100 :  lwz        ...n0x10000104 :  divw       ...n0x10000108 :  stw        ...");
graphviz_node = agnode(graphviz_fg,"0x111ce55c");
agxset(graphviz_node,attrib_node_fillcolor->index,"lightblue");
agset(graphviz_node,"label","RETURN (0)");
insert1 = agnode(graphviz_fg,"0x111d629c");
insert2 = agnode(graphviz_fg,"0x111d63bc");
graphviz_edge=agedge(graphviz_fg,insert1,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"green");
agset(graphviz_edge,"label","O(0,00)");
insert1 = agnode(graphviz_fg,"0x111d629c");
insert2 = agnode(graphviz_fg,"0x111d64dc");
graphviz_edge=agedge(graphviz_fg,insert1,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"black");
agset(graphviz_edge,"label","O(0,00)");
bbl_gv_node = agnode(graphviz_fg,"0x111d64dc");
insert1 = agnode(graphviz_fg,"f0x111d6a7c");
graphviz_edge=agedge(graphviz_fg,bbl_gv_node,insert1);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"red");
graphviz_node = agnode(graphviz_fg,"f0x111d6a7c");
agset(graphviz_node,"label","foo (bbl at 0x1000012c) (0)");
agxset(graphviz_node,attrib_node_fillcolor->index,"yellow");
agxset (graphviz_node,attrib_node_style->index,"filled");
insert1 = agnode(graphviz_fg,"0x111d65fc");
insert2 = agnode(graphviz_fg,"0x111d671c");
graphviz_edge=agedge(graphviz_fg,insert1,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"green");
agset(graphviz_edge,"label","O(0,00)");
insert1 = agnode(graphviz_fg,"0x111d65fc");
insert2 = agnode(graphviz_fg,"0x111d683c");
graphviz_edge=agedge(graphviz_fg,insert1,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"black");
agset(graphviz_edge,"label","O(0,00)");
insert1 = agnode(graphviz_fg,"0x111d671c");
insert2 = agnode(graphviz_fg,"0x111d695c");
graphviz_edge=agedge(graphviz_fg,insert1,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"black");
agset(graphviz_edge,"label","O(0,00)");
bbl_gv_node = agnode(graphviz_fg,"0x111d695c");
insert1 = agnode(graphviz_fg,"f0x111d6a7c");
graphviz_edge=agedge(graphviz_fg,bbl_gv_node,insert1);
agxset(graphviz_edge,attrib_edge_style->index,"bold");
agxset(graphviz_edge,attrib_edge_color->index,"white");
graphviz_node = agnode(graphviz_fg,"f0x111d6a7c");
agset(graphviz_node,"label","bbl at 0x1000012c (in foo at 0x1000012c) in foo");
agxset(graphviz_node,attrib_node_fillcolor->index,"red");
agxset (graphviz_node,attrib_node_style->index,"filled");
insert1 = agnode(graphviz_fg,"0x111d695c");
insert2 = agnode(graphviz_fg,"0x111ce55c");
graphviz_edge=agedge(graphviz_fg,insert1,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"black");
agset(graphviz_edge,"label","O(0,00)");
insert2 = agnode(graphviz_fg,"0x111d629c");
new_gv_node = agnode(graphviz_fg,"e0x111db0dc");
graphviz_edge=agedge(graphviz_fg,new_gv_node,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"black");
agset(new_gv_node,"label","Entry");
agxset(new_gv_node,attrib_node_fillcolor->index,"green");
agxset (new_gv_node,attrib_node_style->index,"filled");
insert2 = agnode(graphviz_fg,"0x111d65fc");
new_gv_node = agnode(graphviz_fg,"f0x111d6a7c");
graphviz_edge=agedge(graphviz_fg,new_gv_node,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"blue");
insert2 = agnode(graphviz_fg,"0x111ce55c");
new_gv_node = agnode(graphviz_fg,"C0x111ce71c");
graphviz_edge=agedge(graphviz_fg,new_gv_node,insert2);
agxset(graphviz_edge,attrib_edge_style->index,"solid");
agxset(graphviz_edge,attrib_edge_color->index,"blue");
agset(new_gv_node,"label","return (0) from foo");
agxset(new_gv_node,attrib_node_fillcolor->index,"white");

[ludo] 've tested the sequence I've send you. It turns out that everything goes fine. So the memory gets corrupt elsewhere in our program, but the result is that graphviz only works correct with a memory checker attached. I got confused by the fact that everything else in our program works fine, but that is no clear indication of the absense of memory troubles of course :-( So look no further, it's probably no graphviz problem. Sorry for the overhead. If I can locate the problem, and it turns out that there is still an issue with graphviz, I will let you know.

[erg] Thanks. If you ever can get it narrowed down, particularly with a small program, and it implicates the graphviz software, please send it on.
Owner: erg
Status: Fixed