How to use .map file to locate line that crashes

Started by allynm, May 06, 2011, 01:54:51 AM

Previous topic - Next topic

dedndave

that's symantics, in a way
it is the same as loading _DATA (or whatever you name the segment)
normally, that is the first segment in DGROUP
so, it's probably the same as loading DGROUP
however, if segments are out of order, then things can go haywire - lol
the GROUP mechanism is provided so that you can get the base of the group of segments
(so that you may access more than one segment without switching registers)

the linenumbers thing is documented in the ibm basic compiler (v1.0) manual   :P
what ? - you don't have a copy ?   :eek

(probably in the orignal ibm fortran compiler manual, too)

allynm

Hi 'Dave,

Despite my advanced age and the fact that I once-upon-a-time programmed 360/65 with a deck of JCL and fortran cards, and despite the fact that these programs routinely bombed and I had to go to a systems programmer who picked through a .map file and never quite explained what he was looking at but invariably found the screwed-up code line, I do not have a copy of the ibm book you mentioned.

Yet another instance of my lack of foresight.

As you surmised....

Yes, indeed, if the user data is actually in the _data segment, then what Red' did works just fine.  As you say, if it ain't there, it won't work---as we have found.  Ferinstance, if it is in DSEG.

Regards,
Mark

FORTRANS

Quote from: allynm on May 07, 2011, 12:39:08 PM
I roughly follow what you are saying the third paragraph.  I would like to see a real example of what you describe.  Problem is---just as you say---getting a program to fail with the failure address produced.  Otherwise you have to "step" through it the way you and 'Dave discuss.

Hi Mark,

   Okay.  I deliberately crashed a program by sticking an undefined
opcode in the program to cause a trap that would kill the session.
I used:

>  0x0F 0x0B UD2 Intel Undefined opcode 2

which generated a trap caught by the OS/2 VDM as an error
at CS:EIP 19f1:000001a2.  Looking in the listing at address
01A2, I see it is line 88 and the undefined opcode 2 that
caused the trap.  As shown in the following snippet.


      84 019B  BA 0103 R         MOV     DX,OFFSET str1  ; load address str1
      85 019E  B4 09         MOV     AH,9            ; DOS Print String to console
      86 01A0  CD 21         INT     21H             ; DOS syscall
      87
      88 01A2  0F 0B         DB      0FH, 0BH
      89 01A4  33 C0         XOR     AX,AX


   A Windows 2000 Command Prompt also caught it with a
similar message:

16 Bit MS-DOS Subsystem
Command Prompt - examp3
The NTVDM has encountered an illegal instruction
CS:068b IP:01a2 OP:0f 0b 33 ...

   As you can see the CS changed, but IP has the same value.

   Does that help?  BTW I tried a divide by zero error, but
that just displayed a message and stopped the program.

Steve N.

jj2007

This works...

Quote.Model small   ; credits to DednDave
.Stack 512

sofar MACRO arg
   pushad
   mov dx, offset ec&arg&
   mov ah, 9
   int 21h
   popad
ENDM

.Data
MsgText   db "Hello 16-bit World", 13, 10, 10
   db "Hit any key to quit ...", 13, 10, "$"

eca   db "A", 13, 10, "$"
ecb   db "B", 13, 10, "$"
ecc   db "C", 13, 10, "$"

.Code

_main proc FAR

; set the DS register to DGROUP (will fail with some Masm versions - use ml 6.15 or higher, or JWasm)
   mov ax, @DATA
   mov ds, ax
   sofar a

; display the message
   mov dx, offset MsgText
   sofar b
   mov ah, 9
   int 21h

; wait for a key
   mov ah, 0
   sofar c
   int 16h

; the DOS equivalent to ExitProcess
   mov ax, 4C00h
   int 21h

_main endp

end _main

redskull

Quote from: allynm on May 07, 2011, 12:39:08 PM
It's hard to find any info on /linenumbers, at least nowadays.  Red's command line uses the /Zd switch for the ml.  I have found that you do not need to set this switch to get the linenumbers.

I'm not sure anyone knows the real answer to the difference between /Zi and /Zd.  I recall going around a few times to try and see what difference they make, and didn't find any.  However, I always include them both just to be safe.  Just remember it's a two step process: you have to get the assembler to put the info into the OBJ file, and then the linker to put it in the exe/map/pdb/dbg.  Also, FWIT, there is also a /CODEVIEW switch which makes codeview style debugging information (if you can get codeview to work).

But like Steve said, there's any number of places it can crash apart from just "your" code; a bad argument will crash inside the call to the INT, a branch to a bad pointer might crash somewhere inside the .DATA section, and infinite loops won't crash at all.  You have to work backwards from the stack trace to decipher the seminal cause.  But these are things that are common to 16-bit and 32-bit.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

allynm

Hi Steve, JJ, & Redskull,

Steve, thanks.  The example is EXACTLY what I was seeking.  Very clear.  All of this makes one appreciate the virtue of GetLastError!

JJ- Very nice job.  It's a nice template.

RedSkull-  Regarding codeview---yes, I have been using codeview and setting the switch.  As you say, CV is not particularly user-friendly but a whole lot more friendly than Windbg!  The version I use comes with Masm 6.15.  Seems to work OK, just hard to use.

Regards.

Mark