Splitting logging core into poly.
This commit is contained in:
parent
08b0226a16
commit
e1b0388faf
|
@ -194,7 +194,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
|
||||||
if (fn_table_count + 1 > fn_table_capacity) {
|
if (fn_table_count + 1 > fn_table_capacity) {
|
||||||
// Table exhausted, need to realloc. If this happens a lot we should tune
|
// Table exhausted, need to realloc. If this happens a lot we should tune
|
||||||
// the table size to prevent this.
|
// the table size to prevent this.
|
||||||
XELOGW("X64CodeCache growing FunctionTable - adjust ESTIMATED_FN_SIZE");
|
PLOGW("X64CodeCache growing FunctionTable - adjust ESTIMATED_FN_SIZE");
|
||||||
RtlDeleteGrowableFunctionTable(fn_table_handle);
|
RtlDeleteGrowableFunctionTable(fn_table_handle);
|
||||||
size_t old_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION);
|
size_t old_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION);
|
||||||
size_t new_size = old_size * 2;
|
size_t new_size = old_size * 2;
|
||||||
|
|
|
@ -193,7 +193,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
|
||||||
if (!SelectSequence(*this, instr, &new_tail)) {
|
if (!SelectSequence(*this, instr, &new_tail)) {
|
||||||
// No sequence found!
|
// No sequence found!
|
||||||
assert_always();
|
assert_always();
|
||||||
XELOGE("Unable to process HIR opcode %s", instr->opcode->name);
|
PLOGE("Unable to process HIR opcode %s", instr->opcode->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
instr = new_tail;
|
instr = new_tail;
|
||||||
|
@ -372,7 +372,7 @@ void X64Emitter::Trap(uint16_t trap_type) {
|
||||||
db(0xCC);
|
db(0xCC);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
XELOGW("Unknown trap type %d", trap_type);
|
PLOGW("Unknown trap type %d", trap_type);
|
||||||
db(0xCC);
|
db(0xCC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -598,8 +598,8 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) {
|
||||||
|
|
||||||
uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) {
|
uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) {
|
||||||
auto symbol_info = reinterpret_cast<FunctionInfo*>(symbol_info_ptr);
|
auto symbol_info = reinterpret_cast<FunctionInfo*>(symbol_info_ptr);
|
||||||
XELOGW("undefined extern call to %.8llX %s", symbol_info->address(),
|
PLOGW("undefined extern call to %.8llX %s", symbol_info->address(),
|
||||||
symbol_info->name().c_str());
|
symbol_info->name().c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void X64Emitter::CallExtern(const hir::Instr* instr,
|
void X64Emitter::CallExtern(const hir::Instr* instr,
|
||||||
|
|
|
@ -5392,7 +5392,7 @@ bool SelectSequence(X64Emitter& e, const Instr* i, const Instr** new_tail) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XELOGE("No sequence match for variant %s", i->opcode->name);
|
PLOGE("No sequence match for variant %s", i->opcode->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
|
||||||
// We spill only those registers we aren't using.
|
// We spill only those registers we aren't using.
|
||||||
if (!SpillOneRegister(builder, block, instr->dest->type)) {
|
if (!SpillOneRegister(builder, block, instr->dest->type)) {
|
||||||
// Unable to spill anything - this shouldn't happen.
|
// Unable to spill anything - this shouldn't happen.
|
||||||
XELOGE("Unable to spill any registers");
|
PLOGE("Unable to spill any registers");
|
||||||
assert_always();
|
assert_always();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
|
||||||
// Demand allocation.
|
// Demand allocation.
|
||||||
if (!TryAllocateRegister(instr->dest)) {
|
if (!TryAllocateRegister(instr->dest)) {
|
||||||
// Boned.
|
// Boned.
|
||||||
XELOGE("Register allocation failed");
|
PLOGE("Register allocation failed");
|
||||||
assert_always();
|
assert_always();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#define ALLOY_CORE_H_
|
#define ALLOY_CORE_H_
|
||||||
|
|
||||||
// TODO(benvanik): move the common stuff into here?
|
// TODO(benvanik): move the common stuff into here?
|
||||||
#include <xenia/logging.h>
|
|
||||||
#include <xenia/profiling.h>
|
#include <xenia/profiling.h>
|
||||||
|
|
||||||
#endif // ALLOY_CORE_H_
|
#endif // ALLOY_CORE_H_
|
||||||
|
|
|
@ -116,7 +116,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
|
||||||
instr_offset_list_[offset] = first_instr;
|
instr_offset_list_[offset] = first_instr;
|
||||||
|
|
||||||
if (!i.type) {
|
if (!i.type) {
|
||||||
XELOGCPU("Invalid instruction %.8llX %.8X", i.address, i.code);
|
PLOGE("Invalid instruction %.8llX %.8X", i.address, i.code);
|
||||||
Comment("INVALID!");
|
Comment("INVALID!");
|
||||||
// TraceInvalidInstruction(i);
|
// TraceInvalidInstruction(i);
|
||||||
continue;
|
continue;
|
||||||
|
@ -131,8 +131,8 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i.type->emit || emit(*this, i)) {
|
if (!i.type->emit || emit(*this, i)) {
|
||||||
XELOGCPU("Unimplemented instr %.8llX %.8X %s", i.address, i.code,
|
PLOGE("Unimplemented instr %.8llX %.8X %s", i.address, i.code,
|
||||||
i.type->name);
|
i.type->name);
|
||||||
Comment("UNIMPLEMENTED!");
|
Comment("UNIMPLEMENTED!");
|
||||||
// DebugBreak();
|
// DebugBreak();
|
||||||
// TraceInvalidInstruction(i);
|
// TraceInvalidInstruction(i);
|
||||||
|
|
|
@ -15,8 +15,15 @@
|
||||||
#include <alloy/frontend/ppc/ppc_frontend.h>
|
#include <alloy/frontend/ppc/ppc_frontend.h>
|
||||||
#include <alloy/frontend/ppc/ppc_instr.h>
|
#include <alloy/frontend/ppc/ppc_instr.h>
|
||||||
#include <alloy/runtime/runtime.h>
|
#include <alloy/runtime/runtime.h>
|
||||||
|
#include <poly/logging.h>
|
||||||
#include <poly/memory.h>
|
#include <poly/memory.h>
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define LOGPPC(fmt, ...) PLOGCORE('p', fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LOGPPC(fmt, ...) POLY_EMPTY_MACRO
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace alloy {
|
namespace alloy {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
namespace ppc {
|
namespace ppc {
|
||||||
|
@ -48,7 +55,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
Memory* memory = frontend_->memory();
|
Memory* memory = frontend_->memory();
|
||||||
const uint8_t* p = memory->membase();
|
const uint8_t* p = memory->membase();
|
||||||
|
|
||||||
XELOGSDB("Analyzing function %.8X...", symbol_info->address());
|
LOGPPC("Analyzing function %.8X...", symbol_info->address());
|
||||||
|
|
||||||
uint32_t start_address = static_cast<uint32_t>(symbol_info->address());
|
uint32_t start_address = static_cast<uint32_t>(symbol_info->address());
|
||||||
uint32_t end_address = static_cast<uint32_t>(symbol_info->end_address());
|
uint32_t end_address = static_cast<uint32_t>(symbol_info->end_address());
|
||||||
|
@ -65,7 +72,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// If we fetched 0 assume that we somehow hit one of the awesome
|
// If we fetched 0 assume that we somehow hit one of the awesome
|
||||||
// 'no really we meant to end after that bl' functions.
|
// 'no really we meant to end after that bl' functions.
|
||||||
if (!i.code) {
|
if (!i.code) {
|
||||||
XELOGSDB("function end %.8X (0x00000000 read)", address);
|
LOGPPC("function end %.8X (0x00000000 read)", address);
|
||||||
// Don't include the 0's.
|
// Don't include the 0's.
|
||||||
address -= 4;
|
address -= 4;
|
||||||
break;
|
break;
|
||||||
|
@ -94,17 +101,16 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// Invalid instruction.
|
// Invalid instruction.
|
||||||
// We can just ignore it because there's (very little)/no chance it'll
|
// We can just ignore it because there's (very little)/no chance it'll
|
||||||
// affect flow control.
|
// affect flow control.
|
||||||
XELOGSDB("Invalid instruction at %.8X: %.8X", address, i.code);
|
LOGPPC("Invalid instruction at %.8X: %.8X", address, i.code);
|
||||||
} else if (i.code == 0x4E800020) {
|
} else if (i.code == 0x4E800020) {
|
||||||
// blr -- unconditional branch to LR.
|
// blr -- unconditional branch to LR.
|
||||||
// This is generally a return.
|
// This is generally a return.
|
||||||
if (furthest_target > address) {
|
if (furthest_target > address) {
|
||||||
// Remaining targets within function, not end.
|
// Remaining targets within function, not end.
|
||||||
XELOGSDB("ignoring blr %.8X (branch to %.8X)", address,
|
LOGPPC("ignoring blr %.8X (branch to %.8X)", address, furthest_target);
|
||||||
furthest_target);
|
|
||||||
} else {
|
} else {
|
||||||
// Function end point.
|
// Function end point.
|
||||||
XELOGSDB("function end %.8X", address);
|
LOGPPC("function end %.8X", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
|
@ -115,11 +121,10 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// TODO(benvanik): decode jump tables.
|
// TODO(benvanik): decode jump tables.
|
||||||
if (furthest_target > address) {
|
if (furthest_target > address) {
|
||||||
// Remaining targets within function, not end.
|
// Remaining targets within function, not end.
|
||||||
XELOGSDB("ignoring bctr %.8X (branch to %.8X)", address,
|
LOGPPC("ignoring bctr %.8X (branch to %.8X)", address, furthest_target);
|
||||||
furthest_target);
|
|
||||||
} else {
|
} else {
|
||||||
// Function end point.
|
// Function end point.
|
||||||
XELOGSDB("function end %.8X", address);
|
LOGPPC("function end %.8X", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
|
@ -129,25 +134,25 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
(uint32_t)XEEXTS26(i.I.LI << 2) + (i.I.AA ? 0 : (int32_t)address);
|
(uint32_t)XEEXTS26(i.I.LI << 2) + (i.I.AA ? 0 : (int32_t)address);
|
||||||
|
|
||||||
if (i.I.LK) {
|
if (i.I.LK) {
|
||||||
XELOGSDB("bl %.8X -> %.8X", address, target);
|
LOGPPC("bl %.8X -> %.8X", address, target);
|
||||||
// Queue call target if needed.
|
// Queue call target if needed.
|
||||||
// GetOrInsertFunction(target);
|
// GetOrInsertFunction(target);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB("b %.8X -> %.8X", address, target);
|
LOGPPC("b %.8X -> %.8X", address, target);
|
||||||
|
|
||||||
// If the target is back into the function and there's no further target
|
// If the target is back into the function and there's no further target
|
||||||
// we are at the end of a function.
|
// we are at the end of a function.
|
||||||
// (Indirect branches may still go beyond, but no way of knowing).
|
// (Indirect branches may still go beyond, but no way of knowing).
|
||||||
if (target >= start_address && target < address &&
|
if (target >= start_address && target < address &&
|
||||||
furthest_target <= address) {
|
furthest_target <= address) {
|
||||||
XELOGSDB("function end %.8X (back b)", address);
|
LOGPPC("function end %.8X (back b)", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the target is not a branch and it goes to before the current
|
// If the target is not a branch and it goes to before the current
|
||||||
// address it's definitely a tail call.
|
// address it's definitely a tail call.
|
||||||
if (!ends_fn && target < start_address && furthest_target <= address) {
|
if (!ends_fn && target < start_address && furthest_target <= address) {
|
||||||
XELOGSDB("function end %.8X (back b before addr)", address);
|
LOGPPC("function end %.8X (back b before addr)", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +161,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// of the function somewhere, so ensure we don't have any branches over
|
// of the function somewhere, so ensure we don't have any branches over
|
||||||
// it.
|
// it.
|
||||||
if (!ends_fn && furthest_target <= address && IsRestGprLr(target)) {
|
if (!ends_fn && furthest_target <= address && IsRestGprLr(target)) {
|
||||||
XELOGSDB("function end %.8X (__restgprlr_*)", address);
|
LOGPPC("function end %.8X (__restgprlr_*)", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +173,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// This check may hit on functions that jump over data code, so only
|
// This check may hit on functions that jump over data code, so only
|
||||||
// trigger this check in leaf functions (no mfspr lr/prolog).
|
// trigger this check in leaf functions (no mfspr lr/prolog).
|
||||||
if (!ends_fn && !starts_with_mfspr_lr && blocks_found == 1) {
|
if (!ends_fn && !starts_with_mfspr_lr && blocks_found == 1) {
|
||||||
XELOGSDB("HEURISTIC: ending at simple leaf thunk %.8X", address);
|
LOGPPC("HEURISTIC: ending at simple leaf thunk %.8X", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +191,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
if (!ends_fn &&
|
if (!ends_fn &&
|
||||||
target > addr &&
|
target > addr &&
|
||||||
furthest_target < addr) {
|
furthest_target < addr) {
|
||||||
XELOGSDB("HEURISTIC: ending at tail call branch %.8X", addr);
|
LOGPPC("HEURISTIC: ending at tail call branch %.8X", addr);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -206,14 +211,14 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
uint32_t target =
|
uint32_t target =
|
||||||
(uint32_t)XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)address);
|
(uint32_t)XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)address);
|
||||||
if (i.B.LK) {
|
if (i.B.LK) {
|
||||||
XELOGSDB("bcl %.8X -> %.8X", address, target);
|
LOGPPC("bcl %.8X -> %.8X", address, target);
|
||||||
|
|
||||||
// Queue call target if needed.
|
// Queue call target if needed.
|
||||||
// TODO(benvanik): see if this is correct - not sure anyone makes
|
// TODO(benvanik): see if this is correct - not sure anyone makes
|
||||||
// function calls with bcl.
|
// function calls with bcl.
|
||||||
// GetOrInsertFunction(target);
|
// GetOrInsertFunction(target);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB("bc %.8X -> %.8X", address, target);
|
LOGPPC("bc %.8X -> %.8X", address, target);
|
||||||
|
|
||||||
// TODO(benvanik): GetOrInsertFunction? it's likely a BB
|
// TODO(benvanik): GetOrInsertFunction? it's likely a BB
|
||||||
|
|
||||||
|
@ -225,17 +230,17 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
} else if (i.type->opcode == 0x4C000020) {
|
} else if (i.type->opcode == 0x4C000020) {
|
||||||
// bclr/bclrl
|
// bclr/bclrl
|
||||||
if (i.XL.LK) {
|
if (i.XL.LK) {
|
||||||
XELOGSDB("bclrl %.8X", address);
|
LOGPPC("bclrl %.8X", address);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB("bclr %.8X", address);
|
LOGPPC("bclr %.8X", address);
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
} else if (i.type->opcode == 0x4C000420) {
|
} else if (i.type->opcode == 0x4C000420) {
|
||||||
// bcctr/bcctrl
|
// bcctr/bcctrl
|
||||||
if (i.XL.LK) {
|
if (i.XL.LK) {
|
||||||
XELOGSDB("bcctrl %.8X", address);
|
LOGPPC("bcctrl %.8X", address);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB("bcctr %.8X", address);
|
LOGPPC("bcctr %.8X", address);
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
}
|
}
|
||||||
|
@ -250,8 +255,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
address += 4;
|
address += 4;
|
||||||
if (end_address && address > end_address) {
|
if (end_address && address > end_address) {
|
||||||
// Hmm....
|
// Hmm....
|
||||||
XELOGSDB("Ran over function bounds! %.8X-%.8X", start_address,
|
LOGPPC("Ran over function bounds! %.8X-%.8X", start_address, end_address);
|
||||||
end_address);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,8 +265,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// from someplace valid (like method hints) this may indicate an error.
|
// from someplace valid (like method hints) this may indicate an error.
|
||||||
// It's also possible that we guessed in hole-filling and there's another
|
// It's also possible that we guessed in hole-filling and there's another
|
||||||
// function below this one.
|
// function below this one.
|
||||||
XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X", start_address,
|
LOGPPC("Function ran under: %.8X-%.8X ended at %.8X", start_address,
|
||||||
end_address, address + 4);
|
end_address, address + 4);
|
||||||
}
|
}
|
||||||
symbol_info->set_end_address(address);
|
symbol_info->set_end_address(address);
|
||||||
|
|
||||||
|
@ -274,7 +278,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// - if present, flag function as needing a stack
|
// - if present, flag function as needing a stack
|
||||||
// - record prolog/epilog lengths/stack size/etc
|
// - record prolog/epilog lengths/stack size/etc
|
||||||
|
|
||||||
XELOGSDB("Finished analyzing %.8X", start_address);
|
LOGPPC("Finished analyzing %.8X", start_address);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ Breakpoint* Function::FindBreakpoint(uint64_t address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Function::Call(ThreadState* thread_state, uint64_t return_address) {
|
int Function::Call(ThreadState* thread_state, uint64_t return_address) {
|
||||||
SCOPE_profile_cpu_f("alloy");
|
//SCOPE_profile_cpu_f("alloy");
|
||||||
|
|
||||||
ThreadState* original_thread_state = ThreadState::Get();
|
ThreadState* original_thread_state = ThreadState::Get();
|
||||||
if (original_thread_state != thread_state) {
|
if (original_thread_state != thread_state) {
|
||||||
|
@ -90,8 +90,8 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) {
|
||||||
handler(thread_state->raw_context(), symbol_info_->extern_arg0(),
|
handler(thread_state->raw_context(), symbol_info_->extern_arg0(),
|
||||||
symbol_info_->extern_arg1());
|
symbol_info_->extern_arg1());
|
||||||
} else {
|
} else {
|
||||||
XELOGW("undefined extern call to %.8llX %s", symbol_info_->address(),
|
PLOGW("undefined extern call to %.8llX %s", symbol_info_->address(),
|
||||||
symbol_info_->name().c_str());
|
symbol_info_->name().c_str());
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,44 +7,49 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xenia/logging.h>
|
#include <poly/logging.h>
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
#include <poly/main.h>
|
#include <poly/main.h>
|
||||||
#include <poly/math.h>
|
#include <poly/math.h>
|
||||||
#include <xenia/common.h>
|
|
||||||
|
|
||||||
DEFINE_bool(fast_stdout, false,
|
DEFINE_bool(fast_stdout, false,
|
||||||
"Don't lock around stdout/stderr. May introduce weirdness.");
|
"Don't lock around stdout/stderr. May introduce weirdness.");
|
||||||
|
DEFINE_bool(log_filenames, false,
|
||||||
|
"Log filenames/line numbers in log statements.");
|
||||||
|
|
||||||
|
namespace poly {
|
||||||
|
|
||||||
namespace {
|
|
||||||
std::mutex log_lock;
|
std::mutex log_lock;
|
||||||
} // namespace
|
|
||||||
|
|
||||||
|
void format_log_line(char* buffer, size_t buffer_count, const char* file_path,
|
||||||
|
const uint32_t line_number, const char level_char,
|
||||||
|
const char* fmt, va_list args) {
|
||||||
|
char* buffer_ptr;
|
||||||
|
if (FLAGS_log_filenames) {
|
||||||
|
// Strip out just the filename from the path.
|
||||||
|
const char* filename = strrchr(file_path, poly::path_separator);
|
||||||
|
if (filename) {
|
||||||
|
// Slash - skip over it.
|
||||||
|
filename++;
|
||||||
|
} else {
|
||||||
|
// No slash, entire thing is filename.
|
||||||
|
filename = file_path;
|
||||||
|
}
|
||||||
|
|
||||||
void xe_format_log_line(
|
// Format string - add a trailing newline if required.
|
||||||
char* buffer, size_t buffer_count,
|
const char* outfmt = "%c> %s:%d: ";
|
||||||
const char* file_path, const uint32_t line_number,
|
buffer_ptr = buffer + snprintf(buffer, buffer_count - 1, outfmt, level_char,
|
||||||
const char* function_name, const char level_char,
|
filename, line_number);
|
||||||
const char* fmt, va_list args) {
|
|
||||||
// Strip out just the filename from the path.
|
|
||||||
const char* filename = strrchr(file_path, poly::path_separator);
|
|
||||||
if (filename) {
|
|
||||||
// Slash - skip over it.
|
|
||||||
filename++;
|
|
||||||
} else {
|
} else {
|
||||||
// No slash, entire thing is filename.
|
buffer_ptr = buffer;
|
||||||
filename = file_path;
|
*(buffer_ptr++) = level_char;
|
||||||
|
*(buffer_ptr++) = '>';
|
||||||
|
*(buffer_ptr++) = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format string - add a trailing newline if required.
|
|
||||||
const char* outfmt = "XE[%c] %s:%d: ";
|
|
||||||
char* buffer_ptr = buffer + snprintf(buffer, buffer_count - 1, outfmt,
|
|
||||||
level_char, filename, line_number);
|
|
||||||
|
|
||||||
// Scribble args into the print buffer.
|
// Scribble args into the print buffer.
|
||||||
buffer_ptr = buffer_ptr + vsnprintf(buffer_ptr,
|
buffer_ptr = buffer_ptr + vsnprintf(buffer_ptr,
|
||||||
buffer_count - (buffer_ptr - buffer) - 1,
|
buffer_count - (buffer_ptr - buffer) - 1,
|
||||||
|
@ -57,23 +62,21 @@ void xe_format_log_line(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xe_log_line(const char* file_path, const uint32_t line_number,
|
void log_line(const char* file_path, const uint32_t line_number,
|
||||||
const char* function_name, const char level_char,
|
const char level_char, const char* fmt, ...) {
|
||||||
const char* fmt, ...) {
|
// SCOPE_profile_cpu_i("emu", "log_line");
|
||||||
SCOPE_profile_cpu_i("emu", "log_line");
|
|
||||||
|
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
xe_format_log_line(buffer, poly::countof(buffer),
|
format_log_line(buffer, poly::countof(buffer), file_path, line_number,
|
||||||
file_path, line_number, function_name, level_char,
|
level_char, fmt, args);
|
||||||
fmt, args);
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (!FLAGS_fast_stdout) {
|
if (!FLAGS_fast_stdout) {
|
||||||
log_lock.lock();
|
log_lock.lock();
|
||||||
}
|
}
|
||||||
#if 0// defined(OutputDebugString)
|
#if 0 // defined(OutputDebugString)
|
||||||
OutputDebugStringA(buffer);
|
OutputDebugStringA(buffer);
|
||||||
#else
|
#else
|
||||||
fprintf(stdout, buffer);
|
fprintf(stdout, buffer);
|
||||||
|
@ -84,15 +87,13 @@ void xe_log_line(const char* file_path, const uint32_t line_number,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xe_handle_fatal(
|
void handle_fatal(const char* file_path, const uint32_t line_number,
|
||||||
const char* file_path, const uint32_t line_number,
|
const char* fmt, ...) {
|
||||||
const char* function_name, const char* fmt, ...) {
|
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
xe_format_log_line(buffer, poly::countof(buffer),
|
format_log_line(buffer, poly::countof(buffer), file_path, line_number, 'X',
|
||||||
file_path, line_number, function_name, 'X',
|
fmt, args);
|
||||||
fmt, args);
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (!FLAGS_fast_stdout) {
|
if (!FLAGS_fast_stdout) {
|
||||||
|
@ -117,3 +118,5 @@ void xe_handle_fatal(
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace poly
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef POLY_LOGGING_H_
|
||||||
|
#define POLY_LOGGING_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <poly/string.h>
|
||||||
|
|
||||||
|
namespace poly {
|
||||||
|
|
||||||
|
#define POLY_OPTION_ENABLE_LOGGING 1
|
||||||
|
#define POLY_OPTION_LOG_ERROR 1
|
||||||
|
#define POLY_OPTION_LOG_WARNING 1
|
||||||
|
#define POLY_OPTION_LOG_INFO 1
|
||||||
|
#define POLY_OPTION_LOG_DEBUG 1
|
||||||
|
|
||||||
|
#define POLY_EMPTY_MACRO \
|
||||||
|
do { \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#if XE_COMPILER_GNUC
|
||||||
|
#define POLY_LOG_LINE_ATTRIBUTE __attribute__((format(printf, 5, 6)))
|
||||||
|
#else
|
||||||
|
#define POLY_LOG_LINE_ATTRIBUTE
|
||||||
|
#endif // GNUC
|
||||||
|
void log_line(const char* file_path, const uint32_t line_number,
|
||||||
|
const char level_char, const char* fmt,
|
||||||
|
...) POLY_LOG_LINE_ATTRIBUTE;
|
||||||
|
#undef POLY_LOG_LINE_ATTRIBUTE
|
||||||
|
|
||||||
|
void handle_fatal(const char* file_path, const uint32_t line_number,
|
||||||
|
const char* fmt, ...);
|
||||||
|
|
||||||
|
#if POLY_OPTION_ENABLE_LOGGING
|
||||||
|
#define PLOGCORE(level, fmt, ...) \
|
||||||
|
poly::log_line(__FILE__, __LINE__, level, fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define PLOGCORE(level, fmt, ...) POLY_EMPTY_MACRO
|
||||||
|
#endif // ENABLE_LOGGING
|
||||||
|
|
||||||
|
#define PFATAL(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
poly::handle_fatal(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#if POLY_OPTION_LOG_ERROR
|
||||||
|
#define PLOGE(fmt, ...) PLOGCORE('!', fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define PLOGE(fmt, ...) POLY_EMPTY_MACRO
|
||||||
|
#endif
|
||||||
|
#if POLY_OPTION_LOG_WARNING
|
||||||
|
#define PLOGW(fmt, ...) PLOGCORE('w', fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define PLOGW(fmt, ...) POLY_EMPTY_MACRO
|
||||||
|
#endif
|
||||||
|
#if POLY_OPTION_LOG_INFO
|
||||||
|
#define PLOGI(fmt, ...) PLOGCORE('i', fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define PLOGI(fmt, ...) POLY_EMPTY_MACRO
|
||||||
|
#endif
|
||||||
|
#if POLY_OPTION_LOG_DEBUG
|
||||||
|
#define PLOGD(fmt, ...) PLOGCORE('d', fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define PLOGD(fmt, ...) POLY_EMPTY_MACRO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace poly
|
||||||
|
|
||||||
|
#endif // POLY_LOGGING_H_
|
|
@ -16,6 +16,7 @@
|
||||||
#include <poly/config.h>
|
#include <poly/config.h>
|
||||||
#include <poly/cxx_compat.h>
|
#include <poly/cxx_compat.h>
|
||||||
#include <poly/debugging.h>
|
#include <poly/debugging.h>
|
||||||
|
#include <poly/logging.h>
|
||||||
#include <poly/mapped_memory.h>
|
#include <poly/mapped_memory.h>
|
||||||
#include <poly/math.h>
|
#include <poly/math.h>
|
||||||
#include <poly/memory.h>
|
#include <poly/memory.h>
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
'debugging.h',
|
'debugging.h',
|
||||||
'config.h',
|
'config.h',
|
||||||
'cxx_compat.h',
|
'cxx_compat.h',
|
||||||
|
'logging.cc',
|
||||||
|
'logging.h',
|
||||||
'main.h',
|
'main.h',
|
||||||
'mapped_memory.h',
|
'mapped_memory.h',
|
||||||
'math.cc',
|
'math.cc',
|
||||||
|
|
|
@ -125,7 +125,7 @@ void D3D11GraphicsDriver::InitializeInvalidTexture() {
|
||||||
HRESULT hr = device_->CreateTexture2D(
|
HRESULT hr = device_->CreateTexture2D(
|
||||||
&texture_desc, &initial_data, (ID3D11Texture2D**)&texture);
|
&texture_desc, &initial_data, (ID3D11Texture2D**)&texture);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
XEFATAL("D3D11: unable to create invalid texture");
|
PFATAL("D3D11: unable to create invalid texture");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ void D3D11GraphicsDriver::InitializeInvalidTexture() {
|
||||||
hr = device_->CreateSamplerState(
|
hr = device_->CreateSamplerState(
|
||||||
&sampler_desc, &invalid_texture_sampler_state_);
|
&sampler_desc, &invalid_texture_sampler_state_);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
XEFATAL("D3D11: unable to create invalid sampler state");
|
PFATAL("D3D11: unable to create invalid sampler state");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,7 +401,7 @@ bool D3D11ProfilerDisplay::SetupFont() {
|
||||||
hr = device->CreateSamplerState(
|
hr = device->CreateSamplerState(
|
||||||
&sampler_desc, &font_sampler_state_);
|
&sampler_desc, &font_sampler_state_);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
XEFATAL("D3D11: unable to create invalid sampler state");
|
PFATAL("D3D11: unable to create invalid sampler state");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <poly/string.h>
|
#include <poly/logging.h>
|
||||||
|
|
||||||
#define XE_OPTION_ENABLE_LOGGING 1
|
#define XE_OPTION_ENABLE_LOGGING 1
|
||||||
#define XE_OPTION_LOG_ERROR 1
|
#define XE_OPTION_LOG_ERROR 1
|
||||||
|
@ -20,89 +20,55 @@
|
||||||
#define XE_OPTION_LOG_INFO 1
|
#define XE_OPTION_LOG_INFO 1
|
||||||
#define XE_OPTION_LOG_DEBUG 1
|
#define XE_OPTION_LOG_DEBUG 1
|
||||||
#define XE_OPTION_LOG_CPU 1
|
#define XE_OPTION_LOG_CPU 1
|
||||||
#define XE_OPTION_LOG_SDB 0
|
|
||||||
#define XE_OPTION_LOG_APU 1
|
#define XE_OPTION_LOG_APU 1
|
||||||
#define XE_OPTION_LOG_GPU 1
|
#define XE_OPTION_LOG_GPU 1
|
||||||
#define XE_OPTION_LOG_KERNEL 1
|
#define XE_OPTION_LOG_KERNEL 1
|
||||||
#define XE_OPTION_LOG_FS 1
|
#define XE_OPTION_LOG_FS 1
|
||||||
|
|
||||||
#define XE_EMPTY_MACRO do { } while(0)
|
|
||||||
|
|
||||||
#if XE_COMPILER_GNUC
|
|
||||||
#define XE_LOG_LINE_ATTRIBUTE __attribute__ ((format (printf, 5, 6)))
|
|
||||||
#else
|
|
||||||
#define XE_LOG_LINE_ATTRIBUTE
|
|
||||||
#endif // GNUC
|
|
||||||
void xe_log_line(const char* file_path, const uint32_t line_number,
|
|
||||||
const char* function_name, const char level_char,
|
|
||||||
const char* fmt, ...) XE_LOG_LINE_ATTRIBUTE;
|
|
||||||
#undef XE_LOG_LINE_ATTRIBUTE
|
|
||||||
void xe_handle_fatal(
|
|
||||||
const char* file_path, const uint32_t line_number,
|
|
||||||
const char* function_name, const char* fmt, ...);
|
|
||||||
|
|
||||||
#if XE_OPTION_ENABLE_LOGGING
|
|
||||||
#define XELOGCORE(level, fmt, ...) xe_log_line( \
|
|
||||||
__FILE__, __LINE__, __FUNCTION__, level, \
|
|
||||||
fmt, ##__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define XELOGCORE(level, fmt, ...) XE_EMPTY_MACRO
|
|
||||||
#endif // ENABLE_LOGGING
|
|
||||||
|
|
||||||
#define XEFATAL(fmt, ...) do { \
|
|
||||||
xe_handle_fatal(__FILE__, __LINE__, __FUNCTION__, \
|
|
||||||
fmt, ##__VA_ARGS__); \
|
|
||||||
} while (false);
|
|
||||||
|
|
||||||
#if XE_OPTION_LOG_ERROR
|
#if XE_OPTION_LOG_ERROR
|
||||||
#define XELOGE(fmt, ...) XELOGCORE('!', fmt, ##__VA_ARGS__)
|
#define XELOGE PLOGE
|
||||||
#else
|
#else
|
||||||
#define XELOGE(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGE(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
#endif
|
||||||
#if XE_OPTION_LOG_WARNING
|
#if XE_OPTION_LOG_WARNING
|
||||||
#define XELOGW(fmt, ...) XELOGCORE('w', fmt, ##__VA_ARGS__)
|
#define XELOGW PLOGW
|
||||||
#else
|
#else
|
||||||
#define XELOGW(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGW(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
#endif
|
||||||
#if XE_OPTION_LOG_INFO
|
#if XE_OPTION_LOG_INFO
|
||||||
#define XELOGI(fmt, ...) XELOGCORE('i', fmt, ##__VA_ARGS__)
|
#define XELOGI PLOGI
|
||||||
#else
|
#else
|
||||||
#define XELOGI(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGI(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
#endif
|
||||||
#if XE_OPTION_LOG_DEBUG
|
#if XE_OPTION_LOG_DEBUG
|
||||||
#define XELOGD(fmt, ...) XELOGCORE('d', fmt, ##__VA_ARGS__)
|
#define XELOGD PLOGD
|
||||||
#else
|
#else
|
||||||
#define XELOGD(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGD(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
#endif
|
||||||
#if XE_OPTION_LOG_CPU
|
#if XE_OPTION_LOG_CPU
|
||||||
#define XELOGCPU(fmt, ...) XELOGCORE('C', fmt, ##__VA_ARGS__)
|
#define XELOGCPU(fmt, ...) PLOGCORE('C', fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define XELOGCPU(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGCPU(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
|
||||||
#if XE_OPTION_LOG_SDB
|
|
||||||
#define XELOGSDB(fmt, ...) XELOGCORE('S', fmt, ##__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define XELOGSDB(fmt, ...) XE_EMPTY_MACRO
|
|
||||||
#endif
|
#endif
|
||||||
#if XE_OPTION_LOG_APU
|
#if XE_OPTION_LOG_APU
|
||||||
#define XELOGAPU(fmt, ...) XELOGCORE('A', fmt, ##__VA_ARGS__)
|
#define XELOGAPU(fmt, ...) PLOGCORE('A', fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define XELOGAPU(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGAPU(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
#endif
|
||||||
#if XE_OPTION_LOG_GPU
|
#if XE_OPTION_LOG_GPU
|
||||||
#define XELOGGPU(fmt, ...) XELOGCORE('G', fmt, ##__VA_ARGS__)
|
#define XELOGGPU(fmt, ...) PLOGCORE('G', fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define XELOGGPU(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGGPU(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
#endif
|
||||||
#if XE_OPTION_LOG_KERNEL
|
#if XE_OPTION_LOG_KERNEL
|
||||||
#define XELOGKERNEL(fmt, ...) XELOGCORE('K', fmt, ##__VA_ARGS__)
|
#define XELOGKERNEL(fmt, ...) PLOGCORE('K', fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define XELOGKERNEL(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGKERNEL(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
#endif
|
||||||
#if XE_OPTION_LOG_FS
|
#if XE_OPTION_LOG_FS
|
||||||
#define XELOGFS(fmt, ...) XELOGCORE('F', fmt, ##__VA_ARGS__)
|
#define XELOGFS(fmt, ...) PLOGCORE('F', fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define XELOGFS(fmt, ...) XE_EMPTY_MACRO
|
#define XELOGFS(fmt, ...) POLY_EMPTY_MACRO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
'emulator.h',
|
'emulator.h',
|
||||||
'export_resolver.cc',
|
'export_resolver.cc',
|
||||||
'export_resolver.h',
|
'export_resolver.h',
|
||||||
'logging.cc',
|
|
||||||
'logging.h',
|
'logging.h',
|
||||||
'memory.cc',
|
'memory.cc',
|
||||||
'memory.h',
|
'memory.h',
|
||||||
|
|
|
@ -25,13 +25,12 @@ using xdb::PostmortemDebugTarget;
|
||||||
int main(std::vector<std::wstring>& args) {
|
int main(std::vector<std::wstring>& args) {
|
||||||
auto left_target = std::make_unique<PostmortemDebugTarget>();
|
auto left_target = std::make_unique<PostmortemDebugTarget>();
|
||||||
if (!left_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_left))) {
|
if (!left_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_left))) {
|
||||||
XEFATAL("Unable to load left trace file: %s",
|
PFATAL("Unable to load left trace file: %s", FLAGS_trace_file_left.c_str());
|
||||||
FLAGS_trace_file_left.c_str());
|
|
||||||
}
|
}
|
||||||
auto right_target = std::make_unique<PostmortemDebugTarget>();
|
auto right_target = std::make_unique<PostmortemDebugTarget>();
|
||||||
if (!right_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_right))) {
|
if (!right_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_right))) {
|
||||||
XEFATAL("Unable to load right trace file: %s",
|
PFATAL("Unable to load right trace file: %s",
|
||||||
FLAGS_trace_file_right.c_str());
|
FLAGS_trace_file_right.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace xdb {
|
||||||
int main(std::vector<std::wstring>& args) {
|
int main(std::vector<std::wstring>& args) {
|
||||||
wxInitializer init;
|
wxInitializer init;
|
||||||
if (!init.IsOk()) {
|
if (!init.IsOk()) {
|
||||||
XEFATAL("Failed to initialize wxWidgets");
|
PFATAL("Failed to initialize wxWidgets");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,18 +34,18 @@ int main(std::vector<std::wstring>& args) {
|
||||||
auto app = new ui::XdbApp();
|
auto app = new ui::XdbApp();
|
||||||
wxApp::SetInstance(app);
|
wxApp::SetInstance(app);
|
||||||
if (!wxEntryStart(0, nullptr)) {
|
if (!wxEntryStart(0, nullptr)) {
|
||||||
XEFATAL("Failed to enter wxWidgets app");
|
PFATAL("Failed to enter wxWidgets app");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!app->OnInit()) {
|
if (!app->OnInit()) {
|
||||||
XEFATAL("Failed to init app");
|
PFATAL("Failed to init app");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FLAGS_trace_file.empty()) {
|
if (!FLAGS_trace_file.empty()) {
|
||||||
// Trace file specified on command line.
|
// Trace file specified on command line.
|
||||||
if (!app->OpenTraceFile(FLAGS_trace_file, FLAGS_content_file)) {
|
if (!app->OpenTraceFile(FLAGS_trace_file, FLAGS_content_file)) {
|
||||||
XEFATAL("Failed to open trace file");
|
PFATAL("Failed to open trace file");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,7 +23,7 @@ int xenia_run(std::vector<std::wstring>& args) {
|
||||||
// Grab path from the flag or unnamed argument.
|
// Grab path from the flag or unnamed argument.
|
||||||
if (!FLAGS_target.size() && args.size() < 2) {
|
if (!FLAGS_target.size() && args.size() < 2) {
|
||||||
google::ShowUsageWithFlags("xenia-run");
|
google::ShowUsageWithFlags("xenia-run");
|
||||||
XEFATAL("Pass a file to launch.");
|
PFATAL("Pass a file to launch.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
std::wstring path;
|
std::wstring path;
|
||||||
|
|
Loading…
Reference in New Issue