Bugzilla – Bug 438
Windows: Missing characters in Audacity log when log reaches 30000 characters
Last modified: 2018-08-20 11:45:20 UTC
Created attachment 189 [details] Log file produced in debug mode containing truncated record Steps to reproduce (using either debug or release versions): 1. Open Audacity, generate a chirp of 30 minutes or longer, export it as a wav file, then close Audacity without saving the aup. 2. Open Audacity again, do File/Open to load the wav file just saved, then do File/Check Dependencies. 3. In the "Project Depends on Other Audio Files" dialog that appears, press either "Copy Selected Files" or "Copy All Files (Safer)". 4. Wait until the "Remove dependencies" progress dialog window has completed, then "crash" Audacity, either by stopping it in the VC++ debugger, or terminating the Audacity.exe process in Windows Task Manager. 5. Open Audacity again, where the "Automatic Crash Recovery" dialog will appear, and press the "Recover Projects" button. 6. A "Warning: Problems in Automatic Recovery" dialog will appear, saying "Project check found file inconsistencies during automatic recovery. Select 'Show Log...' in the Help menu to see details." Press "OK" to dismiss this. 7. Do Help/Show Log as the last dialog suggested, and the "Audacity Log" window will appear. 8. In the Audacity Log window, do Log/Save... to save the log to a text file. 9. Examine the log file, and observe numerous lines (one per block file) like this within it: 11:30:39: Warning: Orphan blockfile: 'C:\Users\DAVIDW~1\AppData\Local\Temp\audacity_temp\project30639\e00\d01\e0001153.au' 10. Scan through all these orphan blockfile warnings and you should see a line in the log that has been truncated and overwritten by the next line, like this: 11:30:40: Warning: Orphan blockfile: 'C:\Users\DAVIDW~1\AppData\Local\Temp\audacity_temp\pr11:30:40: Warning: Orphan blockfile: 'C:\Users\DAVIDW~1\AppData\Local\Temp\audacity_temp\project30639\e00\d01\e0001e1b.au' 11. Select the text in the log file from the beginning up until the last character in the truncated line, and paste it into a new file. Open the new file in a text editor that supplies a file size character count (I used notepad++) and you will find it exactly 30000 characters long. 12. Note, if your path to your "audacity_temp" folder is shorter than mine, you may need to generate a longer .wav file in step 1 in order to generate enough blockfile warning messages to hit the 30000 character threshold. 13. If using debug mode, repeat in release mode, or vice versa. You will get a slightly different log file, yet still find the truncation occurs at exactly 30000 characters. Investigation: I have confirmed in the debugger that the truncated string is delivered intact to the call to wxLogWarning at line 1736 of DirManager.cpp: wxLogWarning(_("Orphan blockfile: '%s'"), orphanFilePathArray[i].c_str()); wxLogWarning is declared in c:\wxWidgets-2.8.11\include\wx\log.h, so as far as Audacity is concerned, all buffer limit considerations should be taken care of by wxWidgets, not by Audacity. Because the missing characters got lost in the wxWidgets dll, not in Audacity itself, I did not know how trace them to find out what damage, if any, they might be causing. I did a search in the wxWidgets source code for the number 30000, and found that it appears to be related to a limit alluded to in wxTextCtrl::HasSpaceLimit in wxWidgets file textctrl.cpp.
Artificially creating lots of orphaned block files is just a repeatable way to get a log file greater than 30000 characters. Any other way of creating a large log file would do. Lots of creating new projects, importing tracks, generating tones would also eventually do this, but would probably take much longer to do. Tempting to believe that creating a large log file shares the moonphase characteristics of bug 137, but this can by no means be assumed until we find out where the missing characters are ending up in wxWidgets.
Created attachment 190 [details] Log file produced "normally" by lots of imports still shows problem There is truncation at line 563, at exactly 30000 characters. However I was able to successfully recover the projects saved in the latter part this session, after the 30k threshold in the log file had been hit. So, unsurprisingly really, there doesn't seem to be any demonstrable connection with bug 137. But I would still like to know where wxWidgets puts the missing characters.
If anyone cares... This seems to be a wxWidgets limit; from wxWidgets-2.8.12\src\msw\textctrl.cpp line 2148: bool wxTextCtrl::HasSpaceLimit(unsigned int *len) const { // HACK: we try to automatically extend the limit for the amount of text // to allow (interactively) entering more than 64Kb of text under // Win9x but we shouldn't reset the text limit which was previously // set explicitly with SetMaxLength() // // Unfortunately there is no EM_GETLIMITTEXTSETBYUSER and so we don't // know the limit we set (if any). We could solve this by storing the // limit we set in wxTextCtrl but to save space we prefer to simply // test here the actual limit value: we consider that SetMaxLength() // can only be called for small values while EN_MAXTEXT is only sent // for large values (in practice the default limit seems to be 30000 // but make it smaller just to be on the safe side) WxLogWindow is based (eventually) on wxLogFrame which contains wxTextCtrl *m_pTextCtrl. void wxTextCtrl::SetMaxLength(unsigned long len) { #if wxUSE_RICHEDIT if ( IsRich() ) { ::SendMessage(GetHwnd(), EM_EXLIMITTEXT, 0, len ? len : 0x7fffffff); } else #endif // wxUSE_RICHEDIT { if ( len >= 0xffff ) { // this will set it to a platform-dependent maximum (much more // than 64Kb under NT) len = 0; } ::SendMessage(GetHwnd(), EM_LIMITTEXT, len, 0); } } Since 0x7fffffff = 2147483647 and 0xffff = 65535, I am guessing that the 30k is a platform specified limit, but... under Win7 Debug: wxString efm5; size_t maxStr = efm5.max_size(); maxStr = 4294967295 unsigned int Unicode Unicode Debug is the same. However, if you search MSDN you will run across this: http://msdn.microsoft.com/en-us/library/1h19b39a(v=VS.90).aspx which points out that the max is 32k for file system API and I bet (with some overhead) that is what you see. A partial improvement would be to remove all the stale wxLog... stuff that is stale.