Skip to content

Flush logs when crashing.#21517

Merged
PunkPun merged 1 commit into
OpenRA:bleedfrom
RoosterDragon:flush-logs
Aug 16, 2024
Merged

Flush logs when crashing.#21517
PunkPun merged 1 commit into
OpenRA:bleedfrom
RoosterDragon:flush-logs

Conversation

@RoosterDragon

@RoosterDragon RoosterDragon commented Aug 3, 2024

Copy link
Copy Markdown
Member

When the process is running, we use a finally block to call Log.Dispose and flush any outstanding logs to disk before the process exits. This works when we handle any exception in a matching catch block.

When the exception is unhandled, then the finally block will not run and instead the process will just exit. To fix this, flush the logs inside a catch block instead before rethrowing the error. This ensures we get logs even when crashing.

Fixes #20733

@PunkPun PunkPun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't seem to have fixed the issue. For instance I run

make; ./utility.sh ra --png a a

and after crashing the utility.log is still zero bytes

@RoosterDragon

Copy link
Copy Markdown
Member Author

Fair. I've unlinked the utility ticket. This does fix the debugger case for sure, so must be something else going on with that one.

@RoosterDragon RoosterDragon changed the title Flush logs when crashing under a debugger. Flush logs when crashing. Aug 5, 2024
@RoosterDragon

Copy link
Copy Markdown
Member Author

Applying this same fix across all our Main entrypoints does the job. Relinked the ticket about fixing the utility.

@anvilvapre

Copy link
Copy Markdown
Contributor

So i was curious why it would not end up logged. The cause is that top level exception are not caught.

Looking at the stack trace the program is aborted - on my system even a core is dumped. The final clause is never reached.

OpenRA.Utility/Program.cs.Main does not catch any exceptions at top level resulting in Unhandled exception. System.IO.FileNotFoundException: Could not find file and an abort before the final clause is reached.

The solution likely is to add catch { } to the main of utility.

==== AddChannel utility
==== Write utility, Received args: --png a a
==== WriteEx utility, System.IO.FileNotFoundException: Could not find file '/home/openra/source/cs/OpenRA/a'.

File name: '/home/openra/source/cs/OpenRA/a'
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
   at System.IO.File.OpenRead(String path)
   at OpenRA.Graphics.ImmutablePalette..ctor(String filename, Int32[] remapTransparent, Int32[] remap) in /home/openra/source/cs/OpenRA/OpenRA.Game/Graphics/Palette.cs:line 69
   at OpenRA.Mods.Common.UtilityCommands.ConvertSpriteToPngCommand.OpenRA.IUtilityCommand.Run(Utility utility, String[] args) in /home/openra/source/cs/OpenRA/OpenRA.Mods.Common/UtilityCommands/ConvertSpriteToPngCommand.cs:line 47
   at OpenRA.Program.Run(String[] args) in /home/openra/source/cs/OpenRA/OpenRA.Utility/Program.cs:line 118
* thread #1, name = 'dotnet', stop reason = signal SIGABRT                                                                                                   
  * frame #0: 0x00007fbdab8109fc libc.so.6`pthread_kill@@GLIBC_2.34 + 300                                                                                    
    frame #1: 0x00007fbdab7bc476 libc.so.6`raise + 22                                                                                                        
    frame #2: 0x00007fbdab7a27f3 libc.so.6`abort + 211                                                                                                       
    frame #3: 0x00007fbdab62c4c2 libcoreclr.so`___lldb_unnamed_symbol15933$$libcoreclr.so + 50                                                               
    frame #4: 0x00007fbdab62c3f9 libcoreclr.so`___lldb_unnamed_symbol15930$$libcoreclr.so + 137
    frame #5: 0x00007fbdab3fdaf5 libcoreclr.so`___lldb_unnamed_symbol8107$$libcoreclr.so + 1125                                                              
    frame #6: 0x00007fbdab3fdb40 libcoreclr.so`___lldb_unnamed_symbol8108$$libcoreclr.so + 64                                                                
    frame #7: 0x00007fbdab359b6b libcoreclr.so`___lldb_unnamed_symbol5952$$libcoreclr.so + 315                                                               
    frame #8: 0x00007fbd31ef0c35                                                                                                                             
    frame #9: 0x00007fbd31eedb1b                                                                                                                             
    frame #10: 0x00007fbdab4ae723 libcoreclr.so`___lldb_unnamed_symbol10051$$libcoreclr.so + 124                                                             
    frame #11: 0x00007fbdab2f545d libcoreclr.so`___lldb_unnamed_symbol4481$$libcoreclr.so + 1693                                                             
    frame #12: 0x00007fbdab1d48e5 libcoreclr.so`___lldb_unnamed_symbol301$$libcoreclr.so + 853                                                               
    frame #13: 0x00007fbdab1d4c12 libcoreclr.so`___lldb_unnamed_symbol302$$libcoreclr.so + 418                                                               
    frame #14: 0x00007fbdab2081cd libcoreclr.so`___lldb_unnamed_symbol1108$$libcoreclr.so + 733                                                              
    frame #15: 0x00007fbdab1befa8 libcoreclr.so`coreclr_execute_assembly + 248                                                                               
    frame #16: 0x00007fbdab6f215b libhostpolicy.so`___lldb_unnamed_symbol134$$libhostpolicy.so + 955                                                         
    frame #17: 0x00007fbdab6f23f0 libhostpolicy.so`___lldb_unnamed_symbol135$$libhostpolicy.so + 64                                                          
    frame #18: 0x00007fbdab6f2cd6 libhostpolicy.so`corehost_main + 214                                                                                       
    frame #19: 0x00007fbdab73cafb libhostfxr.so`___lldb_unnamed_symbol61$$libhostfxr.so + 1499                                                               
    frame #20: 0x00007fbdab73baf2 libhostfxr.so`___lldb_unnamed_symbol59$$libhostfxr.so + 770                                                                
    frame #21: 0x00007fbdab7383e8 libhostfxr.so`hostfxr_main_startupinfo + 200                                                                               
    frame #22: 0x00005566e70a7ff0 dotnet`___lldb_unnamed_symbol133$$dotnet + 1136                                                                            
    frame #23: 0x00005566e70a8240 dotnet`___lldb_unnamed_symbol134$$dotnet + 144                                                                             
    frame #24: 0x00007fbdab7a3d90 libc.so.6`__libc_start_call_main + 128                                                                                     
    frame #25: 0x00007fbdab7a3e40 libc.so.6`__libc_start_main@@GLIBC_2.34 + 128                                                                              
    frame #26: 0x00005566e709eb75 dotnet`___lldb_unnamed_symbol1$$dotnet + 37 

@RoosterDragon

Copy link
Copy Markdown
Member Author

That is indeed the solution this PR applies.

When the process is running, we use a finally block to call Log.Dispose and flush any outstanding logs to disk before the process exits. This works when we handle any exception in a matching catch block.

When the exception is unhandled, then the finally block will not run and instead the process will just exit. To fix this, flush the logs inside a catch block instead before rethrowing the error. This ensures we get logs even when crashing.
@PunkPun PunkPun merged commit 3232040 into OpenRA:bleed Aug 16, 2024
@PunkPun

PunkPun commented Aug 16, 2024

Copy link
Copy Markdown
Member

changelog

@RoosterDragon RoosterDragon deleted the flush-logs branch August 18, 2024 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Utility doesn't write logs, yet refers you to read the logs

3 participants