MS VC 6.0 debugger

Hi,

Is there any way to make MS VC 6.0 debugger stop when it fails during
static variables init?
Currently, I have invalid memory access somewhere in my startup code.
Any guesses/tips?

Thank you,
Giga

Gregory Giguashvili  
Software Engineer  
Email: xxxxx@ParadigmGeo.com  
Tel: 972-9-9709379 Fax: 972-3-9709337  
Paradigm Geophysical Ltd.  
http://www.math.tau.ac.il/~gregoryg

Just wanted to make myself clear:
In Unix, you get a signal (like: SEGV or BUS) and can trap it anytime to
browse process stack.
On NT, the situation is quite different… Is there anything that I can
always stop at during program exit, regardless its’ exit state???

Thanks,
Giga

Giga Giguashvili wrote:

Hi,

Is there any way to make MS VC 6.0 debugger stop when it fails during
static variables init?
Currently, I have invalid memory access somewhere in my startup code.
Any guesses/tips?

Thank you,
Giga

Gregory Giguashvili  
Software Engineer  
Email: xxxxx@ParadigmGeo.com  
Tel: 972-9-9709379 Fax: 972-3-9709337  
Paradigm Geophysical Ltd.  
http://www.math.tau.ac.il/~gregoryg  
 
---  
You are currently subscribed to ntdev as: xxxxx@ParadigmGeo.com  
To unsubscribe send a blank email to $subst('Email.Unsub')  

Gregory Giguashvili  
Software Engineer  
Email: xxxxx@ParadigmGeo.com  
Tel: 972-9-9709379 Fax: 972-3-9709337  
Paradigm Geophysical Ltd.  
http://www.math.tau.ac.il/~gregoryg

On Tuesday 15 August 2000 Gregory Giguashvili wrote:

Is there any way to make MS VC 6.0 debugger stop when it fails during
static variables init?
Currently, I have invalid memory access somewhere in my startup code.
Any guesses/tips?

Try putting something like the following before your static variable
declarations:

#pragma init_seg(compiler)
class CBreak { public: CBreak(){ DebugBreak(); } } initBreak;
#pragma init_seg(user)

MSDN says objects are constructed in the order: those placed in the
“compiler” section, those placed in the “lib” section, finally normal
user objects which are by default placed in the “user” section. The
above should cause a breakpoint at some point before your own
variables are initialized.

John

you gave me something that i could touch in a world where i’d had too much
something i could feel with my broken hands full of lost ideals but soon i’m
returning to you my friend and we’ll go where the rivers end in the silver sea
and i’ll carry you if you carry me

Oh, I can’t:

  1. To much code to traverse.
  2. I have to idea where it fails

I need to see the stack when the trap occures…

Thanks you

John Sullivan wrote:

On Tuesday 15 August 2000 Gregory Giguashvili wrote:
> Is there any way to make MS VC 6.0 debugger stop when it fails during
> static variables init?
> Currently, I have invalid memory access somewhere in my startup code.
> Any guesses/tips?

Try putting something like the following before your static variable
declarations:

#pragma init_seg(compiler)
class CBreak { public: CBreak(){ DebugBreak(); } } initBreak;
#pragma init_seg(user)

MSDN says objects are constructed in the order: those placed in the
“compiler” section, those placed in the “lib” section, finally normal
user objects which are by default placed in the “user” section. The
above should cause a breakpoint at some point before your own
variables are initialized.

John

you gave me something that i could touch in a world where i’d had too much
something i could feel with my broken hands full of lost ideals but soon i’m
returning to you my friend and we’ll go where the rivers end in the silver sea
and i’ll carry you if you carry me


You are currently subscribed to ntdev as: xxxxx@ParadigmGeo.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

Gregory Giguashvili  
Software Engineer  
Email: xxxxx@ParadigmGeo.com  
Tel: 972-9-9709379 Fax: 972-3-9709337  
Paradigm Geophysical Ltd.  
http://www.math.tau.ac.il/~gregoryg

On Tuesday 15 August 2000 you wrote:

Oh, I can’t:

  1. To much code to traverse.

Reasonable, though it is a powerful technique when absolutely nothing
else is working.

The C runtime WinMain/DllMain is actually fairly straightforward once
you’ve deciphered it. A bigger problem is that the static initializer
code is compiler-generated (no source) so you get dumped into
disassembly mode a lot - not everyone’s cup of tea.

  1. I have to idea where it fails

Ah. I thought you knew the point of failure and just couldn’t
breakpoint before it to step through. Fair enough.

In Unix, you get a signal (like: SEGV or BUS) and can trap it anytime to
browse process stack.

Under Win32 you have Structured Exception Handling (SEH) which fills
much the same role as UNIX signals. Each SEH exception has a unique
32-bit code. The equivalent of SIGSEGV is STATUS_ACCESS_VIOLATION
(0xc0000005). (The symbols STATUS_* are defined in WINNT.H.)

Every time an SEH exception is raised you will see a status line
appear in the Developer Studio output window, similar to “First-chance
exception in myprog.exe: 0xC0000005: Access Violation.”. This happens
regardless of any further processing. (0xe04d5343 is the code used by
the MSVC++ throw statement: all throws of C/C++ objects appear as this
SEH code. Interestingly, a C++ catch(type) statement will *only* catch
this SEH code, but a C++ catch(…) statement will catch all
recoverable SEH exceptions, even things like STATUS_ACCESS_VIOLATION.)

If there is a handler installed, then by default it is called and
devstudio takes no further action. If there is no handler installed,
then devstudio will automatically breakpoint. Unfortunately the C
runtime protects static initializer code with a catch-all handler to
ensure graceful termination in that case.

Actually, that fires off a warning bell to do with the code I posted
previously: if a catch-all handler is installed, DebugBreak() may not
work since hard-coded breakpoints are themselves implemented as SEH
exceptions (STATUS_BREAKPOINT, code 0x80000003). The following works
around this, and is necessary for Explorer extensions, some COM
servers, and almost certainly for debugging C runtime startup code:

#pragma init_seg(compiler)
class CBreak { public: CBreak() {
__try { DebugBreak(); }
__except(UnhandledExceptionFilter(GetExceptionInformation())){}
} } initBreak;
#pragma init_seg(user)

You can tell devstudio to *always* breakpoint on a particular
exception by going into Debug->Exceptions…, selecting the exception
that is causing the problem and choosing Stop Always (instead of Stop
if not handled).

The problem here is that this menu is only available during execution
of the debuggee - tricky if you can’t even get to the first line of the
program because of crashes in the startup code!

What you may have to do, is use my code snippet anyway, to force a
breakpoint before static initialization. Then choose
Debug->Exceptions…, Stop Always on the exception that is causing you
problems (probably 0xc0000005, it usually is), then continue
execution. You should now get a breakpoint at the point of failure.

On NT, the situation is quite different… Is there anything that I can
always stop at during program exit, regardless its’ exit state???

Not *every* program exit, no. Most crashes, yes, since they tend to
raise STATUS_ACCESS_VIOLATION a lot of the time. If you have heap
debugging turned on then certain memory corruptions automatically
raise STATUS_BREAKPOINT.

You can attempt to stop at program exit by setting a breakpoint on the
ExitProcess Win32 API, but this is tricky since you i) need to find
its entry-point address, which is different for different
service-packs and operating systems, ii) may not give you a complete
stack backtrace in the case of abnormal termination or if you don’t
have the necessary symbol files installed, and iii) not all process
exits run through ExitProcess (you may want to break on
TerminateProcess, ExitThread, TerminateThread et al.), just most of
them, and they’re not all even initiated within the process that is
dying.

So you generally have to tailor your technique to the particular type
of bug/crash that is occuring.

John

you gave me something that i could touch in a world where i’d had too much
something i could feel with my broken hands full of lost ideals but soon i’m
returning to you my friend and we’ll go where the rivers end in the silver sea
and i’ll carry you if you carry me

You should try WinDBG. It breaks in early on and should allow you to debug
some of this code.

-Andre

Thank you…
I enabled stop on exceptions and it helped…

Regards,
Giga

John Sullivan wrote:

On Tuesday 15 August 2000 you wrote:
> Oh, I can’t:
> 1) To much code to traverse.

Reasonable, though it is a powerful technique when absolutely nothing
else is working.

The C runtime WinMain/DllMain is actually fairly straightforward once
you’ve deciphered it. A bigger problem is that the static initializer
code is compiler-generated (no source) so you get dumped into
disassembly mode a lot - not everyone’s cup of tea.

> 2) I have to idea where it fails

Ah. I thought you knew the point of failure and just couldn’t
breakpoint before it to step through. Fair enough.

> In Unix, you get a signal (like: SEGV or BUS) and can trap it anytime to
> browse process stack.

Under Win32 you have Structured Exception Handling (SEH) which fills
much the same role as UNIX signals. Each SEH exception has a unique
32-bit code. The equivalent of SIGSEGV is STATUS_ACCESS_VIOLATION
(0xc0000005). (The symbols STATUS_* are defined in WINNT.H.)

Every time an SEH exception is raised you will see a status line
appear in the Developer Studio output window, similar to “First-chance
exception in myprog.exe: 0xC0000005: Access Violation.”. This happens
regardless of any further processing. (0xe04d5343 is the code used by
the MSVC++ throw statement: all throws of C/C++ objects appear as this
SEH code. Interestingly, a C++ catch(type) statement will *only* catch
this SEH code, but a C++ catch(…) statement will catch all
recoverable SEH exceptions, even things like STATUS_ACCESS_VIOLATION.)

If there is a handler installed, then by default it is called and
devstudio takes no further action. If there is no handler installed,
then devstudio will automatically breakpoint. Unfortunately the C
runtime protects static initializer code with a catch-all handler to
ensure graceful termination in that case.

Actually, that fires off a warning bell to do with the code I posted
previously: if a catch-all handler is installed, DebugBreak() may not
work since hard-coded breakpoints are themselves implemented as SEH
exceptions (STATUS_BREAKPOINT, code 0x80000003). The following works
around this, and is necessary for Explorer extensions, some COM
servers, and almost certainly for debugging C runtime startup code:

#pragma init_seg(compiler)
class CBreak { public: CBreak() {
__try { DebugBreak(); }
__except(UnhandledExceptionFilter(GetExceptionInformation())){}
} } initBreak;
#pragma init_seg(user)

You can tell devstudio to *always* breakpoint on a particular
exception by going into Debug->Exceptions…, selecting the exception
that is causing the problem and choosing Stop Always (instead of Stop
if not handled).

The problem here is that this menu is only available during execution
of the debuggee - tricky if you can’t even get to the first line of the
program because of crashes in the startup code!

What you may have to do, is use my code snippet anyway, to force a
breakpoint before static initialization. Then choose
Debug->Exceptions…, Stop Always on the exception that is causing you
problems (probably 0xc0000005, it usually is), then continue
execution. You should now get a breakpoint at the point of failure.

> On NT, the situation is quite different… Is there anything that I can
> always stop at during program exit, regardless its’ exit state???

Not *every* program exit, no. Most crashes, yes, since they tend to
raise STATUS_ACCESS_VIOLATION a lot of the time. If you have heap
debugging turned on then certain memory corruptions automatically
raise STATUS_BREAKPOINT.

You can attempt to stop at program exit by setting a breakpoint on the
ExitProcess Win32 API, but this is tricky since you i) need to find
its entry-point address, which is different for different
service-packs and operating systems, ii) may not give you a complete
stack backtrace in the case of abnormal termination or if you don’t
have the necessary symbol files installed, and iii) not all process
exits run through ExitProcess (you may want to break on
TerminateProcess, ExitThread, TerminateThread et al.), just most of
them, and they’re not all even initiated within the process that is
dying.

So you generally have to tailor your technique to the particular type
of bug/crash that is occuring.

John

you gave me something that i could touch in a world where i’d had too much
something i could feel with my broken hands full of lost ideals but soon i’m
returning to you my friend and we’ll go where the rivers end in the silver sea
and i’ll carry you if you carry me


You are currently subscribed to ntdev as: xxxxx@ParadigmGeo.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

Gregory Giguashvili  
Software Engineer  
Email: xxxxx@ParadigmGeo.com  
Tel: 972-9-9709379 Fax: 972-3-9709337  
Paradigm Geophysical Ltd.  
http://www.math.tau.ac.il/~gregoryg