home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / gnu / gdb / bug / 995 < prev    next >
Encoding:
Text File  |  1992-08-21  |  6.5 KB  |  228 lines

  1. Newsgroups: gnu.gdb.bug
  2. Path: sparky!uunet!cis.ohio-state.edu!cat.rpi.edu!tarbox
  3. From: tarbox@cat.rpi.edu (Glenn Tarbox)
  4. Subject: (none)
  5. Message-ID: <9208211707.AA26966@cat.rpi.edu>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: GNUs Not Usenet
  8. Distribution: gnu
  9. Date: Fri, 21 Aug 1992 17:07:32 GMT
  10. Approved: bug-gdb@prep.ai.mit.edu
  11. Lines: 215
  12.  
  13. Hello,
  14.  
  15. This is what I hope is a complete bug report on a problem with gdb
  16. which I know existed in 4.4 and is still with us in 4.6.
  17.  
  18. First the necessary background.  The computer sytem is a Sun Sparc
  19. running 4.1.1.  I used the gcc-2.2.2 compiler to compile gdb and the
  20. test program included.  When gdb is compiled using suns cc compiler,
  21. the problem persists.
  22.  
  23. To compile the test program code included I used the following:
  24.  
  25. g++ -ggdb3 -o testgdb testgdb.cc
  26.  
  27. Simply stated, the problem is that (using g++) when passing an object
  28. by value to a subroutine, the debugger gets the address of the object
  29. passed into the subroutine wrong.  Therefore, when looking at that
  30. object, it has garbage inside.
  31.  
  32. The object does get passed correctly, however, as the test code which I
  33. wrote illustrates.
  34.  
  35. First, the code which illustrates the problem.  The line numbers correspond
  36. to those provided by gdb.  At the end of this note, this file is provided
  37. without the numbers to facilitate testing at your site.
  38.  
  39. 1    #include <stdio.h>
  40. 2    
  41. 3    class mytestclass{
  42. 4      int first, second, third, fourth;;
  43. 5    public:
  44. 6      mytestclass(){first=second=third=fourth=1;}
  45. 7      mytestclass(mytestclass &inarg);
  46. 8      void printout();
  47. 9    };
  48. 10    
  49. 11    mytestclass::mytestclass(mytestclass &inarg)
  50. 12    {
  51. 13      (*this)=inarg;
  52. 14      fprintf(stderr," in the copy constructor\n");
  53. 15      printout();
  54. 16    }
  55. 17    
  56. 18    void mytestclass::printout()
  57. 19    {
  58. 20      fprintf(stderr," variables = %d, %d, %d, %d\n",first,second,third,fourth);
  59. 21      fprintf(stderr," this = %X\n",(int)this);
  60. 22    }
  61. 23    
  62. 24    void testsubroutine(mytestclass subarg);
  63. 25    
  64. 26    main()
  65. 27    {
  66. 28      mytestclass testone;
  67. 29    
  68. 30      mytestclass testtwo(testone);
  69. 31    
  70. 32      testsubroutine(testtwo);
  71. 33    }
  72. 34    
  73. 35    void testsubroutine(mytestclass subarg)
  74. 36    {
  75. 37      fprintf(stderr," in the subroutine\n");
  76. 38      subarg.printout();
  77. 39    }
  78.  
  79. When this code is run, the following output is produced:
  80.  
  81.  in the copy constructor
  82.  variables = 1, 1, 1, 1
  83.  this = F7FFF850
  84.  in the copy constructor
  85.  variables = 1, 1, 1, 1
  86.  this = F7FFF840
  87.  in the subroutine
  88.  variables = 1, 1, 1, 1
  89.  this = F7FFF840
  90.  
  91. What this code shows is that in the copy constructor, the same object is
  92. being initialized as is eventually being passed to the testsubroutine
  93. subroutine.  The code works as we expect it would.
  94.  
  95. But, the issue is:  What happens to gdb when looking at an object which
  96. has been passed by value to a subroutine and when a copy constructor
  97. is provided?  Here is a gdb session which explores that question.
  98.  
  99. NOTE:  I have annotated this session with comments after the gt>
  100. symbol
  101.  
  102. Current directory is /home/a/tarbox/testgdb/
  103. GDB is free software and you are welcome to distribute copies of it
  104.  under certain conditions; type "show copying" to see the conditions.
  105. There is absolutely no warranty for GDB; type "show warranty" for details.
  106. GDB 4.6, Copyright 1992 Free Software Foundation, Inc...
  107. (gdb) Breakpoint 1 at 0x2320: file testgdb.cc, line 14.
  108. (gdb) Breakpoint 2 at 0x2404: file testgdb.cc, line 32.
  109. (gdb) Breakpoint 3 at 0x2454: file testgdb.cc, line 37.
  110. (gdb) r
  111. Starting program: /home/a/tarbox/testgdb/testgdb 
  112.  
  113. Breakpoint 1, mytestclass::mytestclass (this=0xf7fff850, inarg=@0xf7fff860)
  114.     at testgdb.cc:14
  115. (gdb) p this
  116. $1 = (struct mytestclass *) 0xf7fff850
  117. (gdb) c
  118. Continuing.
  119.  in the copy constructor
  120.  variables = 1, 1, 1, 1
  121.  this = F7FFF850
  122.  
  123. Breakpoint 2, main () at testgdb.cc:32
  124. (gdb) p &testtwo
  125. $2 = (struct mytestclass *) 0xf7fff850
  126. (gdb) p testtwo
  127. $3 = {first = 1, second = 1, third = 1, fourth = 1}
  128. (gdb) c
  129. Continuing.
  130.  
  131. gt> We see here that the "this" pointer printed by fprintf in the
  132. gt> copy constructor is the same as what gdb sees for testtwo 
  133. gt> after it is created in main().  This is how we expect the copy
  134. gt> constructor to work.
  135.  
  136. Breakpoint 1, mytestclass::mytestclass (this=0xf7fff840, inarg=@0xf7fff850)
  137.     at testgdb.cc:14
  138. (gdb) p this
  139. $4 = (struct mytestclass *) 0xf7fff840
  140. (gdb) c
  141. Continuing.
  142.  in the copy constructor
  143.  variables = 1, 1, 1, 1
  144.  this = F7FFF840
  145.  
  146. gt> Here, in the copy constructor, which is being called because the
  147. gt> argument to testsubroutine is being passed by value, we see that
  148. gt> "this" as printed by gdb and printed by fprintf correspond.
  149.  
  150. Breakpoint 3, testsubroutine (subarg={first = 4194437, second = 8292, 
  151.       third = 8296, fourth = 0}) at testgdb.cc:37
  152. (gdb) p &subarg
  153. $5 = (struct mytestclass *) 0xf7fff7c8
  154. (gdb) p subarg
  155. $6 = {first = 4194437, second = 8292, third = 8296, fourth = 0}
  156. (gdb) c
  157. Continuing.
  158.  in the subroutine
  159.  variables = 1, 1, 1, 1
  160.  this = F7FFF840
  161.  
  162. >gt Here is the problem.  The address for subarg is different than the
  163. gt> "this" in the copy constructor which created subarg.  However, the
  164. gt> value F7FFF840 is what gdb had for "this" when in the copy constructor.
  165. gt> The value for subarg used by gdb, 0xf7fff7c8, is wrong as indicated by
  166. gt> value printed by fprintf for that object in printout().
  167.  
  168. Program exited normally.
  169. (gdb) quit
  170.  
  171. So, the problem here is simple to state.  Somehow, when an object is
  172. passed to a subroutine by value, and a copy constructor exists, gdb
  173. evaluates an incorrect address to that object.
  174.  
  175. Thanks for you time,
  176.  
  177. -glenn
  178.  
  179. ------------------------------------------------------------------------
  180. Glenn Tarbox - tarbox@cat.rpi.edu   (518) 276-8367
  181. New York State Center for Advanced Technology in Automation and Robotics
  182. CII-8015, Rensselaer Polytechnic Institute, Troy, NY  12180-3590
  183. ------------------------------------------------------------------------
  184.  
  185. PS: Below is the program code without the numbers so you can take it
  186. directly and play with it.
  187.  
  188. #include <stdio.h>
  189.  
  190. class mytestclass{
  191.   int first, second, third, fourth;;
  192. public:
  193.   mytestclass(){first=second=third=fourth=1;}
  194.   mytestclass(mytestclass &inarg);
  195.   void printout();
  196. };
  197.  
  198. mytestclass::mytestclass(mytestclass &inarg)
  199. {
  200.   (*this)=inarg;
  201.   fprintf(stderr," in the copy constructor\n");
  202.   printout();
  203. }
  204.  
  205. void mytestclass::printout()
  206. {
  207.   fprintf(stderr," variables = %d, %d, %d, %d\n",first,second,third,fourth);
  208.   fprintf(stderr," this = %X\n",(int)this);
  209. }
  210.  
  211. void testsubroutine(mytestclass subarg);
  212.  
  213. main()
  214. {
  215.   mytestclass testone; // create a default object
  216.  
  217.   mytestclass testtwo(testone); // test the copy constructor
  218.  
  219.   testsubroutine(testtwo);
  220. }
  221.  
  222. void testsubroutine(mytestclass subarg)
  223. {
  224.   fprintf(stderr," in the subroutine\n");
  225.   subarg.printout(); // print the object passed by value
  226. }
  227.  
  228.