void *malloc_file_line(size_t size, const char *file, int line, bool array, bool throw_on_fail, bool clear) { // allocate the memory and fail if we can't void *result = array ? osd_malloc_array(size) : osd_malloc(size); if (result == nullptr) { fprintf(stderr, "Failed to allocate %d bytes (%s:%d)\n", UINT32(size), file, line); osd_break_into_debugger("Failed to allocate RAM"); if (throw_on_fail) throw std::bad_alloc(); return nullptr; } // zap the memory if requested if (clear) memset(result, 0, size); else { #if !__has_feature(memory_sanitizer) && defined(INITIALIZE_ALLOCATED_MEMORY) && !defined(MAME_DEBUG_FAST) memset(result, 0xdd, size); #endif } // add a new entry memory_entry::allocate(size, result, file, line, array); return result; }
void free_file_line(void *memory, const char *file, int line) { // ignore NULL frees/deletes if (memory == NULL) return; // find the memory entry memory_entry *entry = memory_entry::find(memory); // warn about untracked frees if (entry == NULL) { fprintf(stderr, "Error: attempt to free untracked memory in %s(%d)!\n", file, line); osd_break_into_debugger("Error: attempt to free untracked memory"); return; } #ifdef MAME_DEBUG // clear memory to a bogus value memset(memory, 0xfc, entry->m_size); #endif // free the entry and the memory memory_entry::release(entry); osd_free(memory); }
void CLIB_DECL free(void *memory) { memory_entry *entry; // allow NULL frees if (memory == NULL) return; // error if no entry found entry = find_entry(memory); if (entry == NULL) { if (winalloc_in_main_code) { fprintf(stderr, "Error: free a non-existant block\n"); osd_break_into_debugger("Error: free a non-existant block"); } return; } free_entry(entry); // free the memory if (USE_GUARD_PAGES) VirtualFree((UINT8 *)memory - ((UINT32)memory & (PAGE_SIZE-1)) - PAGE_SIZE, 0, MEM_RELEASE); else GlobalFree(memory); #if LOG_CALLS logerror("free #%06d size = %d\n", entry->id, entry->size); #endif }
void *realloc_file_line(void *memory, size_t size, const char *file, int line) { void *newmemory = NULL; // if size is non-zero, we need to reallocate memory if (size != 0) { // allocate space for the new amount newmemory = malloc_file_line(size, file, line); if (newmemory == NULL) return NULL; // if we have an old pointer, copy it if (memory != NULL) { memory_entry *entry = find_entry(memory); if (entry == NULL) { if (winalloc_in_main_code) { fprintf(stderr, "Error: realloc a non-existant block\n"); osd_break_into_debugger("Error: realloc a non-existant block"); } } else memcpy(newmemory, memory, (size < entry->size) ? size : entry->size); } } // if we have an original pointer, free it if (memory != NULL) free(memory); return newmemory; }
emu_fatalerror::emu_fatalerror(const char *format, va_list ap) : code(0) { if (format == nullptr) { text[0] = '\0'; } else { vsnprintf(text, sizeof(text), format, ap); } osd_break_into_debugger(text); }
void free_file_line(void *memory, const char *file, int line, bool array) { // find the memory entry memory_entry *entry = memory_entry::find(memory); // warn about untracked frees if (entry == nullptr) { fprintf(stderr, "Error: attempt to free untracked memory %p in %s(%d)!\n", memory, file, line); osd_break_into_debugger("Error: attempt to free untracked memory"); return; } // warn about mismatched arrays if (!array && entry->m_array) { fprintf(stderr, "Warning: attempt to free array %p with global_free in %s(%d)!\n", memory, file, line); if (DEBUG_MISMATCHED_ALLOCS) { osd_break_into_debugger("Error: attempt to free array with global_free"); } } if (array && !entry->m_array) { #ifndef __INTEL_COMPILER // todo: fix this properly, it appears some optimization the compiler applies breaks our logic here fprintf(stderr, "Warning: attempt to free single object %p with global_free_array in %s(%d)!\n", memory, file, line); if (DEBUG_MISMATCHED_ALLOCS) { osd_break_into_debugger("Error: attempt to free single object with global_free_array"); } #endif } #ifdef OVERWRITE_FREED_MEMORY // clear memory to a bogus value memset(memory, 0xfc, entry->m_size); #endif // free the entry and the memory memory_entry::release(entry, file, line); osd_free(memory); }
static void fatalerror_common(running_machine *machine, int exitcode, const char *buffer) { /* output and return */ mame_printf_error("%s\n", giant_string_buffer); /* break into the debugger if attached */ osd_break_into_debugger(giant_string_buffer); /* longjmp back if we can; otherwise, exit */ if (machine != NULL && machine->mame_data != NULL && machine->mame_data->fatal_error_jmpbuf_valid) longjmp(machine->mame_data->fatal_error_jmpbuf, exitcode); else exit(exitcode); }
size_t CLIB_DECL _msize(void *memory) { memory_entry *entry = find_entry(memory); if (entry == NULL) { if (winalloc_in_main_code) { fprintf(stderr, "Error: msize a non-existant block\n"); osd_break_into_debugger("Error: msize a non-existant block"); } return 0; } return entry->size; }
void *realloc_internal(void *memory, size_t size, const char *file, int line, bool array) { fprintf(stderr, "realloc_internal called for %p in %s(%d)!\n", memory, file, line); if(size == 0) { return nullptr; } if(memory == nullptr) { return malloc_file_line(size, file, line, array, false, false); } // find the memory entry memory_entry *entry = memory_entry::find(memory); // warn about untracked reallocs if (entry == nullptr) { fprintf(stderr, "Error: attempt to realloc untracked memory %p in %s(%d)!\n", memory, file, line); osd_break_into_debugger("Error: attempt to realloc untracked memory"); return memory; } // this is used internally and should always be an array if(!array || !entry->m_array) { fprintf(stderr, "Error: attempt to realloc non-array memory %p in %s(%d). realloc_internal should never be called directly!\n", memory, file, line); osd_break_into_debugger("Error: attempt to realloc non-array memory"); } size_t o_size = entry->m_size; void *new_buf = malloc_file_line(size, file, line, array, false, false); if(new_buf == nullptr) { fprintf(stderr, "Error: realloc: unable to allocate new buffer %p in %s(%d)!\n", memory, file, line); return nullptr; } memcpy(new_buf, memory, (o_size < size) ? o_size : size); free_file_line(memory, file, line, array); return new_buf; }
bool video_assert_out_of_range_pixels(running_machine &machine, bitmap_ind16 &bitmap) { #ifdef MAME_DEBUG // iterate over rows int maxindex = palette_get_max_index(machine.palette); for (int y = 0; y < bitmap.height(); y++) { UINT16 *rowbase = &bitmap.pix16(y); for (int x = 0; x < bitmap.width(); x++) if (rowbase[x] > maxindex) { osd_break_into_debugger("Out of range pixel"); return true; } } #endif return false; }