void write_basic_trace_file (void) { int fd, int_x; short short_x; fd = start_trace_file ("basic.tf"); /* The next part of the file consists of newline-separated lines defining status, tracepoints, etc. The section is terminated by an empty line. */ /* Dump the size of the R (register) blocks in traceframes. */ snprintf (spbuf, sizeof spbuf, "R %x\n", 500 /* FIXME get from arch */); write (fd, spbuf, strlen (spbuf)); /* Dump trace status, in the general form of the qTstatus reply. */ snprintf (spbuf, sizeof spbuf, "status 0;tstop:0;tframes:1;tcreated:1;tfree:100;tsize:1000\n"); write (fd, spbuf, strlen (spbuf)); /* Dump tracepoint definitions, in syntax similar to that used for reconnection uploads. */ /* FIXME need a portable way to print function address in hex */ snprintf (spbuf, sizeof spbuf, "tp T1:%lx:E:0:0\n", (long) &write_basic_trace_file); write (fd, spbuf, strlen (spbuf)); /* (Note that we would only need actions defined if we wanted to test tdump.) */ /* Empty line marks the end of the definition section. */ write (fd, "\n", 1); /* Make up a simulated trace buffer. */ /* (Encapsulate better if we're going to do lots of this; note that buffer endianness is the target program's enddianness.) */ trptr = trbuf; short_x = 1; memcpy (trptr, &short_x, 2); trptr += 2; tfsizeptr = trptr; trptr += 4; add_memory_block (&testglob, sizeof (testglob)); /* Divide a variable between two separate memory blocks. */ add_memory_block (&testglob2, 1); add_memory_block (((char*) &testglob2) + 1, sizeof (testglob2) - 1); /* Go back and patch in the frame size. */ int_x = trptr - tfsizeptr - sizeof (int); memcpy (tfsizeptr, &int_x, 4); /* Write end of tracebuffer marker. */ memset (trptr, 0, 6); trptr += 6; write (fd, trbuf, trptr - trbuf); finish_trace_file (fd); }
/* * Initialize the sysfs support for memory devices... */ int __init memory_dev_init(void) { unsigned int i; int ret; int err; unsigned long block_sz; ret = subsys_system_register(&memory_subsys, memory_root_attr_groups); if (ret) goto out; block_sz = get_memory_block_size(); sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; /* * Create entries for memory sections that were found * during boot and have been initialized */ mutex_lock(&mem_sysfs_mutex); for (i = 0; i < NR_MEM_SECTIONS; i += sections_per_block) { err = add_memory_block(i); if (!ret) ret = err; } mutex_unlock(&mem_sysfs_mutex); out: if (ret) printk(KERN_ERR "%s() failed: %d\n", __func__, ret); return ret; }
/****************************************************************** * dump_threads * * Dumps into File the information about running threads */ static void dump_threads(struct dump_context* dc) { MINIDUMP_THREAD mdThd; MINIDUMP_THREAD_LIST mdThdList; unsigned i; RVA rva_base; DWORD flags_out; CONTEXT ctx; mdThdList.NumberOfThreads = 0; rva_base = dc->rva; dc->rva += sizeof(mdThdList.NumberOfThreads) + dc->spi->dwThreadCount * sizeof(mdThd); for (i = 0; i < dc->spi->dwThreadCount; i++) { fetch_thread_info(dc, i, &mdThd, &ctx); flags_out = ThreadWriteThread | ThreadWriteStack | ThreadWriteContext | ThreadWriteInstructionWindow; if (dc->type & MiniDumpWithProcessThreadData) flags_out |= ThreadWriteThreadData; if (dc->type & MiniDumpWithThreadInfo) flags_out |= ThreadWriteThreadInfo; if (dc->cb) { MINIDUMP_CALLBACK_INPUT cbin; MINIDUMP_CALLBACK_OUTPUT cbout; cbin.ProcessId = dc->pid; cbin.ProcessHandle = dc->hProcess; cbin.CallbackType = ThreadCallback; cbin.u.Thread.ThreadId = dc->spi->ti[i].dwThreadID; cbin.u.Thread.ThreadHandle = 0; /* FIXME */ memcpy(&cbin.u.Thread.Context, &ctx, sizeof(CONTEXT)); cbin.u.Thread.SizeOfContext = sizeof(CONTEXT); cbin.u.Thread.StackBase = mdThd.Stack.StartOfMemoryRange; cbin.u.Thread.StackEnd = mdThd.Stack.StartOfMemoryRange + mdThd.Stack.Memory.DataSize; cbout.u.ThreadWriteFlags = flags_out; if (!dc->cb->CallbackRoutine(dc->cb->CallbackParam, &cbin, &cbout)) continue; flags_out &= cbout.u.ThreadWriteFlags; } if (flags_out & ThreadWriteThread) { if (ctx.ContextFlags && (flags_out & ThreadWriteContext)) { mdThd.ThreadContext.Rva = dc->rva; mdThd.ThreadContext.DataSize = sizeof(CONTEXT); append(dc, &ctx, sizeof(CONTEXT)); } if (mdThd.Stack.Memory.DataSize && (flags_out & ThreadWriteStack)) { add_memory_block(dc, mdThd.Stack.StartOfMemoryRange, mdThd.Stack.Memory.DataSize, rva_base + sizeof(mdThdList.NumberOfThreads) + mdThdList.NumberOfThreads * sizeof(mdThd) + FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva)); } writeat(dc, rva_base + sizeof(mdThdList.NumberOfThreads) + mdThdList.NumberOfThreads * sizeof(mdThd), &mdThd, sizeof(mdThd)); mdThdList.NumberOfThreads++; } if (ctx.ContextFlags && (flags_out & ThreadWriteInstructionWindow)) { /* FIXME: - Native dbghelp also dumps 0x80 bytes around EIP * - also crop values across module boundaries, * - and don't make it i386 dependent */ /* add_memory_block(dc, ctx.Eip - 0x80, ctx.Eip + 0x80, 0); */ } } writeat(dc, rva_base, &mdThdList.NumberOfThreads, sizeof(mdThdList.NumberOfThreads)); }