log: Add locking to large logging blocks
Reuse the existing locking provided by stdio to keep in_asm, cpu, op, op_opt, op_ind, and out_asm as contiguous blocks. While it isn't possible to interleave e.g. in_asm or op_opt logs because of the TB lock protecting all code generation, it is possible to interleave cpu logs, or to interleave a cpu dump with an out_asm dump. For mingw32, we appear to have no viable solution for this. The locking functions are not properly exported from the system runtime library. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
		
							parent
							
								
									9acbf7d8ca
								
							
						
					
					
						commit
						1ee73216f4
					
				| @ -150,11 +150,13 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) | ||||
| #if defined(DEBUG_DISAS) | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_CPU) | ||||
|         && qemu_log_in_addr_range(itb->pc)) { | ||||
|         qemu_log_lock(); | ||||
| #if defined(TARGET_I386) | ||||
|         log_cpu_state(cpu, CPU_DUMP_CCOP); | ||||
| #else | ||||
|         log_cpu_state(cpu, 0); | ||||
| #endif | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif /* DEBUG_DISAS */ | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										2
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								exec.c
									
									
									
									
									
								
							| @ -911,11 +911,13 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...) | ||||
|     fprintf(stderr, "\n"); | ||||
|     cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP); | ||||
|     if (qemu_log_separate()) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("qemu: fatal: "); | ||||
|         qemu_log_vprintf(fmt, ap2); | ||||
|         qemu_log("\n"); | ||||
|         log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP); | ||||
|         qemu_log_flush(); | ||||
|         qemu_log_unlock(); | ||||
|         qemu_log_close(); | ||||
|     } | ||||
|     va_end(ap2); | ||||
|  | ||||
| @ -51,6 +51,22 @@ static inline bool qemu_loglevel_mask(int mask) | ||||
|     return (qemu_loglevel & mask) != 0; | ||||
| } | ||||
| 
 | ||||
| /* Lock output for a series of related logs.  Since this is not needed
 | ||||
|  * for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we | ||||
|  * assume that qemu_loglevel_mask has already been tested, and that | ||||
|  * qemu_loglevel is never set when qemu_logfile is unset. | ||||
|  */ | ||||
| 
 | ||||
| static inline void qemu_log_lock(void) | ||||
| { | ||||
|     qemu_flockfile(qemu_logfile); | ||||
| } | ||||
| 
 | ||||
| static inline void qemu_log_unlock(void) | ||||
| { | ||||
|     qemu_funlockfile(qemu_logfile); | ||||
| } | ||||
| 
 | ||||
| /* Logging functions: */ | ||||
| 
 | ||||
| /* main logging function
 | ||||
|  | ||||
| @ -87,4 +87,16 @@ void *qemu_alloc_stack(size_t *sz); | ||||
|  */ | ||||
| void qemu_free_stack(void *stack, size_t sz); | ||||
| 
 | ||||
| /* POSIX and Mingw32 differ in the name of the stdio lock functions.  */ | ||||
| 
 | ||||
| static inline void qemu_flockfile(FILE *f) | ||||
| { | ||||
|     flockfile(f); | ||||
| } | ||||
| 
 | ||||
| static inline void qemu_funlockfile(FILE *f) | ||||
| { | ||||
|     funlockfile(f); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -103,6 +103,21 @@ static inline char *realpath(const char *path, char *resolved_path) | ||||
|     return resolved_path; | ||||
| } | ||||
| 
 | ||||
| /* ??? Mingw appears to export _lock_file and _unlock_file as the functions
 | ||||
|  * with which to lock a stdio handle.  But something is wrong in the markup, | ||||
|  * either in the header or the library, such that we get undefined references | ||||
|  * to "_imp___lock_file" etc when linking.  Since we seem to have no other | ||||
|  * alternative, and the usage within the logging functions isn't critical, | ||||
|  * ignore FILE locking. | ||||
|  */ | ||||
| 
 | ||||
| static inline void qemu_flockfile(FILE *f) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static inline void qemu_funlockfile(FILE *f) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| /* We wrap all the sockets functions so that we can
 | ||||
|  * set errno based on WSAGetLastError() | ||||
|  | ||||
| @ -2994,9 +2994,11 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, ctx.pc - pc_start, 1); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -11420,11 +11420,13 @@ done_generating: | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && | ||||
|         qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("----------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, dc->pc - pc_start, | ||||
|                          4 | (bswap_code(dc->sctlr_b) ? 2 : 0)); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
|     tb->size = dc->pc - pc_start; | ||||
|  | ||||
| @ -11963,11 +11963,13 @@ done_generating: | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && | ||||
|         qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("----------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, dc->pc - pc_start, | ||||
|                          dc->thumb | (dc->sctlr_b << 1)); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
|     tb->size = dc->pc - pc_start; | ||||
|  | ||||
| @ -3290,12 +3290,14 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb) | ||||
| #if !DISAS_CRIS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("--------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, dc->pc - pc_start, | ||||
|                          env->pregs[PR_VR]); | ||||
|         qemu_log("\nisize=%d osize=%d\n", | ||||
|                  dc->pc - pc_start, tcg_op_buf_count()); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| @ -2432,11 +2432,13 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) | ||||
| 
 | ||||
|     if (qemu_loglevel_mask(LOG_UNIMP)) { | ||||
|         target_ulong pc = s->pc_start, end = s->pc; | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc); | ||||
|         for (; pc < end; ++pc) { | ||||
|             qemu_log(" %02x", cpu_ldub_code(env, pc)); | ||||
|         } | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -8470,6 +8472,7 @@ done_generating: | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         int disas_flags; | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("----------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
| #ifdef TARGET_X86_64 | ||||
| @ -8480,6 +8483,7 @@ done_generating: | ||||
|             disas_flags = !dc->code32; | ||||
|         log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -1148,10 +1148,12 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("\n"); | ||||
|         log_target_disas(cs, pc_start, dc->pc - pc_start, 0); | ||||
|         qemu_log("\nisize=%d osize=%d\n", | ||||
|                  dc->pc - pc_start, tcg_op_buf_count()); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -3549,10 +3549,12 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("----------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, dc->pc - pc_start, 0); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
|     tb->size = dc->pc - pc_start; | ||||
|  | ||||
| @ -1813,12 +1813,14 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb) | ||||
| #if !SIM_COMPAT | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("--------------\n"); | ||||
| #if DISAS_GNU | ||||
|         log_target_disas(cs, pc_start, dc->pc - pc_start, 0); | ||||
| #endif | ||||
|         qemu_log("\nisize=%d osize=%d\n", | ||||
|                  dc->pc - pc_start, tcg_op_buf_count()); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| @ -20043,9 +20043,11 @@ done_generating: | ||||
|     LOG_DISAS("\n"); | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -1750,11 +1750,13 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("----------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, dc->pc - pc_start, 0); | ||||
|         qemu_log("\nisize=%d osize=%d\n", | ||||
|                  dc->pc - pc_start, tcg_op_buf_count()); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -7211,9 +7211,11 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb) | ||||
|         int flags; | ||||
|         flags = env->bfd_mach; | ||||
|         flags |= ctx.le_mode << 16; | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, ctx.nip - pc_start, flags); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -5432,9 +5432,11 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb) | ||||
| #if defined(S390X_DEBUG_DISAS) | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, dc.pc - pc_start, 1); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -1927,9 +1927,11 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
| 	qemu_log("IN:\n");	/* , lookup_symbol(pc_start)); */ | ||||
|         log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); | ||||
| 	qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -5796,10 +5796,12 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("--------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -2391,6 +2391,7 @@ void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb) | ||||
|     TCGV_UNUSED_I64(dc->zero); | ||||
| 
 | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|     } | ||||
|     if (!max_insns) { | ||||
| @ -2429,7 +2430,10 @@ void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb) | ||||
|     tb->size = dc->pc - pc_start; | ||||
|     tb->icount = num_insns; | ||||
| 
 | ||||
|     qemu_log_mask(CPU_LOG_TB_IN_ASM, "\n"); | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void restore_state_to_opc(CPUTLGState *env, TranslationBlock *tb, | ||||
|  | ||||
| @ -8789,9 +8789,11 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -2024,10 +2024,12 @@ done_generating: | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("----------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, dc->pc - pc_start, 0); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
|     tb->size = dc->pc - pc_start; | ||||
|  | ||||
| @ -3155,10 +3155,12 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) | ||||
|         && qemu_log_in_addr_range(pc_start)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("----------------\n"); | ||||
|         qemu_log("IN: %s\n", lookup_symbol(pc_start)); | ||||
|         log_target_disas(cs, pc_start, dc.pc - pc_start, 0); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
|     tb->size = dc.pc - pc_start; | ||||
|  | ||||
| @ -412,10 +412,12 @@ void tcg_prologue_init(TCGContext *s) | ||||
| 
 | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("PROLOGUE: [size=%zu]\n", prologue_size); | ||||
|         log_disas(buf0, prologue_size); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_flush(); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| @ -2542,9 +2544,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) | ||||
|                  && qemu_log_in_addr_range(tb->pc))) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("OP:\n"); | ||||
|         tcg_dump_ops(s); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
| @ -2570,9 +2574,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|             if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND) | ||||
|                          && qemu_log_in_addr_range(tb->pc))) { | ||||
|                 qemu_log_lock(); | ||||
|                 qemu_log("OP before indirect lowering:\n"); | ||||
|                 tcg_dump_ops(s); | ||||
|                 qemu_log("\n"); | ||||
|                 qemu_log_unlock(); | ||||
|             } | ||||
| #endif | ||||
|             /* Replace indirect temps with direct temps.  */ | ||||
| @ -2590,9 +2596,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT) | ||||
|                  && qemu_log_in_addr_range(tb->pc))) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("OP after optimization and liveness analysis:\n"); | ||||
|         tcg_dump_ops(s); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -1355,10 +1355,12 @@ TranslationBlock *tb_gen_code(CPUState *cpu, | ||||
| #ifdef DEBUG_DISAS | ||||
|     if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) && | ||||
|         qemu_log_in_addr_range(tb->pc)) { | ||||
|         qemu_log_lock(); | ||||
|         qemu_log("OUT: [size=%d]\n", gen_code_size); | ||||
|         log_disas(tb->tc_ptr, gen_code_size); | ||||
|         qemu_log("\n"); | ||||
|         qemu_log_flush(); | ||||
|         qemu_log_unlock(); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Richard Henderson
						Richard Henderson