c++ - Okay, I'm stumped - Crashing on the first fprintf or fwrite after
- SL (84/84) Mar 02 2005 This is some test code that isn't working:
- Arjan Knepper (5/15) Mar 03 2005 Tried this code with the latest beta, no problem.
- SL (52/72) Mar 03 2005 I'm using the latest beta, on windows. I just checked, the function
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
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
Arjan Knepper wrote:SL wrote: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.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