ReactOS  0.4.15-dev-1201-gb2cf5a4
minidump.c
Go to the documentation of this file.
1 /*
2  * File minidump.c - management of dumps (read & write)
3  *
4  * Copyright (C) 2004-2005, Eric Pouech
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <time.h>
22 
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
25 
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "dbghelp_private.h"
29 #include "winternl.h"
30 #include "psapi.h"
31 #include "wine/asm.h"
32 #include "wine/debug.h"
33 
35 
36 /******************************************************************
37  * fetch_process_info
38  *
39  * reads system wide process information, and gather from it the threads information
40  * for process of id 'pid'
41  */
43 {
44  ULONG buf_size = 0x1000;
45  NTSTATUS nts;
46  void* pcs_buffer = NULL;
47 
48  if (!(pcs_buffer = HeapAlloc(GetProcessHeap(), 0, buf_size))) return FALSE;
49  for (;;)
50  {
52  pcs_buffer, buf_size, NULL);
53  if (nts != STATUS_INFO_LENGTH_MISMATCH) break;
54  pcs_buffer = HeapReAlloc(GetProcessHeap(), 0, pcs_buffer, buf_size *= 2);
55  if (!pcs_buffer) return FALSE;
56  }
57 
58  if (nts == STATUS_SUCCESS)
59  {
60  SYSTEM_PROCESS_INFORMATION* spi = pcs_buffer;
61  unsigned i;
62 
63  for (;;)
64  {
65  if (HandleToUlong(spi->UniqueProcessId) == dc->pid)
66  {
67  dc->num_threads = spi->dwThreadCount;
68  dc->threads = HeapAlloc(GetProcessHeap(), 0,
69  dc->num_threads * sizeof(dc->threads[0]));
70  if (!dc->threads) goto failed;
71  for (i = 0; i < dc->num_threads; i++)
72  {
73  dc->threads[i].tid = HandleToULong(spi->ti[i].ClientId.UniqueThread);
74  dc->threads[i].prio_class = spi->ti[i].dwBasePriority; /* FIXME */
75  dc->threads[i].curr_prio = spi->ti[i].dwCurrentPriority;
76  }
77  HeapFree(GetProcessHeap(), 0, pcs_buffer);
78  return TRUE;
79  }
80  if (!spi->NextEntryOffset) break;
81  spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset);
82  }
83  }
84 failed:
85  HeapFree(GetProcessHeap(), 0, pcs_buffer);
86  return FALSE;
87 }
88 
89 static void fetch_thread_stack(struct dump_context* dc, const void* teb_addr,
91 {
92  NT_TIB tib;
94 
95  if (ReadProcessMemory(dc->process->handle, teb_addr, &tib, sizeof(tib), NULL) &&
97  dbghelp_current_cpu->get_addr(NULL /* FIXME */, ctx, cpu_addr_stack, &addr) && addr.Mode == AddrModeFlat)
98  {
99  if (addr.Offset)
100  {
101  addr.Offset -= dbghelp_current_cpu->word_size;
102  /* make sure stack pointer is within the established range of the stack. It could have
103  been clobbered by whatever caused the original exception. */
104  if (addr.Offset < (ULONG_PTR)tib.StackLimit || addr.Offset > (ULONG_PTR)tib.StackBase)
106 
107  else
108  mmd->StartOfMemoryRange = addr.Offset;
109  }
110  else
113  }
114 }
115 
116 /******************************************************************
117  * fetch_thread_info
118  *
119  * fetches some information about thread of id 'tid'
120  */
121 static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
123  MINIDUMP_THREAD* mdThd, CONTEXT* ctx)
124 {
125  DWORD tid = dc->threads[thd_idx].tid;
126  HANDLE hThread;
128 
129  memset(ctx, 0, sizeof(*ctx));
130 
131  mdThd->ThreadId = tid;
132  mdThd->SuspendCount = 0;
133  mdThd->Teb = 0;
134  mdThd->Stack.StartOfMemoryRange = 0;
135  mdThd->Stack.Memory.DataSize = 0;
136  mdThd->Stack.Memory.Rva = 0;
137  mdThd->ThreadContext.DataSize = 0;
138  mdThd->ThreadContext.Rva = 0;
139  mdThd->PriorityClass = dc->threads[thd_idx].prio_class;
140  mdThd->Priority = dc->threads[thd_idx].curr_prio;
141 
143  {
144  FIXME("Couldn't open thread %u (%u)\n", tid, GetLastError());
145  return FALSE;
146  }
147 
149  &tbi, sizeof(tbi), NULL) == STATUS_SUCCESS)
150  {
151  mdThd->Teb = (ULONG_PTR)tbi.TebBaseAddress;
152  if (tbi.ExitStatus == STILL_ACTIVE)
153  {
154  if (tid != GetCurrentThreadId() &&
155  (mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
156  {
157  ctx->ContextFlags = CONTEXT_FULL;
159  memset(ctx, 0, sizeof(*ctx));
160 
161  fetch_thread_stack(dc, tbi.TebBaseAddress, ctx, &mdThd->Stack);
163  }
164  else if (tid == GetCurrentThreadId() && except)
165  {
166  CONTEXT lctx, *pctx;
167  mdThd->SuspendCount = 1;
168  if (except->ClientPointers)
169  {
171 
172  ReadProcessMemory(dc->process->handle, except->ExceptionPointers,
173  &ep, sizeof(ep), NULL);
174  ReadProcessMemory(dc->process->handle, ep.ContextRecord,
175  &lctx, sizeof(lctx), NULL);
176  pctx = &lctx;
177  }
178  else pctx = except->ExceptionPointers->ContextRecord;
179 
180  *ctx = *pctx;
181  fetch_thread_stack(dc, tbi.TebBaseAddress, pctx, &mdThd->Stack);
182  }
183  else mdThd->SuspendCount = 0;
184  }
185  }
187  return TRUE;
188 }
189 
190 /******************************************************************
191  * add_module
192  *
193  * Add a module to a dump context
194  */
195 static BOOL add_module(struct dump_context* dc, const WCHAR* name,
197  BOOL is_elf)
198 {
199  if (!dc->modules)
200  {
201  dc->alloc_modules = 32;
202  dc->modules = HeapAlloc(GetProcessHeap(), 0,
203  dc->alloc_modules * sizeof(*dc->modules));
204  }
205  else if(dc->num_modules >= dc->alloc_modules)
206  {
207  dc->alloc_modules *= 2;
208  dc->modules = HeapReAlloc(GetProcessHeap(), 0, dc->modules,
209  dc->alloc_modules * sizeof(*dc->modules));
210  }
211  if (!dc->modules)
212  {
213  dc->alloc_modules = dc->num_modules = 0;
214  return FALSE;
215  }
216  if (is_elf ||
217  !GetModuleFileNameExW(dc->process->handle, (HMODULE)(DWORD_PTR)base,
218  dc->modules[dc->num_modules].name,
219  ARRAY_SIZE(dc->modules[dc->num_modules].name)))
220  lstrcpynW(dc->modules[dc->num_modules].name, name,
221  ARRAY_SIZE(dc->modules[dc->num_modules].name));
222  dc->modules[dc->num_modules].base = base;
223  dc->modules[dc->num_modules].size = size;
224  dc->modules[dc->num_modules].timestamp = timestamp;
225  dc->modules[dc->num_modules].checksum = checksum;
226  dc->modules[dc->num_modules].is_elf = is_elf;
227  dc->num_modules++;
228 
229  return TRUE;
230 }
231 
232 /******************************************************************
233  * fetch_pe_module_info_cb
234  *
235  * Callback for accumulating in dump_context a PE modules set
236  */
238  PVOID user)
239 {
240  struct dump_context* dc = user;
241  IMAGE_NT_HEADERS nth;
242 
243  if (!validate_addr64(base)) return FALSE;
244 
245  if (pe_load_nt_header(dc->process->handle, base, &nth))
248  FALSE);
249  return TRUE;
250 }
251 
252 /******************************************************************
253  * fetch_elf_module_info_cb
254  *
255  * Callback for accumulating in dump_context an host modules set
256  */
258  void* user)
259 {
260  struct dump_context* dc = user;
261  DWORD_PTR rbase;
263 
264  /* FIXME: there's no relevant timestamp on ELF modules */
265  if (!dc->process->loader->fetch_file_info(dc->process, name, base, &rbase, &size, &checksum))
266  size = checksum = 0;
267  add_module(dc, name, base ? base : rbase, size, 0 /* FIXME */, checksum, TRUE);
268  return TRUE;
269 }
270 
272 {
273  if (!dc->mem64)
274  {
275  dc->alloc_mem64 = 32;
276  dc->mem64 = HeapAlloc(GetProcessHeap(), 0, dc->alloc_mem64 * sizeof(*dc->mem64));
277  }
278  else if (dc->num_mem64 >= dc->alloc_mem64)
279  {
280  dc->alloc_mem64 *= 2;
281  dc->mem64 = HeapReAlloc(GetProcessHeap(), 0, dc->mem64,
282  dc->alloc_mem64 * sizeof(*dc->mem64));
283  }
284  if (dc->mem64)
285  {
286  dc->mem64[dc->num_mem64].base = base;
287  dc->mem64[dc->num_mem64].size = size;
288  dc->num_mem64++;
289  }
290  else dc->num_mem64 = dc->alloc_mem64 = 0;
291 }
292 
293 static void fetch_memory64_info(struct dump_context* dc)
294 {
295  ULONG_PTR addr;
297 
298  addr = 0;
299  while (VirtualQueryEx(dc->process->handle, (LPCVOID)addr, &mbi, sizeof(mbi)) != 0)
300  {
301  /* Memory regions with state MEM_COMMIT will be added to the dump */
302  if (mbi.State == MEM_COMMIT)
303  {
305  }
306 
307  if ((addr + mbi.RegionSize) < addr)
308  break;
309 
310  addr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize;
311  }
312 }
313 
314 static void fetch_modules_info(struct dump_context* dc)
315 {
317  /* Since we include ELF modules in a separate stream from the regular PE ones,
318  * we can always include those ELF modules (they don't eat lots of space)
319  * And it's always a good idea to have a trace of the loaded ELF modules for
320  * a given application in a post mortem debugging condition.
321  */
322  dc->process->loader->enum_modules(dc->process, fetch_host_module_info_cb, dc);
323 }
324 
326 {
327  DWORD handle;
328  DWORD sz;
329  static const WCHAR backslashW[] = {'\\', '\0'};
330 
331  memset(ffi, 0, sizeof(*ffi));
333  {
334  void* info = HeapAlloc(GetProcessHeap(), 0, sz);
336  {
338  UINT len;
339 
340  if (VerQueryValueW(info, backslashW, (void*)&ptr, &len))
341  memcpy(ffi, ptr, min(len, sizeof(*ffi)));
342  }
344  }
345 }
346 
347 /******************************************************************
348  * minidump_add_memory_block
349  *
350  * Add a memory block to be dumped in a minidump
351  * If rva is non 0, it's the rva in the minidump where has to be stored
352  * also the rva of the memory block when written (this allows us to reference
353  * a memory block from outside the list of memory blocks).
354  */
356 {
357  if (!dc->mem)
358  {
359  dc->alloc_mem = 32;
360  dc->mem = HeapAlloc(GetProcessHeap(), 0, dc->alloc_mem * sizeof(*dc->mem));
361  }
362  else if (dc->num_mem >= dc->alloc_mem)
363  {
364  dc->alloc_mem *= 2;
365  dc->mem = HeapReAlloc(GetProcessHeap(), 0, dc->mem,
366  dc->alloc_mem * sizeof(*dc->mem));
367  }
368  if (dc->mem)
369  {
370  dc->mem[dc->num_mem].base = base;
371  dc->mem[dc->num_mem].size = size;
372  dc->mem[dc->num_mem].rva = rva;
373  dc->num_mem++;
374  }
375  else dc->num_mem = dc->alloc_mem = 0;
376 }
377 
378 /******************************************************************
379  * writeat
380  *
381  * Writes a chunk of data at a given position in the minidump
382  */
383 static void writeat(struct dump_context* dc, RVA rva, const void* data, unsigned size)
384 {
385  DWORD written;
386 
387  SetFilePointer(dc->hFile, rva, NULL, FILE_BEGIN);
388  WriteFile(dc->hFile, data, size, &written, NULL);
389 }
390 
391 /******************************************************************
392  * append
393  *
394  * writes a new chunk of data to the minidump, increasing the current
395  * rva in dc
396  */
397 static void append(struct dump_context* dc, const void* data, unsigned size)
398 {
399  writeat(dc, dc->rva, data, size);
400  dc->rva += size;
401 }
402 
403 /******************************************************************
404  * dump_exception_info
405  *
406  * Write in File the exception information from pcs
407  */
408 static unsigned dump_exception_info(struct dump_context* dc,
410 {
412  EXCEPTION_RECORD rec, *prec;
413  CONTEXT ctx, *pctx;
414  DWORD i;
415 
416  mdExcpt.ThreadId = except->ThreadId;
417  mdExcpt.__alignment = 0;
418  if (except->ClientPointers)
419  {
421 
422  ReadProcessMemory(dc->process->handle,
423  except->ExceptionPointers, &ep, sizeof(ep), NULL);
424  ReadProcessMemory(dc->process->handle,
425  ep.ExceptionRecord, &rec, sizeof(rec), NULL);
426  ReadProcessMemory(dc->process->handle,
427  ep.ContextRecord, &ctx, sizeof(ctx), NULL);
428  prec = &rec;
429  pctx = &ctx;
430  }
431  else
432  {
433  prec = except->ExceptionPointers->ExceptionRecord;
434  pctx = except->ExceptionPointers->ContextRecord;
435  }
442  for (i = 0; i < mdExcpt.ExceptionRecord.NumberParameters; i++)
444  mdExcpt.ThreadContext.DataSize = sizeof(*pctx);
445  mdExcpt.ThreadContext.Rva = dc->rva + sizeof(mdExcpt);
446 
447  append(dc, &mdExcpt, sizeof(mdExcpt));
448  append(dc, pctx, sizeof(*pctx));
449  return sizeof(mdExcpt);
450 }
451 
452 /******************************************************************
453  * dump_modules
454  *
455  * Write in File the modules from pcs
456  */
457 static unsigned dump_modules(struct dump_context* dc, BOOL dump_elf)
458 {
460  MINIDUMP_MODULE_LIST mdModuleList;
461  char tmp[1024];
462  MINIDUMP_STRING* ms = (MINIDUMP_STRING*)tmp;
463  ULONG i, nmod;
464  RVA rva_base;
466  unsigned sz;
467 
468  for (i = nmod = 0; i < dc->num_modules; i++)
469  {
470  if ((dc->modules[i].is_elf && dump_elf) ||
471  (!dc->modules[i].is_elf && !dump_elf))
472  nmod++;
473  }
474 
475  mdModuleList.NumberOfModules = 0;
476  /* reserve space for mdModuleList
477  * FIXME: since we don't support 0 length arrays, we cannot use the
478  * size of mdModuleList
479  * FIXME: if we don't ask for all modules in cb, we'll get a hole in the file
480  */
481 
482  /* the stream size is just the size of the module index. It does not include the data for the
483  names of each module. *Technically* the names are supposed to go into the common string table
484  in the minidump file. Since each string is referenced by RVA they can all safely be located
485  anywhere between streams in the file, so the end of this stream is sufficient. */
486  rva_base = dc->rva;
487  dc->rva += sz = sizeof(mdModuleList.NumberOfModules) + sizeof(mdModule) * nmod;
488  for (i = 0; i < dc->num_modules; i++)
489  {
490  if ((dc->modules[i].is_elf && !dump_elf) ||
491  (!dc->modules[i].is_elf && dump_elf))
492  continue;
493 
495  if (dc->type & MiniDumpWithDataSegs)
497  if (dc->type & MiniDumpWithProcessThreadData)
499  if (dc->type & MiniDumpWithCodeSegs)
501  ms->Length = (lstrlenW(dc->modules[i].name) + 1) * sizeof(WCHAR);
502  if (sizeof(ULONG) + ms->Length > sizeof(tmp))
503  FIXME("Buffer overflow!!!\n");
504  lstrcpyW(ms->Buffer, dc->modules[i].name);
505 
506  if (dc->cb)
507  {
510 
511  cbin.ProcessId = dc->pid;
512  cbin.ProcessHandle = dc->process->handle;
514 
515  cbin.u.Module.FullPath = ms->Buffer;
516  cbin.u.Module.BaseOfImage = dc->modules[i].base;
517  cbin.u.Module.SizeOfImage = dc->modules[i].size;
518  cbin.u.Module.CheckSum = dc->modules[i].checksum;
519  cbin.u.Module.TimeDateStamp = dc->modules[i].timestamp;
520  memset(&cbin.u.Module.VersionInfo, 0, sizeof(cbin.u.Module.VersionInfo));
521  cbin.u.Module.CvRecord = NULL;
522  cbin.u.Module.SizeOfCvRecord = 0;
523  cbin.u.Module.MiscRecord = NULL;
524  cbin.u.Module.SizeOfMiscRecord = 0;
525 
526  cbout.u.ModuleWriteFlags = flags_out;
527  if (!dc->cb->CallbackRoutine(dc->cb->CallbackParam, &cbin, &cbout))
528  continue;
529  flags_out &= cbout.u.ModuleWriteFlags;
530  }
532  {
533  /* fetch CPU dependent module info (like UNWIND_INFO) */
534  dbghelp_current_cpu->fetch_minidump_module(dc, i, flags_out);
535 
536  mdModule.BaseOfImage = dc->modules[i].base;
537  mdModule.SizeOfImage = dc->modules[i].size;
538  mdModule.CheckSum = dc->modules[i].checksum;
539  mdModule.TimeDateStamp = dc->modules[i].timestamp;
540  mdModule.ModuleNameRva = dc->rva;
541  ms->Length -= sizeof(WCHAR);
542  append(dc, ms, sizeof(ULONG) + ms->Length + sizeof(WCHAR));
543  fetch_module_versioninfo(ms->Buffer, &mdModule.VersionInfo);
544  mdModule.CvRecord.DataSize = 0; /* FIXME */
545  mdModule.CvRecord.Rva = 0; /* FIXME */
546  mdModule.MiscRecord.DataSize = 0; /* FIXME */
547  mdModule.MiscRecord.Rva = 0; /* FIXME */
548  mdModule.Reserved0 = 0; /* FIXME */
549  mdModule.Reserved1 = 0; /* FIXME */
550  writeat(dc,
551  rva_base + sizeof(mdModuleList.NumberOfModules) +
552  mdModuleList.NumberOfModules++ * sizeof(mdModule),
553  &mdModule, sizeof(mdModule));
554  }
555  }
556  writeat(dc, rva_base, &mdModuleList.NumberOfModules,
557  sizeof(mdModuleList.NumberOfModules));
558 
559  return sz;
560 }
561 
562 #ifdef __i386__
563 #ifndef __REACTOS__
564 extern void do_x86cpuid(unsigned int ax, unsigned int *p);
566  "pushl %esi\n\t"
567  "pushl %ebx\n\t"
568  "movl 12(%esp),%eax\n\t"
569  "movl 16(%esp),%esi\n\t"
570  "cpuid\n\t"
571  "movl %eax,(%esi)\n\t"
572  "movl %ebx,4(%esi)\n\t"
573  "movl %ecx,8(%esi)\n\t"
574  "movl %edx,12(%esi)\n\t"
575  "popl %ebx\n\t"
576  "popl %esi\n\t"
577  "ret" )
578 extern int have_x86cpuid(void);
580  "pushfl\n\t"
581  "pushfl\n\t"
582  "movl (%esp),%ecx\n\t"
583  "xorl $0x00200000,(%esp)\n\t"
584  "popfl\n\t"
585  "pushfl\n\t"
586  "popl %eax\n\t"
587  "popfl\n\t"
588  "xorl %ecx,%eax\n\t"
589  "andl $0x00200000,%eax\n\t"
590  "ret" )
591 #else
592 static void do_x86cpuid(unsigned int ax, unsigned int *p)
593 {
594  __cpuid((int*)p, ax);
595 }
596 
597 static int have_x86cpuid(void)
598 {
599  ULONG CallerFlags, Flags;
600 
601  /* Read the original flags, and add the CPUID bit */
602  CallerFlags = __readeflags() ^ 0x200000;
603  __writeeflags(CallerFlags);
604 
605  /* Read our flags now */
606  Flags = __readeflags();
607 
608  /* Check if the bit stuck */
609  return (((CallerFlags ^ Flags) >> 21) & 1) ^ 1;
610 }
611 #endif
612 #else
613 static void do_x86cpuid(unsigned int ax, unsigned int *p)
614 {
615 }
616 
617 static int have_x86cpuid(void)
618 {
619  return 0;
620 }
621 #endif
622 
623 /******************************************************************
624  * dump_system_info
625  *
626  * Dumps into File the information about the system
627  */
628 static unsigned dump_system_info(struct dump_context* dc)
629 {
630  MINIDUMP_SYSTEM_INFO mdSysInfo;
631  SYSTEM_INFO sysInfo;
632  OSVERSIONINFOW osInfo;
633  DWORD written;
634  ULONG slen;
635  DWORD wine_extra = 0;
636 
637  const char *(CDECL *wine_get_build_id)(void);
638  void (CDECL *wine_get_host_version)(const char **sysname, const char **release);
639  const char* build_id = NULL;
640  const char* sys_name = NULL;
641  const char* release_name = NULL;
642 
643  GetSystemInfo(&sysInfo);
644  osInfo.dwOSVersionInfoSize = sizeof(osInfo);
645  GetVersionExW(&osInfo);
646 
647  wine_get_build_id = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_build_id");
648  wine_get_host_version = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_host_version");
649  if (wine_get_build_id && wine_get_host_version)
650  {
651  /* cheat minidump system information by adding specific wine information */
652  wine_extra = 4 + 4 * sizeof(slen);
653  build_id = wine_get_build_id();
654  wine_get_host_version(&sys_name, &release_name);
655  wine_extra += strlen(build_id) + 1 + strlen(sys_name) + 1 + strlen(release_name) + 1;
656  }
657 
658  mdSysInfo.ProcessorArchitecture = sysInfo.u.s.wProcessorArchitecture;
659  mdSysInfo.ProcessorLevel = sysInfo.wProcessorLevel;
660  mdSysInfo.ProcessorRevision = sysInfo.wProcessorRevision;
661  mdSysInfo.u.s.NumberOfProcessors = sysInfo.dwNumberOfProcessors;
662  mdSysInfo.u.s.ProductType = VER_NT_WORKSTATION; /* FIXME */
663  mdSysInfo.MajorVersion = osInfo.dwMajorVersion;
664  mdSysInfo.MinorVersion = osInfo.dwMinorVersion;
665  mdSysInfo.BuildNumber = osInfo.dwBuildNumber;
666  mdSysInfo.PlatformId = osInfo.dwPlatformId;
667 
668  mdSysInfo.CSDVersionRva = dc->rva + sizeof(mdSysInfo) + wine_extra;
669  mdSysInfo.u1.Reserved1 = 0;
670  mdSysInfo.u1.s.SuiteMask = VER_SUITE_TERMINAL;
671 
672  if (have_x86cpuid())
673  {
674  unsigned regs0[4], regs1[4];
675 
676  do_x86cpuid(0, regs0);
677  mdSysInfo.Cpu.X86CpuInfo.VendorId[0] = regs0[1];
678  mdSysInfo.Cpu.X86CpuInfo.VendorId[1] = regs0[3];
679  mdSysInfo.Cpu.X86CpuInfo.VendorId[2] = regs0[2];
680  do_x86cpuid(1, regs1);
681  mdSysInfo.Cpu.X86CpuInfo.VersionInformation = regs1[0];
682  mdSysInfo.Cpu.X86CpuInfo.FeatureInformation = regs1[3];
683  mdSysInfo.Cpu.X86CpuInfo.AMDExtendedCpuFeatures = 0;
684  if (regs0[1] == 0x68747541 /* "Auth" */ &&
685  regs0[3] == 0x69746e65 /* "enti" */ &&
686  regs0[2] == 0x444d4163 /* "cAMD" */)
687  {
688  do_x86cpuid(0x80000000, regs1); /* get vendor cpuid level */
689  if (regs1[0] >= 0x80000001)
690  {
691  do_x86cpuid(0x80000001, regs1); /* get vendor features */
692  mdSysInfo.Cpu.X86CpuInfo.AMDExtendedCpuFeatures = regs1[3];
693  }
694  }
695  }
696  else
697  {
698  unsigned i;
699  ULONG64 one = 1;
700 
701  mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] = 0;
702  mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[1] = 0;
703 
704  for (i = 0; i < sizeof(mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0]) * 8; i++)
706  mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] |= one << i;
707  }
708  append(dc, &mdSysInfo, sizeof(mdSysInfo));
709 
710  /* write Wine specific system information just behind the structure, and before any string */
711  if (wine_extra)
712  {
713  static const char code[] = {'W','I','N','E'};
714 
715  WriteFile(dc->hFile, code, 4, &written, NULL);
716  /* number of sub-info, so that we can extend structure if needed */
717  slen = 3;
718  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
719  /* we store offsets from just after the WINE marker */
720  slen = 4 * sizeof(DWORD);
721  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
722  slen += strlen(build_id) + 1;
723  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
724  slen += strlen(sys_name) + 1;
725  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
726  WriteFile(dc->hFile, build_id, strlen(build_id) + 1, &written, NULL);
727  WriteFile(dc->hFile, sys_name, strlen(sys_name) + 1, &written, NULL);
728  WriteFile(dc->hFile, release_name, strlen(release_name) + 1, &written, NULL);
729  dc->rva += wine_extra;
730  }
731 
732  /* write the service pack version string after this stream. It is referenced within the
733  stream by its RVA in the file. */
734  slen = lstrlenW(osInfo.szCSDVersion) * sizeof(WCHAR);
735  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
736  WriteFile(dc->hFile, osInfo.szCSDVersion, slen, &written, NULL);
737  dc->rva += sizeof(ULONG) + slen;
738 
739  return sizeof(mdSysInfo);
740 }
741 
742 /******************************************************************
743  * dump_threads
744  *
745  * Dumps into File the information about running threads
746  */
747 static unsigned dump_threads(struct dump_context* dc,
749 {
750  MINIDUMP_THREAD mdThd;
751  MINIDUMP_THREAD_LIST mdThdList;
752  unsigned i, sz;
753  RVA rva_base;
755  CONTEXT ctx;
756 
757  mdThdList.NumberOfThreads = 0;
758 
759  rva_base = dc->rva;
760  dc->rva += sz = sizeof(mdThdList.NumberOfThreads) + dc->num_threads * sizeof(mdThd);
761 
762  for (i = 0; i < dc->num_threads; i++)
763  {
764  fetch_thread_info(dc, i, except, &mdThd, &ctx);
765 
768  if (dc->type & MiniDumpWithProcessThreadData)
770  if (dc->type & MiniDumpWithThreadInfo)
772 
773  if (dc->cb)
774  {
777 
778  cbin.ProcessId = dc->pid;
779  cbin.ProcessHandle = dc->process->handle;
781  cbin.u.Thread.ThreadId = dc->threads[i].tid;
782  cbin.u.Thread.ThreadHandle = 0; /* FIXME */
783  cbin.u.Thread.Context = ctx;
784  cbin.u.Thread.SizeOfContext = sizeof(CONTEXT);
785  cbin.u.Thread.StackBase = mdThd.Stack.StartOfMemoryRange;
786  cbin.u.Thread.StackEnd = mdThd.Stack.StartOfMemoryRange +
787  mdThd.Stack.Memory.DataSize;
788 
789  cbout.u.ThreadWriteFlags = flags_out;
790  if (!dc->cb->CallbackRoutine(dc->cb->CallbackParam, &cbin, &cbout))
791  continue;
792  flags_out &= cbout.u.ThreadWriteFlags;
793  }
795  {
796  if (ctx.ContextFlags && (flags_out & ThreadWriteContext))
797  {
798  mdThd.ThreadContext.Rva = dc->rva;
799  mdThd.ThreadContext.DataSize = sizeof(CONTEXT);
800  append(dc, &ctx, sizeof(CONTEXT));
801  }
803  {
805  mdThd.Stack.Memory.DataSize,
806  rva_base + sizeof(mdThdList.NumberOfThreads) +
807  mdThdList.NumberOfThreads * sizeof(mdThd) +
808  FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva));
809  }
810  writeat(dc,
811  rva_base + sizeof(mdThdList.NumberOfThreads) +
812  mdThdList.NumberOfThreads * sizeof(mdThd),
813  &mdThd, sizeof(mdThd));
814  mdThdList.NumberOfThreads++;
815  }
816  /* fetch CPU dependent thread info (like 256 bytes around program counter */
817  dbghelp_current_cpu->fetch_minidump_thread(dc, i, flags_out, &ctx);
818  }
819  writeat(dc, rva_base,
820  &mdThdList.NumberOfThreads, sizeof(mdThdList.NumberOfThreads));
821 
822  return sz;
823 }
824 
825 /******************************************************************
826  * dump_memory_info
827  *
828  * dumps information about the memory of the process (stack of the threads)
829  */
830 static unsigned dump_memory_info(struct dump_context* dc)
831 {
832  MINIDUMP_MEMORY_LIST mdMemList;
834  DWORD written;
835  unsigned i, pos, len, sz;
836  RVA rva_base;
837  char tmp[1024];
838 
839  mdMemList.NumberOfMemoryRanges = dc->num_mem;
840  append(dc, &mdMemList.NumberOfMemoryRanges,
841  sizeof(mdMemList.NumberOfMemoryRanges));
842  rva_base = dc->rva;
843  sz = mdMemList.NumberOfMemoryRanges * sizeof(mdMem);
844  dc->rva += sz;
845  sz += sizeof(mdMemList.NumberOfMemoryRanges);
846 
847  for (i = 0; i < dc->num_mem; i++)
848  {
849  mdMem.StartOfMemoryRange = dc->mem[i].base;
850  mdMem.Memory.Rva = dc->rva;
851  mdMem.Memory.DataSize = dc->mem[i].size;
852  SetFilePointer(dc->hFile, dc->rva, NULL, FILE_BEGIN);
853  for (pos = 0; pos < dc->mem[i].size; pos += sizeof(tmp))
854  {
855  len = min(dc->mem[i].size - pos, sizeof(tmp));
856  if (read_process_memory(dc->process, dc->mem[i].base + pos, tmp, len))
857  WriteFile(dc->hFile, tmp, len, &written, NULL);
858  }
859  dc->rva += mdMem.Memory.DataSize;
860  writeat(dc, rva_base + i * sizeof(mdMem), &mdMem, sizeof(mdMem));
861  if (dc->mem[i].rva)
862  {
863  writeat(dc, dc->mem[i].rva, &mdMem.Memory.Rva, sizeof(mdMem.Memory.Rva));
864  }
865  }
866 
867  return sz;
868 }
869 
870 /******************************************************************
871  * dump_memory64_info
872  *
873  * dumps information about the memory of the process (virtual memory)
874  */
875 static unsigned dump_memory64_info(struct dump_context* dc)
876 {
877  MINIDUMP_MEMORY64_LIST mdMem64List;
879  DWORD written;
880  unsigned i, len, sz;
881  RVA rva_base;
882  char tmp[1024];
883  ULONG64 pos;
884  LARGE_INTEGER filepos;
885 
886  sz = sizeof(mdMem64List.NumberOfMemoryRanges) +
887  sizeof(mdMem64List.BaseRva) +
888  dc->num_mem64 * sizeof(mdMem64);
889 
890  mdMem64List.NumberOfMemoryRanges = dc->num_mem64;
891  mdMem64List.BaseRva = dc->rva + sz;
892 
893  append(dc, &mdMem64List.NumberOfMemoryRanges,
894  sizeof(mdMem64List.NumberOfMemoryRanges));
895  append(dc, &mdMem64List.BaseRva,
896  sizeof(mdMem64List.BaseRva));
897 
898  rva_base = dc->rva;
899  dc->rva += dc->num_mem64 * sizeof(mdMem64);
900 
901  /* dc->rva is not updated past this point. The end of the dump
902  * is just the full memory data. */
903  filepos.QuadPart = dc->rva;
904  for (i = 0; i < dc->num_mem64; i++)
905  {
906  mdMem64.StartOfMemoryRange = dc->mem64[i].base;
907  mdMem64.DataSize = dc->mem64[i].size;
908  SetFilePointerEx(dc->hFile, filepos, NULL, FILE_BEGIN);
909  for (pos = 0; pos < dc->mem64[i].size; pos += sizeof(tmp))
910  {
911  len = min(dc->mem64[i].size - pos, sizeof(tmp));
912  if (read_process_memory(dc->process, dc->mem64[i].base + pos, tmp, len))
913  WriteFile(dc->hFile, tmp, len, &written, NULL);
914  }
915  filepos.QuadPart += mdMem64.DataSize;
916  writeat(dc, rva_base + i * sizeof(mdMem64), &mdMem64, sizeof(mdMem64));
917  }
918 
919  return sz;
920 }
921 
922 static unsigned dump_misc_info(struct dump_context* dc)
923 {
924  MINIDUMP_MISC_INFO mmi;
925 
926  mmi.SizeOfInfo = sizeof(mmi);
928  mmi.ProcessId = dc->pid;
929  /* FIXME: create/user/kernel time */
930  mmi.ProcessCreateTime = 0;
931  mmi.ProcessKernelTime = 0;
932  mmi.ProcessUserTime = 0;
933 
934  append(dc, &mmi, sizeof(mmi));
935  return sizeof(mmi);
936 }
937 
938 /******************************************************************
939  * MiniDumpWriteDump (DEBUGHLP.@)
940  *
941  */
944  PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
945  PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
946  PMINIDUMP_CALLBACK_INFORMATION CallbackParam)
947 {
948  static const MINIDUMP_DIRECTORY emptyDir = {UnusedStream, {0, 0}};
949  MINIDUMP_HEADER mdHead;
950  MINIDUMP_DIRECTORY mdDir;
951  DWORD i, nStreams, idx_stream;
952  struct dump_context dc;
953  BOOL sym_initialized = FALSE;
954 
955  if (!(dc.process = process_find_by_handle(hProcess)))
956  {
957  if (!(sym_initialized = SymInitializeW(hProcess, NULL, TRUE)))
958  {
959  WARN("failed to initialize process\n");
960  return FALSE;
961  }
963  }
964 
965  dc.hFile = hFile;
966  dc.pid = pid;
967  dc.modules = NULL;
968  dc.num_modules = 0;
969  dc.alloc_modules = 0;
970  dc.threads = NULL;
971  dc.num_threads = 0;
972  dc.cb = CallbackParam;
973  dc.type = DumpType;
974  dc.mem = NULL;
975  dc.num_mem = 0;
976  dc.alloc_mem = 0;
977  dc.mem64 = NULL;
978  dc.num_mem64 = 0;
979  dc.alloc_mem64 = 0;
980  dc.rva = 0;
981 
982  if (!fetch_process_info(&dc)) return FALSE;
984 
985  /* 1) init */
986  nStreams = 6 + (ExceptionParam ? 1 : 0) +
987  (UserStreamParam ? UserStreamParam->UserStreamCount : 0);
988 
989  /* pad the directory size to a multiple of 4 for alignment purposes */
990  nStreams = (nStreams + 3) & ~3;
991 
993  FIXME("NIY MiniDumpWithDataSegs\n");
995  FIXME("NIY MiniDumpWithHandleData\n");
997  FIXME("NIY MiniDumpFilterMemory\n");
999  FIXME("NIY MiniDumpScanMemory\n");
1000 
1001  /* 2) write header */
1002  mdHead.Signature = MINIDUMP_SIGNATURE;
1003  mdHead.Version = MINIDUMP_VERSION; /* NOTE: native puts in an 'implementation specific' value in the high order word of this member */
1004  mdHead.NumberOfStreams = nStreams;
1005  mdHead.CheckSum = 0; /* native sets a 0 checksum in its files */
1006  mdHead.StreamDirectoryRva = sizeof(mdHead);
1007  mdHead.u.TimeDateStamp = time(NULL);
1008  mdHead.Flags = DumpType;
1009  append(&dc, &mdHead, sizeof(mdHead));
1010 
1011  /* 3) write stream directories */
1012  dc.rva += nStreams * sizeof(mdDir);
1013  idx_stream = 0;
1014 
1015  /* 3.1) write data stream directories */
1016 
1017  /* must be first in minidump */
1018  mdDir.StreamType = SystemInfoStream;
1019  mdDir.Location.Rva = dc.rva;
1021  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1022  &mdDir, sizeof(mdDir));
1023 
1024  mdDir.StreamType = ThreadListStream;
1025  mdDir.Location.Rva = dc.rva;
1026  mdDir.Location.DataSize = dump_threads(&dc, ExceptionParam);
1027  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1028  &mdDir, sizeof(mdDir));
1029 
1030  mdDir.StreamType = ModuleListStream;
1031  mdDir.Location.Rva = dc.rva;
1032  mdDir.Location.DataSize = dump_modules(&dc, FALSE);
1033  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1034  &mdDir, sizeof(mdDir));
1035 
1036  mdDir.StreamType = 0xfff0; /* FIXME: this is part of MS reserved streams */
1037  mdDir.Location.Rva = dc.rva;
1038  mdDir.Location.DataSize = dump_modules(&dc, TRUE);
1039  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1040  &mdDir, sizeof(mdDir));
1041 
1042 
1044  {
1045  mdDir.StreamType = MemoryListStream;
1046  mdDir.Location.Rva = dc.rva;
1048  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1049  &mdDir, sizeof(mdDir));
1050  }
1051 
1052  mdDir.StreamType = MiscInfoStream;
1053  mdDir.Location.Rva = dc.rva;
1054  mdDir.Location.DataSize = dump_misc_info(&dc);
1055  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1056  &mdDir, sizeof(mdDir));
1057 
1058  /* 3.2) write exception information (if any) */
1059  if (ExceptionParam)
1060  {
1061  mdDir.StreamType = ExceptionStream;
1062  mdDir.Location.Rva = dc.rva;
1063  mdDir.Location.DataSize = dump_exception_info(&dc, ExceptionParam);
1064  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1065  &mdDir, sizeof(mdDir));
1066  }
1067 
1068  /* 3.3) write user defined streams (if any) */
1069  if (UserStreamParam)
1070  {
1071  for (i = 0; i < UserStreamParam->UserStreamCount; i++)
1072  {
1073  mdDir.StreamType = UserStreamParam->UserStreamArray[i].Type;
1074  mdDir.Location.DataSize = UserStreamParam->UserStreamArray[i].BufferSize;
1075  mdDir.Location.Rva = dc.rva;
1076  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1077  &mdDir, sizeof(mdDir));
1078  append(&dc, UserStreamParam->UserStreamArray[i].Buffer,
1079  UserStreamParam->UserStreamArray[i].BufferSize);
1080  }
1081  }
1082 
1083  /* 3.4) write full memory (if requested) */
1085  {
1087 
1089  mdDir.Location.Rva = dc.rva;
1091  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
1092  &mdDir, sizeof(mdDir));
1093  }
1094 
1095  /* fill the remaining directory entries with 0's (unused stream types) */
1096  /* NOTE: this should always come last in the dump! */
1097  for (i = idx_stream; i < nStreams; i++)
1098  writeat(&dc, mdHead.StreamDirectoryRva + i * sizeof(emptyDir), &emptyDir, sizeof(emptyDir));
1099 
1100  if (sym_initialized)
1102 
1103  HeapFree(GetProcessHeap(), 0, dc.mem);
1104  HeapFree(GetProcessHeap(), 0, dc.mem64);
1105  HeapFree(GetProcessHeap(), 0, dc.modules);
1106  HeapFree(GetProcessHeap(), 0, dc.threads);
1107 
1108  return TRUE;
1109 }
1110 
1111 /******************************************************************
1112  * MiniDumpReadDumpStream (DEBUGHLP.@)
1113  *
1114  *
1115  */
1117  PMINIDUMP_DIRECTORY* pdir,
1118  PVOID* stream, ULONG* size)
1119 {
1120  MINIDUMP_HEADER* mdHead = base;
1121 
1122  if (mdHead->Signature == MINIDUMP_SIGNATURE)
1123  {
1125  DWORD i;
1126 
1127  dir = (MINIDUMP_DIRECTORY*)((char*)base + mdHead->StreamDirectoryRva);
1128  for (i = 0; i < mdHead->NumberOfStreams; i++, dir++)
1129  {
1130  if (dir->StreamType == str_idx)
1131  {
1132  if (pdir) *pdir = dir;
1133  if (stream) *stream = (char*)base + dir->Location.Rva;
1134  if (size) *size = dir->Location.DataSize;
1135  return TRUE;
1136  }
1137  }
1138  }
1140  return FALSE;
1141 }
BOOL WINAPI SymCleanup(HANDLE hProcess)
Definition: dbghelp.c:531
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
ULONG NumberOfMemoryRanges
Definition: dbghelp.h:809
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
#define VER_NT_WORKSTATION
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
const uint16_t * PCWSTR
Definition: typedefs.h:57
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
static void minidump_add_memory64_block(struct dump_context *dc, ULONG64 base, ULONG64 size)
Definition: minidump.c:271
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
#define CloseHandle
Definition: compat.h:598
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static unsigned dump_modules(struct dump_context *dc, BOOL dump_elf)
Definition: minidump.c:457
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
DWORD NumberOfStreams
Definition: dbghelp.h:790
#define DWORD_PTR
Definition: treelist.c:76
ULONG NumberParameters
Definition: dbghelp.h:766
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
WCHAR Buffer[1]
Definition: dbghelp.h:862
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext
Definition: dbghelp.h:920
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
union _MINIDUMP_SYSTEM_INFO::_CPU_INFORMATION Cpu
VOID DumpType(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers)
Definition: symdump.c:695
#define TRUE
Definition: types.h:120
#define MINIDUMP_VERSION
Definition: dbghelp.h:599
MINIDUMP_THREAD_CALLBACK Thread
Definition: compat.h:1189
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam)
Definition: minidump.c:942
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
#define HandleToUlong(h)
Definition: basetsd.h:79
WCHAR szCSDVersion[128]
Definition: rtltypes.h:251
BOOL validate_addr64(DWORD64 addr)
Definition: dbghelp.c:112
GLdouble n
Definition: glext.h:7729
GLdouble GLdouble t
Definition: gl.h:2047
MINIDUMP_MODULE_CALLBACK Module
Definition: compat.h:1191
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
#define HandleToULong(h)
Definition: basetsd.h:95
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:617
static BOOL fetch_host_module_info_cb(const WCHAR *name, ULONG_PTR base, void *user)
Definition: minidump.c:257
#define FILE_BEGIN
Definition: compat.h:620
__u16 time
Definition: mkdosfs.c:366
#define VER_SUITE_TERMINAL
static void append(struct dump_context *dc, const void *data, unsigned size)
Definition: minidump.c:397
BOOL WINAPI GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
Definition: version.c:37
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:609
#define MEM_COMMIT
Definition: nt_native.h:1313
#define DWORD
Definition: nt_native.h:44
ULONG64 Flags
Definition: dbghelp.h:798
struct _CONTEXT CONTEXT
#define MINIDUMP_MISC1_PROCESS_ID
Definition: dbghelp.h:826
PVOID ExceptionAddress
Definition: compat.h:211
static BOOL fetch_process_info(struct dump_context *dc)
Definition: minidump.c:42
#define lstrcpynW
Definition: compat.h:597
static double one
Definition: j0_y0.c:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
DWORD ExceptionCode
Definition: compat.h:208
static void fetch_thread_stack(struct dump_context *dc, const void *teb_addr, const CONTEXT *ctx, MINIDUMP_MEMORY_DESCRIPTOR *mmd)
Definition: minidump.c:89
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:500
UCHAR NumberOfProcessors
Definition: dbghelp.h:875
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
WORD wProcessorRevision
Definition: winbase.h:1147
ULONG __unusedAlignment
Definition: dbghelp.h:767
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1569
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint base
Definition: 3dtext.c:35
USHORT ProcessorArchitecture
Definition: dbghelp.h:867
ULONG ExceptionFlags
Definition: dbghelp.h:763
BOOL WINAPI MiniDumpReadDumpStream(PVOID base, ULONG str_idx, PMINIDUMP_DIRECTORY *pdir, PVOID *stream, ULONG *size)
Definition: minidump.c:1116
BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS *nth) DECLSPEC_HIDDEN
Definition: pe_module.c:877
#define FIXME(fmt,...)
Definition: debug.h:111
MINIDUMP_LOCATION_DESCRIPTOR Location
Definition: dbghelp.h:757
static PVOID ptr
Definition: dispmode.c:27
ecx edi movl
Definition: synth_sse3d.h:75
ULONG64 ExceptionAddress
Definition: dbghelp.h:765
static unsigned dump_threads(struct dump_context *dc, const MINIDUMP_EXCEPTION_INFORMATION *except)
Definition: minidump.c:747
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 mm1 mm5 paddd mm0 paddd mm4 mm0 mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 mm1 paddd mm0 mm0 packssdw mm0 movd eax movw ax
Definition: synth_sse3d.h:171
#define GetModuleFileNameExW(w, x, y, z)
Definition: compat.h:781
ULONG ProcessKernelTime
Definition: dbghelp.h:836
smooth NULL
Definition: ftsmooth.c:416
MINIDUMP_EXCEPTION ExceptionRecord
Definition: dbghelp.h:782
VS_FIXEDFILEINFO VersionInfo
Definition: compat.h:1168
INT nStreams
Definition: api.c:60
static void fetch_modules_info(struct dump_context *dc)
Definition: minidump.c:314
unsigned int dir
Definition: maze.c:112
mdToken mdModule
Definition: cordebug.idl:72
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
ULONG ThreadId
Definition: dbghelp.h:914
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:458
BOOL WINAPI EnumerateLoadedModulesW64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1108
struct _MINIDUMP_SYSTEM_INFO::_CPU_INFORMATION::@2782 OtherCpuInfo
SIZE_T NTAPI VirtualQueryEx(IN HANDLE hProcess, IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:236
PCONTEXT ContextRecord
Definition: rtltypes.h:201
static const WCHAR backslashW[]
static unsigned dump_memory_info(struct dump_context *dc)
Definition: minidump.c:830
#define CONTEXT_FULL
Definition: nt_native.h:1375
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
GLsizeiptr size
Definition: glext.h:5919
ULONG dwMajorVersion
Definition: rtltypes.h:247
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl eax
Definition: synth_sse3d.h:85
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD TimeDateStamp
Definition: dbghelp.h:796
#define STILL_ACTIVE
Definition: winbase.h:230
static unsigned dump_misc_info(struct dump_context *dc)
Definition: minidump.c:922
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:246
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned flags_out
#define SetLastError(x)
Definition: compat.h:611
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2501
ULONG dwBuildNumber
Definition: rtltypes.h:249
unsigned __int64 ULONG64
Definition: imports.h:198
static unsigned dump_memory64_info(struct dump_context *dc)
Definition: minidump.c:875
int ret
GLenum const GLvoid * addr
Definition: glext.h:9621
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:641
Definition: parse.h:22
struct _MINIDUMP_SYSTEM_INFO::_CPU_INFORMATION::@2781 X86CpuInfo
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1564
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:611
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
HANDLE WINAPI OpenThread(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwThreadId)
Definition: thread.c:402
DWORD Signature
Definition: dbghelp.h:788
#define except(x)
Definition: btrfs_drv.h:139
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
WORD wProcessorLevel
Definition: winbase.h:1146
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
Definition: inflate.c:139
ULONG SuspendCount
Definition: dbghelp.h:915
uint32_t DWORD_PTR
Definition: typedefs.h:65
_In_ HANDLE hFile
Definition: mswsock.h:90
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
ULONG dwPlatformId
Definition: rtltypes.h:250
static void writeat(struct dump_context *dc, RVA rva, const void *data, unsigned size)
Definition: minidump.c:383
static unsigned dump_system_info(struct dump_context *dc)
Definition: minidump.c:628
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
static BOOL fetch_thread_info(struct dump_context *dc, int thd_idx, const MINIDUMP_EXCEPTION_INFORMATION *except, MINIDUMP_THREAD *mdThd, CONTEXT *ctx)
Definition: minidump.c:121
ULONG ProcessCreateTime
Definition: dbghelp.h:834
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext
Definition: dbghelp.h:783
ULONG Priority
Definition: dbghelp.h:917
MINIDUMP_MEMORY_DESCRIPTOR Stack
Definition: dbghelp.h:919
static unsigned dump_exception_info(struct dump_context *dc, const MINIDUMP_EXCEPTION_INFORMATION *except)
Definition: minidump.c:408
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
Definition: intrin_ppc.h:682
USHORT ProcessorRevision
Definition: dbghelp.h:869
uint64_t DWORD64
Definition: typedefs.h:67
#define lstrcpyW
Definition: compat.h:608
BOOL WINAPI IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
Definition: sysinfo.c:168
PVOID StackBase
Definition: compat.h:571
#define CDECL
Definition: compat.h:29
#define ARRAY_SIZE(a)
Definition: main.h:24
RVA StreamDirectoryRva
Definition: dbghelp.h:791
void minidump_add_memory_block(struct dump_context *dc, ULONG64 base, ULONG size, ULONG rva)
Definition: minidump.c:355
ULONG64 NumberOfMemoryRanges
Definition: dbghelp.h:821
#define HeapReAlloc
Definition: compat.h:593
static int have_x86cpuid(void)
Definition: minidump.c:617
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:142
#define min(a, b)
Definition: monoChain.cc:55
static void fetch_module_versioninfo(LPCWSTR filename, VS_FIXEDFILEINFO *ffi)
Definition: minidump.c:325
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:27
static BOOL WINAPI fetch_pe_module_info_cb(PCWSTR name, DWORD64 base, ULONG size, PVOID user)
Definition: minidump.c:237
ULONG64 ExceptionRecord
Definition: dbghelp.h:764
WORD wProcessorArchitecture
Definition: winbase.h:1135
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:845
ULONG dwMinorVersion
Definition: rtltypes.h:248
CONST void * LPCVOID
Definition: windef.h:191
Definition: name.c:38
DWORD RVA
Definition: compat.h:1121
DWORD dwNumberOfProcessors
Definition: winbase.h:1143
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:566
static void fetch_memory64_info(struct dump_context *dc)
Definition: minidump.c:293
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
DWORD ExceptionFlags
Definition: compat.h:209
static const WCHAR dc[]
#define GetProcAddress(x, y)
Definition: compat.h:612
PVOID StackLimit
Definition: compat.h:572
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
DWORD NumberParameters
Definition: compat.h:212
GLfloat GLfloat p
Definition: glext.h:8902
static void do_x86cpuid(unsigned int ax, unsigned int *p)
Definition: minidump.c:613
ULONG PriorityClass
Definition: dbghelp.h:916
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define memset(x, y, z)
Definition: compat.h:39
BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:414
MINIDUMP_LOCATION_DESCRIPTOR Memory
Definition: dbghelp.h:804
DWORD CheckSum
Definition: dbghelp.h:792
static TfClientId tid
static BOOL read_process_memory(const struct process *process, UINT64 addr, void *buf, size_t size)
void user(int argc, const char *argv[])
Definition: cmds.c:1350
ULONG ProcessUserTime
Definition: dbghelp.h:835
#define HeapFree(x, y, z)
Definition: compat.h:594
static BOOL add_module(struct dump_context *dc, const WCHAR *name, DWORD64 base, DWORD size, DWORD timestamp, DWORD checksum, BOOL is_elf)
Definition: minidump.c:195
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
#define SetFilePointer
Definition: compat.h:602
#define MINIDUMP_SIGNATURE
Definition: dbghelp.h:598
ULONG64 Teb
Definition: dbghelp.h:918
LONGLONG QuadPart
Definition: typedefs.h:114
PMINIDUMP_USER_STREAM UserStreamArray
Definition: dbghelp.h:939
ULONG64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: dbghelp.h:768
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1049
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 mm1 mm5 paddd mm0 paddd mm4 mm0 mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl
Definition: synth_sse3d.h:161
enum _MINIDUMP_TYPE MINIDUMP_TYPE