Re: [Harbour] Debugging c code

2010-02-08 Thread Przemysław Czerpak
On Sun, 07 Feb 2010, April White wrote:

Hi,

 Przemek, I want to confirm something. I'm not yet using the new code
 you wrote, so bear with me here.
 If I allocate memory using hb_xgrab_fm() as you suggested before and
 then call p1 = hb_itemNew(p2) if I do not release p1 the line
 reported by FM statistics appears to be where hb_xgrab_fm() is
 called. This is what I believe I am seeing, can you confirm this?

It depends on few different things.
By default when HB_TR_LEVEL is not set to HB_TR_DEBUG
   hb_traceset( HB_TR_FM, szFile, iLine, NULL );
set's the information about file and line used by the nearest call
to hb_xgrab()/hb_xalloc() and after using it it's reset so it can
be used only once.
In such case if you make:

   hb_traceset( HB_TR_FM, MYFILE, 123, NULL );
   ptr = hb_xgrab( 100 );   // use MYFILE:123 set above
   pItem = hb_itemNew( NULL );  // use PROCNAME():PROCLINE()

but if you make:
   hb_traceset( HB_TR_FM, MYFILE, 123, NULL );
   ptr = hb_xgrab( 100 );   // use MYFILE:123
   hb_traceset( HB_TR_FM, MYFILE2, 125, NULL );
   pItem = hb_itemNew( NULL );  // use MYFILE2:125

then 1-st memory block allocated by hb_xgrab()/hb_xalloc()
inside hb_itemNew() will use MYFILE2:125 and next ones (if any)
will use PROCNAME():PROCLINE().

If you set HB_TR_LEVEL to HB_TR_DEBUG then hb_traceset() will
set default file and line number for all blocks until next call
to hb_traceset() or HB_TRACE() message in C code because compiled
into final code HB_TRACE() messages (not stripped but C macrocompiler)
overwrite values set by hb_traceset().

So you described situation which happens when core code is compiled
without HB_TRACE() debug messages (default) and you set HB_TR_LEVEL
envvar to HB_TR_DEBUG.

BTW you can define macro HB_FM_MARKER and use it in your code
before functions which allocates memory:

   #ifdef DEBUG
  #define HB_FM_MARKER hb_traceset( HB_TR_FM, __FILE__, __LINE__, NULL );
   #else
  #define HB_FM_MARKER
   #endif

   [...]

   HB_FM_MARKER
   ptr = hb_xgrab( 100 );
   HB_FM_MARKER
   pItem = hb_itemNew( NULL );

best regards,
Przemek
___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-07 Thread April White
Przemek, I want to confirm something. I'm not yet using the new code you 
wrote, so bear with me here.


If I allocate memory using hb_xgrab_fm() as you suggested before and 
then call p1 = hb_itemNew(p2) if I do not release p1 the line reported 
by FM statistics appears to be where hb_xgrab_fm() is called. This is 
what I believe I am seeing, can you confirm this?


April

--
With my last breath I spit at thee...
'The Wrath of Khan'

___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-03 Thread Viktor Szakáts

On 2010 Feb 3, at 03:56, Xavi wrote:

 To Viktor,
 
 El 03/02/2010 0:09, Viktor Szakáts escribió:
 for GPF at application startup caused by accessing TSD before HVM
 stack is initialized. It seems to work though it can be greatly
 simplified and of course the GPF in startup code and non HVM threads
 has to be fixed.
 That pretty much sums up what I didn't like about the
 implementation without even knowing the exact details
 (I'd have bet that MT mode had problems f.e.)
 
 That's great!. No Comments. :-)

Next time maybe you should post your patch instead of 
hiding it, so no guessing is required based on past work!

Brgds,
Viktor

___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-02 Thread marco bra
To get the support (or to report bug) about your Ubuntu issue please refer
to the main  https://launchpad.net/ubuntu Ubuntu site, be free to ask any
kind of question here: https://answers.launchpad.net/ubuntu

Hth
___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-02 Thread Przemysław Czerpak
On Mon, 01 Feb 2010, Xavi wrote:

Hi,

 HB_TRACEFM(), with my next commit. I'm waiting for Przemek and others
 are ready. ;)

Can you send .diff file here so we can check what exactly this
modification does?

 Is there a macro I can use to identify this sub-function? I could leave
 it in the code wrapped conditional code for debug only.
 Yes if you have a C99 compiler, just have to redefine the macro in your code 
 .-
 #ifdef HB_TRACEFM
 #  undef  HB_TRACEFM
 #  define HB_TRACEFM( x )  hb_fm_xInfoEx( #x, __FILE__, __LINE__, __func__ ); 
 x
 #endif

We do not have hb_fm_xInfoEx() in our code so I guess it's part of
modifications you want to commit. __func__ is C99 macro. It makes
log more readable but __FILE__ + __LINE__ is enough to detect exact
place and function name if you have source code so it's not critical
information. For current unmodified code requested functionality
(without function name) can be reached by:
   extern HB_EXPORT void * hb_xgrab_fm( ULONG ulSize,
const char * szFile, int iLine );
   [...]
   void * hb_xgrab_fm( ULONG ulSize, const char * szFile, int iLine )
   {
  hb_tr_file_ = szFile;
  hb_tr_line_ = iLine;
  return hb_xgrab( szFile );
   }

   #if HB_TR_LEVEL = HB_TR_DEBUG
  #define HB_XGRABFM( n )hb_xgrab_fm( n, __FILE__, __SIZE__ )
   #else
  #define HB_XGRABFM( n )hb_xgrab( n )
   #endif

with most of C compilers the same effect can be reached using only
macros without hb_xgrab_fm() function, i.e.:

   #if HB_TR_LEVEL = HB_TR_DEBUG
  #define HB_XGRABFM( n )( hb_tr_file_ = __FILE__, \
   hb_tr_line_ = __LINE__, \
   hb_xgrab( n ) )
   #else
  #define HB_XGRABFM( n )hb_xgrab( n )
   #endif

If user wants does not want to set HB_TR_LEVEL=DEBUG then the
above macro can be extend to dynamically change and restore
debug level, i.e.:

   #if HB_TR_LEVEL = HB_TR_DEBUG
  #define HB_XGRABFM( n ){ int iLevel = hb_tracelevel( HB_TR_DEBUG ); \
   void * ptr; \
   hb_tr_file_ = __FILE__; \
   hb_tr_line_ = __LINE__; \
   ptr = hb_xgrab( n ); \
   hb_tracelevel( iLevel ); \
   ( void ) ptr; }
   #else
  #define HB_XGRABFM( n )hb_xgrab( n )
   #endif

anyhow such version can be compiled only by few C compilers, i.e. by GCC.
To make it simpler we can change a little bit fm.c and HB_TRACE_STEALTH()
macro so user can use the first version independently to HB_TR_LEVEL setting.
BTW such modifications in HB_TRACE_STEALTH() macro should be done also to
fix yet another problem in current code so I'll commit them ASAP.

best regards,
Przemek
___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-02 Thread Przemysław Czerpak
On Tue, 02 Feb 2010, Xavi wrote:

Hi,

 Thank you Przemek. It's not so easy because these solutions don't
 work with C++ new operator.

If you want to include memory allocated by C++ code to FM static
then it's necessary to overload new and delete operators and redirect
them to hb_xgrab()/hb_xfree(). hbmk2 has an option to enable such
overloading. Anyhow C preprocessor is too week to automatically insert
instruction which can safe __FILE__ and __LINE__ values so it cannot
be cleanly done. Using macros like HB_TRACEFM( x ) you send is not
solution too because in C++ code NEW/DELETE operators can be executed
indirectly. I.e.:
   {
  my_type x;
  f( x );
   }
can activate code constructor and destructors which executes indirectly
some other code which can allocated new memory. To correctly set file
and line information in such code you will have to make sth like:
   {
  HB_TRACEFM( my_type x );  // this code is illegal in ANSI C mode !!!
  HB_TRACEFM( f( x ) );
  HB_TRACEFM( )  // dummy call to set valid line and file info for
 // destructors which also can allocate some memory
   }

In fact for real C++ code using extensively constructors and destructors
you will have to enclose nearly _each_ line of code inside HB_TRACEFM()
so for me HB_TRACEFM() isn't reasonable solution, too.

Please also note that:
  HB_TRACEFM( my_type x );
just like:
  HB_TRACEFM( void * ptr = hb_xgrab( 100 ) );
generates in hidden way code which is not ANSI C compatible what creates
yet another problem.

Instead of using such HB_TRACEFM() macro I suggest to simply define
macro which will set file and line number for FM module, i.e.:

   #define HB_TR_SET_CREATE(l)  do { \
   hb_tr_level_ = l; \
   hb_tr_file_ = __FILE__; \
   hb_tr_line_ = __LINE__; \
} while( 0 )

   #if HB_TR_LEVEL = HB_TR_DEBUG
  #define HB_TR_SET_HB_TR_DEBUG() HB_TR_SET_CREATE(HB_TR_DEBUG)
   #else
  #define HB_TR_SET_HB_TR_DEBUG()
   #endif
   [...]
   #if 1  /* always! */
  #define HB_TR_SET_HB_TR_ALWAYS()HB_TR_SET_CREATE(HB_TR_ALWAYS)
   #else
  #define HB_TR_SET_HB_TR_ALWAYS()
   #endif

   #define HB_TR_SET(l)   HB_TR_SET_##l()

so user can mark any place in his code before calling hb_xgrab()
or activating any other code which may allocates new memory by simple
adding HB_TR_SET( HB_TR_DEBUG ); i.e.

   HB_TR_SET( HB_TR_DEBUG );  // code marker, store file and line info
   ptr = hb_xgrab( 100 );

In such version it's explicitly visible for users what such macros does
and which lines will be reported by FM statistic module.
And if you still prefer HB_TRACEFM() then you can simply define in your
code:
   HB_TRACEFM( x )  HB_TR_SET( HB_TR_ALWAYS ); x

In the code you created you are storing with each memory block also
the code inside HB_TRACEFM() macro ( #x ) in the 264 bytes buffer
attached to each memory block. For me it seems to be redundant. Having
file name and line number is enough to check the exact code so it does
not give any new functionality but increase the overhead created by
FM statistic module reducing the speed and increasing total memory
usage. I agree that final FM log looks nicer with such feature but
personally I do not think that such reason is important enough. Anyhow
this are only my personal feelings so it should be rather group
decision. If other developers things that it's important to attach
text with source code inside HB_TRACEFM() macro to each memory block
allocated by FM statistic module to report such lines in fm.log file
and agree to accept slowness and additional memory overhead because
information about source file name and line number is not enough
then we can add it.

 Attache files ready for committed, I've taken care to preserve intact
 the largest existing code as possible.
 Please, you can review especially in MT mode. I've tried it with
 success in a large multi-threaded application without conflict or
 deadlock but maybe I missed something and I don't know force the
 error.

I see that you used TSD structure allocated on HVM stack to make it
MT safe. But it creates one serious problem. It means that it's
not possible to activate this code before HVM stack is created
by application startup code and it's not possible to use hb_xgrab()
by non HVM threads. I only guess that this trick with s_pInfoEx
which makes it much more complicated then necessary is workaround
for GPF at application startup caused by accessing TSD before HVM
stack is initialized. It seems to work though it can be greatly
simplified and of course the GPF in startup code and non HVM threads
has to be fixed.

In general whole HB_TRACE() module should be fixed to be MT safe.
Unfortunately it can be cleanly done without any TSD/TLS variables
only using C99 macros :-(.
Anyhow it systematically begins to be bigger problems so I'll 

Re: [Harbour] Debugging c code

2010-02-02 Thread Viktor Szakáts
To Xavi and All,

 Thank you Przemek. It's not so easy because these solutions don't
 work with C++ new operator.
 
 If you want to include memory allocated by C++ code to FM static
 then it's necessary to overload new and delete operators and redirect
 them to hb_xgrab()/hb_xfree(). hbmk2 has an option to enable such
 overloading. Anyhow C preprocessor is too week to automatically insert
 instruction which can safe __FILE__ and __LINE__ values so it cannot
 be cleanly done. Using macros like HB_TRACEFM( x ) you send is not
 solution too because in C++ code NEW/DELETE operators can be executed
 indirectly. I.e.:
   {
  my_type x;
  f( x );
   }
 can activate code constructor and destructors which executes indirectly
 some other code which can allocated new memory. To correctly set file
 and line information in such code you will have to make sth like:
   {
  HB_TRACEFM( my_type x );  // this code is illegal in ANSI C mode !!!
  HB_TRACEFM( f( x ) );
  HB_TRACEFM( )  // dummy call to set valid line and file info for
 // destructors which also can allocate some memory
   }
 
 In fact for real C++ code using extensively constructors and destructors
 you will have to enclose nearly _each_ line of code inside HB_TRACEFM()
 so for me HB_TRACEFM() isn't reasonable solution, too.
 
 Please also note that:
  HB_TRACEFM( my_type x );
 just like:
  HB_TRACEFM( void * ptr = hb_xgrab( 100 ) );
...
 generates in hidden way code which is not ANSI C compatible what creates
 yet another problem.
 
 Instead of using such HB_TRACEFM() macro I suggest to simply define
 macro which will set file and line number for FM module, i.e.:
 
   #define HB_TR_SET_CREATE(l)  do { \
   hb_tr_level_ = l; \
   hb_tr_file_ = __FILE__; \
   hb_tr_line_ = __LINE__; \
} while( 0 )
 
   #if HB_TR_LEVEL = HB_TR_DEBUG
  #define HB_TR_SET_HB_TR_DEBUG() HB_TR_SET_CREATE(HB_TR_DEBUG)
   #else
  #define HB_TR_SET_HB_TR_DEBUG()
   #endif
   [...]
   #if 1  /* always! */
  #define HB_TR_SET_HB_TR_ALWAYS()HB_TR_SET_CREATE(HB_TR_ALWAYS)
   #else
  #define HB_TR_SET_HB_TR_ALWAYS()
   #endif
 
   #define HB_TR_SET(l)   HB_TR_SET_##l()
 
 so user can mark any place in his code before calling hb_xgrab()
 or activating any other code which may allocates new memory by simple
 adding HB_TR_SET( HB_TR_DEBUG ); i.e.
 
   HB_TR_SET( HB_TR_DEBUG );  // code marker, store file and line info
   ptr = hb_xgrab( 100 );
 
 In such version it's explicitly visible for users what such macros does
 and which lines will be reported by FM statistic module.
 And if you still prefer HB_TRACEFM() then you can simply define in your
 code:
   HB_TRACEFM( x )  HB_TR_SET( HB_TR_ALWAYS ); x
 
 In the code you created you are storing with each memory block also
 the code inside HB_TRACEFM() macro ( #x ) in the 264 bytes buffer
 attached to each memory block. For me it seems to be redundant. Having
 file name and line number is enough to check the exact code so it does
 not give any new functionality but increase the overhead created by
 FM statistic module reducing the speed and increasing total memory
 usage. I agree that final FM log looks nicer with such feature but
 personally I do not think that such reason is important enough. Anyhow
 this are only my personal feelings so it should be rather group
 decision. If other developers things that it's important to attach
 text with source code inside HB_TRACEFM() macro to each memory block
 allocated by FM statistic module to report such lines in fm.log file
 and agree to accept slowness and additional memory overhead because
 information about source file name and line number is not enough
 then we can add it.
 
 Attache files ready for committed, I've taken care to preserve intact
 the largest existing code as possible.
 Please, you can review especially in MT mode. I've tried it with
 success in a large multi-threaded application without conflict or
 deadlock but maybe I missed something and I don't know force the
 error.
 
 I see that you used TSD structure allocated on HVM stack to make it
 MT safe. But it creates one serious problem. It means that it's
 not possible to activate this code before HVM stack is created
 by application startup code and it's not possible to use hb_xgrab()
 by non HVM threads. I only guess that this trick with s_pInfoEx
 which makes it much more complicated then necessary is workaround
 for GPF at application startup caused by accessing TSD before HVM
 stack is initialized. It seems to work though it can be greatly
 simplified and of course the GPF in startup code and non HVM threads
 has to be fixed.

That pretty much sums up what I didn't like about the 
implementation without even knowing the exact details 
(I'd have bet that MT mode had problems f.e.)

And while I liked 

Re: [Harbour] Debugging c code

2010-02-02 Thread April White
Thank you Przemek.  I've tried your suggestion but my implementation 
does not work as expected, the stats output is:


   fm.c:1134: HB_TR_ERROR Block 1 (size 40) HB_BTREEINSERT(0), 
F8A454004001550058D

   C4B00010001001000F03F0A000200

But I know the memory allocation is in a sub-function.

My implementation is different from yours but keeps the spirit.  I added 
some debug code not shown below so I know it is compiling this code and 
executing it.  My system is:


WinXP SP2
MinGW32 from Qt installer
HB_USER_CFLAGS to compile harbour:
   -O3 -Wall -Wunused-variable -Wpointer-arith -DHB_FM_STATISTICS
HB_USER_CFLAGS to compile this project:
   -O3 -Wall -Wunused-variable -Wpointer-arith -DHB_FM_STATISTICS 
-DHB_TR_LEVEL=5


My existing code already uses a local function to memory allocation, a 
wrapper for hb_xgrab() or hb_xrealloc().


#if HB_TR_LEVEL = HB_TR_DEBUG

#define BufferAlloc(n)  hb_xgrab_fm( NULL, (n), __FILE__, __LINE__ )
#define BufferRealloc(p,n)  hb_xgrab_fm( (p), (n), __FILE__, __LINE__ )

extern HB_EXPORT void * hb_xgrab_fm( void *buffer, ULONG ulSize, const 
char * szFile, int iLine )

{
  void *tmpBuffer;
  hb_tr_file_ = szFile;
  hb_tr_line_ = iLine;
  tmpBuffer = buffer ? hb_xrealloc( buffer, ulSize ) : hb_xgrab( ulSize );
  return tmpBuffer;
}

#else
...
#endif






--
Without facts, the decision cannot be made logically. You must rely on your 
human intuition.
- Spock, 'Assignment: Earth', stardate unknown

___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-02 Thread Przemysław Czerpak
On Tue, 02 Feb 2010, April White wrote:

Hi,

 Thank you Przemek.  I've tried your suggestion but my implementation
 does not work as expected, the stats output is:
fm.c:1134: HB_TR_ERROR Block 1 (size 40) HB_BTREEINSERT(0),
 F8A454004001550058D
C4B00010001001000F03F0A000200
 But I know the memory allocation is in a sub-function.

You haven't set DEBUG tracing level. You can do that setting
HB_TR_LEVEL envvar, i.e.:
   export HB_TR_LEVEL=HB_TR_DEBUG
or in DOS/Windows:
   set HB_TR_LEVEL=HB_TR_DEBUG

Just try.

I'll commit in a while modifications which allow to eliminate
setting HB_TR_LEVEL using HB_TR_FM message level.
You will have to modify your code to:

   void * hb_xgrab_fm( void *buffer, ULONG ulSize,
   const char * szFile, int iLine )
   {
  hb_traceset( HB_TR_FM, szFile, iLine, NULL );
  return hb_xrealloc( buffer, ulSize );
   }

You can use hb_xrealloc( NULL, ulSize ) to allocate memory so you do not
need additional condition in hb_xgrab_fm() function.

best regards,
Przemek
___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-02 Thread Xavi

To Viktor,

El 03/02/2010 0:09, Viktor Szakáts escribió:

for GPF at application startup caused by accessing TSD before HVM
stack is initialized. It seems to work though it can be greatly
simplified and of course the GPF in startup code and non HVM threads
has to be fixed.

That pretty much sums up what I didn't like about the
implementation without even knowing the exact details
(I'd have bet that MT mode had problems f.e.)


That's great!. No Comments. :-)

Best regards,
Xavi
___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-01 Thread Xavi

Hi April,

HB_TRACEFM(), with my next commit. I'm waiting for Przemek and others are 
ready. ;)


Is there a macro I can use to identify this sub-function? I could leave
it in the code wrapped conditional code for debug only.


Yes if you have a C99 compiler, just have to redefine the macro in your code .-

#ifdef HB_TRACEFM
#  undef  HB_TRACEFM
#  define HB_TRACEFM( x )  hb_fm_xInfoEx( #x, __FILE__, __LINE__, __func__ ); x
#endif

Best regards,
Xavi

El 01/02/2010 4:00, April White escribió:

When my C level code does not release memory, the fm statistics reports
this but gives the public function though in some cases the allocation
occured in a sub-function.

Is there a macro I can use to identify this sub-function? I could leave
it in the code wrapped conditional code for debug only.

April


___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


Re: [Harbour] Debugging c code

2010-02-01 Thread Viktor Szakáts
Hi,

 HB_TRACEFM(), with my next commit. I'm waiting for Przemek and others are 
 ready. ;)
 
 Is there a macro I can use to identify this sub-function? I could leave
 it in the code wrapped conditional code for debug only.
 
 Yes if you have a C99 compiler, just have to redefine the macro in your code 
 .-
 
 #ifdef HB_TRACEFM
 #  undef  HB_TRACEFM
 #  define HB_TRACEFM( x )  hb_fm_xInfoEx( #x, __FILE__, __LINE__, __func__ ); 
 x
 #endif

Sorry, I still don't like it in its current form, 
pls could post the complete patch for review if possible.

Brgds,
Viktor

___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


RE: [Harbour] Debugging c code

2010-02-01 Thread April White

You may recall my email from about a week ago about my Ubuntu machine.  I'm 
(re)installed 9.10 with the same results that it does not boot.  I do not know 
enough about linux / ubuntu to know whether it is a bug or a hardware failure.  
Because the installation has no failures it says to me it is a bug not hardware.

Thank you!

April

p.s.  I've found a work around for the runtime error in the btree code, but I 
do not know 'why' is it happening.  More work to do.


 Subject: Re: [Harbour] Debugging c code
 From: harbour...@syenar.hu
 Date: Mon, 1 Feb 2010 16:10:00 +0100
 To: harbour@harbour-project.org
 
 Hi April,
 
 Under Ubuntu you can use valgrind to find out the exact locations 
 of leaked allocations. Check the debugging section in INSTALL.

 On 2010 Feb 1, at 04:00, April White wrote:
 
  When my C level code does not release memory, the fm statistics reports 
  this but gives the public function though in some cases the allocation 
  occured in a sub-function.  
  
  Is there a macro I can use to identify this sub-function?  I could leave it 
  in the code wrapped conditional code for debug only.  
  
  April
  ___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour


[Harbour] Debugging c code

2010-01-31 Thread April White
When my C level code does not release memory, the fm statistics reports this 
but gives the public function though in some cases the allocation occured in a 
sub-function.  

Is there a macro I can use to identify this sub-function?  I could leave it in 
the code wrapped conditional code for debug only.  

April
  ___
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour