www.digitalmars.com Home | Search | C & C++ | D | DMDScript | News Groups | index | prev | next
Archives

D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger

C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows

digitalmars.empire
digitalmars.DMDScript

c++ - Okay, I'm stumped - Crashing on the first fprintf or fwrite after

↑ ↓ ← SL <shadowlord13 gmail.com> writes:
This is some test code that isn't working:
void freeze ()
{
	printf("Opening [%s]\n", situation_file);
	FILE *fh = fopen(situation_file, "wb");
	if (fh==NULL) return;
	fprintf(fh, "This is a test.\n");
	...
	(There's a bunch of fwrites below there, and eventually an fclose, but 
it's not getting past the fprintf)

What's happening is, the path is correct, the file is being opened fine 
and cleared when it's opened, but it crashes on the fprintf line. (P.S. 
I have 1.7 GB of free HD space, and other programs can write to the HD 
just fine, even the DOS version of this program. I can modify that file 
  in SciTE without any trouble either.

Originally there was no fprintf, and it was crashing on the first fwrite 
- I initially added the fprintf to find out if the crash was due to the 
variable being written (Since it wouldn't be crashing on the fprintf 
line if it was due to the variable).

It's an "Access violation - code c0000005" by the way.

This is that section of code in asm (from the disassembly provided by 
WinDbg):
	image00400000!freeze:
	004037c5 c8040000         enter   0x4,0x0
	004037c9 ff35f0744400 push dword ptr [image00400000!situation_file 
(004474f0)] ds:0023:004474f0=004474dc
	004037cf 686c524400       push    0x44526c
	004037d4 e8c7220300       call    image00400000!printf (00435aa0)
	004037d9 687a524400       push    0x44527a
	004037de ff35f0744400 push dword ptr [image00400000!situation_file 
(004474f0)]
	004037e4 e857220300       call    image00400000!fopen (00435a40)
	004037e9 8945fc           mov     [ebp-0x4],eax
	004037ec 83c410           add     esp,0x10
	004037ef 85c0             test    eax,eax
	004037f1 7502             jnz     image00400000!freeze+0x30 (004037f5)
	004037f3 c9               leave
	004037f4 c3               ret
	004037f5 687d524400       push    0x44527d
	004037fa ff75fc           push    dword ptr [ebp-0x4]
	004037fd e8c22b0300       call    image00400000!fprintf (004363c4)
	00403802 83c408           add     esp,0x8


I can't for the life of me come up with any possible reason why this 
should be opening fine, clearing the file, and then crashing as soon as 
it tries to write something.

So I tried following it into fprintf. Each time it crashed on a call, I 
restarted it, got back to that spot, and stepped into that call, and 
continued until it crashed again, repeating the procedure. This is how 
it went: fprintf called vfprintf which called _pformat which called 
_fputc_nlock which called _flushbu which called setvbuf which called 
malloc, which crashes while calling RTLMultiPool::Alloc
	00437591 8b0d90b74400 mov ecx,[image00400000!RTLMultiPool::pMainHeap 
(0044b790)]
	00437597 e824450000       call   image00400000!RTLMultiPool::Alloc 
(0043bac0)

This was the state when it called RTLMultiPool::Alloc:
eax=00000c4c ebx=0044ab8c ecx=0044dc24 edx=00000001 esi=00000000 
edi=00004000
eip=00437597 esp=0012fc18 ebp=0012fc30 iopl=0         nv up ei pl zr ac 
po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000 
efl=00000256
image00400000!malloc+0x2b:
00437597 e824450000       call   image00400000!RTLMultiPool::Alloc 
(0043bac0)

I didn't follow it beyond there.

A few more things:
1) It can't be an incorrect path; It's successfully opening the file and 
clearing it (I tested by adding some gibberish to the file and saving, 
then running the program. It does indeed open the file and clear it 
before crashing).
2) The file isn't locked, if it were I wouldn't be able to modify it 
from ScITE or other programs, and fopen would have failed.
3) situation_file is correct, it's printf'd so I could make sure of 
that. It's a constant. Oh, and it fopens the same file earlier, and yes, 
it's all successful, and yes, it fcloses it afterwards (I 
double-checked). It doesn't open that file anywhere else in the program.
4) I can even set a breakpoint on the printf("Opening [%s]\n", 
situation_file); line, and when it reaches it, open up that file that 
situation_file refers to in SciTE, type some characters, save it, and 
close it, and check - it was indeed written, nothing prevented it, the 
file definitely isn't locked.

Anyone have any clue WTF is going on? I'm out of ideas.

-SL
Mar 02 2005
↑ ↓ Arjan Knepper <arjan ask.me> writes:
SL wrote:
 This is some test code that isn't working:
 void freeze ()
 {
     printf("Opening [%s]\n", situation_file);
     FILE *fh = fopen(situation_file, "wb");
     if (fh==NULL) return;
     fprintf(fh, "This is a test.\n");
     ...
     (There's a bunch of fwrites below there, and eventually an fclose, 
 but it's not getting past the fprintf)

Tried this code with the latest beta, no problem. What compiler version are you using? What is the target platform? Using static libs or dynamic RTL lib? What is the lib and include path set to? Arjan
Mar 03 2005
↑ ↓ → SL <shadowlord13 gmail.com> writes:
Arjan Knepper wrote:
 SL wrote:
 
 This is some test code that isn't working:
 void freeze ()
 {
     printf("Opening [%s]\n", situation_file);
     FILE *fh = fopen(situation_file, "wb");
     if (fh==NULL) return;
     fprintf(fh, "This is a test.\n");
     ...
     (There's a bunch of fwrites below there, and eventually an fclose, 
 but it's not getting past the fprintf)

Tried this code with the latest beta, no problem. What compiler version are you using? What is the target platform? Using static libs or dynamic RTL lib? What is the lib and include path set to? Arjan

I'm using the latest beta, on windows. I just checked, the function (freeze) works fine near the start of the program, after unfreeze was called, for instance. So something in the program somewhere is screwing something up, but I hadn't thought of any way to find it. Now it occured to me that I can place calls to freeze() in particular places in the code and recompile (normally it's only called at the very end of the program), and attempt to narrow down when the problem first appears. Target platform is windows. As for static libs or dynamic RTL lib, whichever is default. The compile line I'm using is: dmc.exe -ownoctis.exe -DALL -DWINDOWS noctis.cpp noctis-0.cpp noctis-1.cpp noctis-2.cpp win.cpp noctis.def gdi32.lib shell32.lib -mn -5 | more And for the debug build: dmc.exe -L/co/DETAILEDMAP/LINENUMBERS -oD_wnoctis.exe -DALL -DWINDOWS -DDEBUG -D -g noctis.cpp noctis-0.cpp noctis-1.cpp noctis-2.cpp win.cpp dnoctis.def gdi32.lib shell32.lib -mn -5 | more *checks* Lib is [] Include is ["D:\Program Files\Microsoft Visual C++ Toolkit 2003\includ e";"C:\Program Files\Microsoft SDK\include"] Path is [c:\beta\dm\bin;c:\windows\ system32;c:\windows;c:\windows\command] That's odd. Well I was deliberately clearing lib, since DMC was choking if it pointed to the MS SDK for some reason. I hadn't touched include, since it seemed to work. I've set them to point at c:\dm\lib and c:\dm\include now, though I can't test whether it fixes the crash, since it started failing in OTHER places now (before I changed lib and include, actually). Now I can't seem to convince DMC to make this struct two bytes long (and this is apparently causing crashes due to trying to write outside some pvlist arrays, since they're allocated to a specific size in bits, not to a specific number of elements): struct pvlist { Uword polygon_id : 12; Uchar vtxflag_0 : 1; Uchar vtxflag_1 : 1; Uchar vtxflag_2 : 1; Uchar vtxflag_3 : 1; } It's coming out as 4 bytes, or 3 if I do #pragma pack(1). But those bit amounts total 16, so you'd think it would be 2 bytes (It is in BC too). I can't make polygon_id a Uchar, because then the compiler complains that "12 exceeds maximum bit field width of 8 bits." Moving polygon_id after the flags doesn't make the struct any smaller either. Hm. There was another struct with four two-bit variables which was coming out larger than it should have been, but that one started working after I changed each variable's 'type' to Uchar (It was Uword). If I omit the type from polygon_id's declaration (This surprisingly (to me) actually compiles), the thing becomes 5 bytes long. (!) Well I'm hoping this somehow is the reason for the crash in RTLMemory::Alloc.
Mar 03 2005