linux-user: Clean up when exiting due to a signal
When exiting due to an exit() syscall, qemu-user calls preexit_cleanup(), but this is currently not the case when exiting due to a signal. This leads to various buffers not being flushed (e.g., for gprof, for gcov, and for the upcoming perf support). Add the missing call. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230112152013.125680-2-iii@linux.ibm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
		
				
					committed by
					
						 Richard Henderson
						Richard Henderson
					
				
			
			
				
	
			
			
			
						parent
						
							fb7e799034
						
					
				
				
					commit
					da91c19202
				
			| @@ -695,7 +695,7 @@ void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr, | ||||
|  | ||||
| /* abort execution with signal */ | ||||
| static G_NORETURN | ||||
| void dump_core_and_abort(int target_sig) | ||||
| void dump_core_and_abort(CPUArchState *cpu_env, int target_sig) | ||||
| { | ||||
|     CPUState *cpu = thread_cpu; | ||||
|     CPUArchState *env = cpu->env_ptr; | ||||
| @@ -724,6 +724,8 @@ void dump_core_and_abort(int target_sig) | ||||
|             target_sig, strsignal(host_sig), "core dumped" ); | ||||
|     } | ||||
|  | ||||
|     preexit_cleanup(cpu_env, 128 + target_sig); | ||||
|  | ||||
|     /* The proper exit code for dying from an uncaught signal is | ||||
|      * -<signal>.  The kernel doesn't allow exit() or _exit() to pass | ||||
|      * a negative value.  To get the proper exit code we need to | ||||
| @@ -1058,12 +1060,12 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig, | ||||
|                    sig != TARGET_SIGURG && | ||||
|                    sig != TARGET_SIGWINCH && | ||||
|                    sig != TARGET_SIGCONT) { | ||||
|             dump_core_and_abort(sig); | ||||
|             dump_core_and_abort(cpu_env, sig); | ||||
|         } | ||||
|     } else if (handler == TARGET_SIG_IGN) { | ||||
|         /* ignore sig */ | ||||
|     } else if (handler == TARGET_SIG_ERR) { | ||||
|         dump_core_and_abort(sig); | ||||
|         dump_core_and_abort(cpu_env, sig); | ||||
|     } else { | ||||
|         /* compute the blocked signals during the handler execution */ | ||||
|         sigset_t *blocked_set; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user