[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decladebug

Title:Digital Ladebug debugger
Moderator:TLE::LUCIA
Created:Fri Feb 28 1992
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:969
Total number of notes:3959

808.0. "How to set a breakpoint at a line in a C++ template function???" by GALVIA::STONES (Tom Stones) Tue Feb 04 1997 04:41

This note was entered in TURRIS::C_PLUS_PLUS - note 3422.

I'm having trouble setting a breakpoint at a particular line in a member
function of a template class.

Here's what happened with a shortened version of my code:
[ I also tried
  (ladebug) set $overloadmenu=1
  and
  (ladebug) class Cache_t<EpMcMapEntry_t>
  and
  I tried qualifying the line number in the same way as ladebug does:
  stopped at [int Cache_t<EpMcMapEntry_t>::MoreEntries(void):11 0x1200029b8]
  (ladebug) stop in Cache_t<EpMcMapEntry_t>::MoreEntries(void):27

  None of these do the trick.   Is there a way of doing this?
]


zen> cxx -g main.cxx cache.cxx -I.
main.cxx:
cache.cxx:
zen> ladebug a.out
Welcome to the Ladebug Debugger Version 4.0-19
------------------
object file name: a.out
Reading symbolic information ...done
(ladebug) bp main
[#1: stop in int main(void) ]
(ladebug) r
[1] stopped at [int main(void):6 0x120002418]
      6   Cache_t<int> tcc;
(ladebug) s
stopped at [Cache_t<int>::Cache_t<int>(void):31 0x1200023e0]
     31   Cache_t() { MoreEntries();}
(ladebug) s
stopped at [int Cache_t<int>::MoreEntries(void):6 0x120002318]
      6 int  Cache_t<CACHE_DATA_T>::MoreEntries() {
(ladebug) l
      7         int i;
      8         printf("inside MoreEntries\n");
      9         i = 99;
     10         return 0;
     11    }
     12
(ladebug) b 9
Warning: More than one file named './cache.cxx' found in the binary.
Warning: Breakpoint not set
(ladebug) q



Here's the code:

//main.cxx
#include <cache.h>
void  main() {
  Cache_t<int> tcc;
  Cache_t<char> tbc;
  Cache_t<float> rbc;
}


// cache.cpp
#include <stdio.h>
#include "cache.h"

template<class CACHE_DATA_T>
int  Cache_t<CACHE_DATA_T>::MoreEntries() {
        int i;
        printf("inside MoreEntries\n");
        i = 99;
        return 0;
   }


// cache.h
#ifndef CACHE_
#define CACHE_

template<class CACHE_DATA_T>
class Cache_t {
private:
  struct Entry_t {
    CACHE_DATA_T data;
    Entry_t      *nextEntry;
  };

  //Entries are allocated in blocks.
  struct CbListEntry_t{
    void *cacheblock;
    CbListEntry_t *nextCbListEntry;
  };

  Entry_t *firstEntry;
  Entry_t *freeEntry;
  CbListEntry_t  cb;

  //MoreEntries - Allocates space for cache entries and updates freeEntry.
  //Returns 1 if one or more entries added to free list.
  //Returns 0 if no memory.
  int MoreEntries();

public:

  //Constructor.
  Cache_t() { MoreEntries();}

};
#endif
T.RTitleUserPersonal
Name
DateLines
808.1...GALVIA::STONESTom StonesMon Feb 10 1997 09:573
I still have this problem with ladebug V4.0-30

Tom.
808.2This problem is not template specificTLE::MERRITTSteve Merritt, Ladebug TeamTue Feb 18 1997 11:0453
I looked into this problem and here are some of the things I found.
The good news is that if you can get the symbolic information for the
header file to show up only once in the binary, Ladebug will allow you
to set a breakpoint at a given line in that header file.  In this regard,
this problem is not template specific.  Ladebug will have problems
handling any file within the binary being debugged if the symbolic 
information for that file is in more than one place in the binary.

Here is the template specific problems I found.  Multiple instances of
the header file are likely to be found in the binary if that header file
declares more than one template.  In addition, if the member functions of 
the templates are placed in a corresponding .C file, you will end up with
multiple copies of the symbolic info for the .C file as well.  This may
not happen in all cases, but it happened in the examples I tried.

The other point to consider when trying to debug code in header files is
that most functions defined in header files are trival.  As such, even 
if the symbolic info for the file only shows up once, the functions
are likely to be optimized away.  If they get optimized away, there is
minimal symbolic info available and hence you will not be able to see
whats going on inside the function from the debugger.  When compiling 
with -g, the user can limit optimizations by specifying -O0 (-O1 is the 
default), but even this is no guarantee that a function will not be 
optimized away.

All of this presents a big problem to the developer using templates.
Those developers using third party template libraries are pretty much
out of luck in trying to solve this problem.  However, if the template
being debugged is one the developer can modify, then there is something
that can be tried.

I have found that if template declarations are limited to one per
header file, there is a good chance that the symbolic information for 
this file will be included in the binary only once.  If this doesn't 
work, the second step is to move template member function definitions 
to a .C file since the symbolic info for .C files is much less like to 
be repeated.  Obviously these suggestions will be impractical for a 
large portion of our customers.

Without modifying the code, the only way to debug template member
functions is to use 'stop in <func>'.  This has its limitations and
the user may still have trouble viewing whats going on because of the
multiple file problem.  Ladebug commands such as 'class foo' and 'set
$overloadmenu=1' don't operate at the file level and thus offer no help
in resolving the multiple file problem.

The solution to this problem is to address the root cause, namely stop
the production of multiple instances of the same file from being output 
in the symbolic information of a binary.  



-Steve
808.3ADA9X::BRETTTue Feb 18 1997 15:2923
> The solution to this problem is to address the root cause, namely stop
> the production of multiple instances of the same file from being output
> in the symbolic information of a binary.

Or teach ladebug how to deal with it.  This goes back to a very fundamental
flaw in the design on Unix debuggers.  There is NO reason in C or C++
why the following code is illegal or immoral...

	#define FOO some_variable
	#include "some-file.h"
	#undef FOO

	#define FOO some_different_variable
	#include "some-file.h"
	#undef FOO

and indeed I can point you to significant non-Digital C code written this way.

We need to learn to deal with it, not to sweep the problem under the "but I
don't like it when you to program that way" mat.

/Bevin
808.4GALVIA::STONESTom StonesFri Feb 21 1997 05:203
Instead of refusing to set the breakpoint, could ladebug give me the option of
setting the breakpoint at all addresses that correspond to the line I'm
interested in? 
808.5ADA9X::BRETTFri Feb 21 1997 07:426
I checked out Visual C++ 4.0 last night.

It sets the breakpoints in all the instances, and in all the occurrences of the
include file.

/Bevin
808.6TLE::MURRAYWanfang MurrayMon Feb 24 1997 07:169
    
    This problem is a side-effect of mergeable and non-mergeable stuff.
    So, your request is to have ladebug to set breakpoints on all 
    instances, right?
    
    Will this problem be fixed with your new changes in the object
    file?  
    
    Wanfang
808.7ADA9X::BRETTMon Feb 24 1997 13:1530
> This problem is a side-effect of mergeable and non-mergeable stuff.

Which makes ladebug think the file has been included twice when it has only
been included once, I presume?


> So, your request is to have ladebug to set breakpoints on all instances,
> right?

There is only ONE instance.  I suspect ladebug is getting confused because
it believes what has happened is

	one include, with one routine definition

got split into
	one include, mergeable, with no routine definition
	one include, non-mergeable, with one routine definition

and then ladebug looked for the file name and couldn't decide where to go,
even though only one path would have worked?


> Will this problem be fixed with your new changes in the object file?

No, since it also happens with C and my fixes are for C++.  Mergeability seems
to be ok with C.


/bevin