00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "ace/Stack_Trace.h"
00030 #include "ace/Min_Max.h"
00031 #include "ace/OS_NS_string.h"
00032 #include "ace/OS_NS_stdio.h"
00033
00034 ACE_RCSID (ace, Stack_Trace, "$Id: Stack_Trace.cpp 90041 2010-04-29 03:38:07Z cleeland $")
00035
00036
00037
00038
00039
00040 const char ACE_Stack_Trace::UNSUPPORTED[] = "<stack traces unsupported platform>";
00041 const char ACE_Stack_Trace::UNABLE_TO_GET_TRACE[] = "<unable to get trace>";
00042
00043 ACE_Stack_Trace::ACE_Stack_Trace (ssize_t starting_frame_offset, size_t num_frames)
00044 : buflen_(0)
00045 {
00046
00047 this->buf_[0] = '\0';
00048 this->generate_trace (starting_frame_offset, num_frames);
00049 }
00050
00051 const char*
00052 ACE_Stack_Trace::c_str () const
00053 {
00054 return &this->buf_[0];
00055 }
00056
00057 static inline size_t
00058 determine_starting_frame (ssize_t initial_frame, ssize_t offset)
00059 {
00060 return ACE_MAX( initial_frame + offset, static_cast<ssize_t>(0));
00061 }
00062
00063 #if (defined(__GLIBC__) || defined(ACE_HAS_EXECINFO_H)) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
00064
00065 # include <execinfo.h>
00066
00067 void
00068 ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset, size_t num_frames)
00069 {
00070 const size_t MAX_FRAMES = 128;
00071 const ssize_t INITIAL_FRAME = 3;
00072
00073 void* stack[MAX_FRAMES];
00074 size_t stack_size = 0;
00075 char** stack_syms;
00076
00077 if (num_frames == 0)
00078 num_frames = MAX_FRAMES;
00079
00080 size_t starting_frame =
00081 determine_starting_frame (INITIAL_FRAME, starting_frame_offset);
00082
00083 stack_size = ::backtrace (&stack[0], sizeof(stack)/sizeof(stack[0]));
00084 if (stack_size != 0)
00085 {
00086 stack_syms = ::backtrace_symbols (stack, stack_size);
00087
00088 for (size_t i = starting_frame;
00089 i < stack_size && num_frames > 0;
00090 i++, num_frames--)
00091 {
00092
00093 char *symp = &stack_syms[i][0];
00094 while (this->buflen_ < SYMBUFSIZ - 2 && *symp != '\0')
00095 {
00096 this->buf_[this->buflen_++] = *symp++;
00097 }
00098 this->buf_[this->buflen_++] = '\n';
00099 }
00100 this->buf_[this->buflen_] = '\0';
00101
00102 ::free (stack_syms);
00103 }
00104 else
00105 {
00106 ACE_OS::strcpy (&this->buf_[0], UNABLE_TO_GET_TRACE);
00107 }
00108 }
00109 #elif defined(VXWORKS) && !defined(__RTP__)
00110 # include <trcLib.h>
00111 # include <taskLib.h>
00112
00113 struct ACE_Stack_Trace_stackstate
00114 {
00115 ACE_Stack_Trace_stackstate (char* b, size_t& bl, size_t nf, size_t sf)
00116 : buf(b), buflen(bl), num_frames(nf), starting_frame(sf)
00117 { }
00118
00119 char* buf;
00120 size_t& buflen;
00121 size_t num_frames;
00122 size_t starting_frame;
00123 };
00124
00125
00126
00127 static ACE_Stack_Trace_stackstate* ACE_Stack_Trace_stateptr = 0;
00128
00129 static void
00130 ACE_Stack_Trace_Add_Frame_To_Buf (INSTR *caller,
00131 unsigned int func,
00132 unsigned int nargs,
00133 unsigned int *args)
00134 {
00135 if (ACE_Stack_Trace_stateptr == 0)
00136 return;
00137
00138 ACE_Stack_Trace_stackstate *stackstate = ACE_Stack_Trace_stateptr;
00139
00140
00141
00142 --stackstate->num_frames;
00143 --stackstate->starting_frame;
00144
00145 if (stackstate->num_frames == 0 || stackstate->starting_frame > 0)
00146 return;
00147
00148
00149
00150 char*& buf = stackstate->buf;
00151 unsigned int& len = stackstate->buflen;
00152
00153
00154
00155
00156
00157 if (nargs == static_cast<unsigned int> (-1)) nargs = 0;
00158
00159 len += ACE_OS::sprintf (&buf[len], "%#10x: %#10x (", (int)caller, func);
00160 for (unsigned int i = 0; i < nargs; ++i)
00161 {
00162 if (i != 0)
00163 len += ACE_OS::sprintf (&buf[len], ", ");
00164 len += ACE_OS::sprintf(&buf [len], "%#x", args [i]);
00165 }
00166
00167 len += ACE_OS::sprintf(&buf[len], ")\n");
00168 }
00169
00170 void
00171 ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset,
00172 size_t num_frames)
00173 {
00174 const size_t MAX_FRAMES = 128;
00175 const ssize_t INITIAL_FRAME = 3;
00176
00177 if (num_frames == 0)
00178 num_frames = MAX_FRAMES;
00179
00180 size_t starting_frame =
00181 determine_starting_frame (INITIAL_FRAME, starting_frame_offset);
00182
00183 ACE_Stack_Trace_stackstate state (&this->buf_[0], this->buflen_,
00184 num_frames, starting_frame);
00185
00186 REG_SET regs;
00187
00188 taskRegsGet ((int)taskIdSelf(), ®s);
00189
00190 ACE_Stack_Trace_stateptr = &state;
00191 trcStack (®s, (FUNCPTR)ACE_Stack_Trace_Add_Frame_To_Buf, taskIdSelf ());
00192 }
00193
00194
00195 #elif defined(VXWORKS) && defined(__RTP__)
00196 # include <setjmp.h>
00197 # include <taskLib.h>
00198 # include <private/trcLibP.h>
00199
00200
00201
00202 static STATUS ace_vx_rtp_pc_validate (INSTR *pc, TRC_OS_CTX *pOsCtx)
00203 {
00204 return ALIGNED (pc, sizeof (INSTR)) ? OK : ERROR;
00205 }
00206
00207 void
00208 ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset,
00209 size_t num_frames)
00210 {
00211 const size_t MAX_FRAMES = 128;
00212 const ssize_t INITIAL_FRAME = 2;
00213
00214 if (num_frames == 0) num_frames = MAX_FRAMES;
00215 size_t starting_frame =
00216 determine_starting_frame (INITIAL_FRAME, starting_frame_offset);
00217
00218 jmp_buf regs;
00219 setjmp (regs);
00220
00221 TASK_DESC desc;
00222 if (taskInfoGet (taskIdSelf (), &desc) == ERROR) return;
00223
00224 TRC_OS_CTX osCtx;
00225 osCtx.stackBase = desc.td_pStackBase;
00226 osCtx.stackEnd = desc.td_pStackEnd;
00227 osCtx.pcValidateRtn = reinterpret_cast<FUNCPTR> (ace_vx_rtp_pc_validate);
00228
00229 char *fp = _WRS_FRAMEP_FROM_JMP_BUF (regs);
00230 INSTR *pc = _WRS_RET_PC_FROM_JMP_BUF (regs);
00231
00232 for (size_t depth = 0; depth < num_frames + starting_frame; ++depth)
00233 {
00234 char *prevFp;
00235 INSTR *prevPc;
00236 INSTR *prevFn;
00237
00238 if (trcLibFuncs.lvlInfoGet (fp, pc, &osCtx, &prevFp, &prevPc, &prevFn)
00239 == ERROR)
00240 {
00241 ACE_OS::strcpy (this->buf_, UNABLE_TO_GET_TRACE);
00242 return;
00243 }
00244
00245 if(prevPc == 0 || prevFp == 0) break;
00246
00247 if (depth >= starting_frame)
00248 {
00249
00250
00251
00252 const char *fnName = "(no symbols)";
00253
00254 static const int N_ARGS = 12;
00255 int buf[N_ARGS];
00256 int *pArgs = 0;
00257 int numArgs =
00258 trcLibFuncs.lvlArgsGet (prevPc, prevFn, prevFp,
00259 buf, N_ARGS, &pArgs);
00260
00261
00262 if (numArgs == -1) numArgs = 0;
00263
00264 size_t len = ACE_OS::strlen (this->buf_);
00265 size_t space = SYMBUFSIZ - len - 1;
00266 char *cursor = this->buf_ + len;
00267 size_t written = ACE_OS::snprintf (cursor, space, "%x %s",
00268 prevFn, fnName);
00269 cursor += written;
00270 space -= written;
00271
00272 if (space < 1) return;
00273 for (int arg = 0; numArgs != -1 && pArgs && arg < numArgs; ++arg)
00274 {
00275 if (arg == 0) *cursor++ = '(', --space;
00276 written = ACE_OS::snprintf (cursor, space,
00277 (arg < numArgs - 1) ? "%x, " : "%x",
00278 pArgs[arg]);
00279 cursor += written;
00280 space -= written;
00281 if (space && arg == numArgs - 1) *cursor++ = ')', --space;
00282 }
00283 if (space) *cursor++ = '\n', --space;
00284 *cursor++ = 0;
00285 }
00286
00287 fp = prevFp;
00288 pc = prevPc;
00289 }
00290 }
00291
00292 #elif defined(sun)
00293
00294
00295
00296
00297 # include <dlfcn.h>
00298 # include <setjmp.h>
00299 # include <sys/types.h>
00300 # include <sys/reg.h>
00301 # include <sys/frame.h>
00302 # define ACE_STACK_TRACE_BIAS 0
00303
00304 # if defined(sparc) || defined(__sparc)
00305 # define ACE_STACK_TRACE_FLUSHWIN() asm("ta 3");
00306 # define ACE_STACK_TRACE_FRAME_PTR_INDEX 1
00307 # define ACE_STACK_TRACE_SKIP_FRAMES 0
00308 # if defined(__sparcv9)
00309 # undef ACE_STACK_TRACE_BIAS
00310 # define ACE_STACK_TRACE_BIAS 2047
00311 # endif
00312 # endif
00313
00314 # if defined(i386) || defined(__i386)
00315 # define ACE_STACK_TRACE_FLUSHWIN()
00316 # define ACE_STACK_TRACE_FRAME_PTR_INDEX 3
00317 # define ACE_STACK_TRACE_SKIP_FRAMES 0
00318 # endif
00319
00320 # if defined(__amd64) || defined(__x86_64)
00321 # define ACE_STACK_TRACE_FLUSHWIN()
00322 # define ACE_STACK_TRACE_FRAME_PTR_INDEX 5
00323 # define ACE_STACK_TRACE_SKIP_FRAMES 0
00324 # endif
00325
00326 # if defined(ppc) || defined(__ppc)
00327 # define ACE_STACK_TRACE_FLUSHWIN()
00328 # define ACE_STACK_TRACE_FRAME_PTR_INDEX 0
00329 # define ACE_STACK_TRACE_SKIP_FRAMES 2
00330 # endif
00331
00332 static frame*
00333 cs_frame_adjust(frame* sp)
00334 {
00335 unsigned char* sp_byte = (unsigned char*)sp;
00336 sp_byte += ACE_STACK_TRACE_BIAS;
00337 return (frame*) sp_byte;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346 static int
00347 cs_operate(int (*func)(void *, void *), void * usrarg,
00348 size_t starting_frame, size_t num_frames_arg)
00349 {
00350 ACE_STACK_TRACE_FLUSHWIN();
00351
00352 jmp_buf env;
00353 setjmp(env);
00354 frame* sp = cs_frame_adjust((frame*) env[ACE_STACK_TRACE_FRAME_PTR_INDEX]);
00355
00356
00357
00358
00359 size_t num_frames = num_frames_arg;
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 const size_t starting_skip = starting_frame - 1;
00370 #if ACE_STACK_TRACE_SKIP_FRAMES == 0
00371 size_t skip_frames = starting_skip;
00372 #else
00373 size_t skip_frames =
00374 ACE_STACK_TRACE_SKIP_FRAMES > starting_skip ?
00375 ACE_STACK_TRACE_SKIP_FRAMES : starting_skip;
00376 #endif
00377 size_t i;
00378 for (i = 0; i < skip_frames && sp; ++i)
00379 {
00380 sp = cs_frame_adjust((frame*) sp->fr_savfp);
00381 }
00382
00383 i = 0;
00384
00385 while ( sp
00386 && sp->fr_savpc
00387 && ++i
00388 && --num_frames
00389 && (*func)((void*)sp->fr_savpc, usrarg))
00390 {
00391 sp = cs_frame_adjust((frame*) sp->fr_savfp);
00392 }
00393
00394 return(i);
00395 }
00396
00397 static int
00398 add_frame_to_buf (void* pc, void* usrarg)
00399 {
00400 char* buf = (char*)usrarg;
00401 Dl_info info;
00402 const char* func = "??";
00403 const char* lib = "??";
00404
00405 if(dladdr(pc, & info) != 0)
00406 {
00407 lib = (const char *) info.dli_fname;
00408 func = (const char *) info.dli_sname;
00409 }
00410
00411 (void) ACE_OS::snprintf(buf,
00412 ACE_Stack_Trace::SYMBUFSIZ,
00413 "%s%s:%s+0x%x\n",
00414 buf,
00415 lib,
00416 func,
00417
00418
00419
00420
00421 (size_t)pc - (size_t)info.dli_saddr);
00422
00423 return(1);
00424 }
00425
00426 void
00427 ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset,
00428 size_t num_frames)
00429 {
00430 const size_t MAX_FRAMES = 128;
00431 const ssize_t INITIAL_FRAME = 3;
00432
00433 if (num_frames == 0)
00434 num_frames = MAX_FRAMES;
00435
00436 size_t starting_frame =
00437 determine_starting_frame (INITIAL_FRAME, starting_frame_offset);
00438
00439 cs_operate (&add_frame_to_buf, &this->buf_[0], starting_frame, num_frames);
00440 }
00441
00442 #elif defined(ACE_WIN64) && (_WIN32_WINNT <= _WIN32_WINNT_WIN2K)
00443 # if defined(_MSC_VER)
00444 # define STRING2(X) #X
00445 # define STRING(X) STRING2(X)
00446 # pragma message (__FILE__ "(" STRING(__LINE__) ") : warning: stack traces"\
00447 " can't be generated on 64-bit Windows when _WIN32_WINNT is less than "\
00448 "0x501.")
00449 # undef STRING
00450 # undef STRING2
00451 # endif
00452 void
00453 ACE_Stack_Trace::generate_trace (ssize_t, size_t)
00454 {
00455 ACE_OS::strcpy (&this->buf_[0], "<stack traces unsupported on Win64 unless "
00456 "ACE is built with _WIN32_WINNT set to 0x501 or above>");
00457 }
00458
00459 #elif defined(ACE_WIN32) && !defined(ACE_HAS_WINCE) && !defined (__MINGW32__) \
00460 && !defined(__BORLANDC__)
00461 # include <windows.h>
00462 # include <Dbghelp.h>
00463
00464 # define MAXTEXT 5000
00465 # define SYMSIZE 100
00466
00467
00468
00469
00470 typedef struct _dbghelp_functions
00471 {
00472 HMODULE hMod;
00473
00474
00475 DWORD64 (WINAPI *SymGetModuleBase64) (HANDLE hProc, DWORD64 dwAddr);
00476 PVOID (WINAPI *SymFunctionTableAccess64) (HANDLE hProc, DWORD64 AddrBase);
00477
00478 typedef BOOL (WINAPI *SymFromAddr_t)
00479 (HANDLE hProc, DWORD64 Addr, PDWORD64 Disp, PSYMBOL_INFO Symbol);
00480 SymFromAddr_t SymFromAddr;
00481
00482 typedef BOOL (WINAPI *SymGetLineFromAddr64_t) (HANDLE hProc, DWORD64 dwAddr,
00483 PDWORD pdwDisplacement,
00484 PIMAGEHLP_LINE64 Line);
00485 SymGetLineFromAddr64_t SymGetLineFromAddr64;
00486
00487 typedef DWORD (WINAPI *SymSetOptions_t) (DWORD SymOptions);
00488 SymSetOptions_t SymSetOptions;
00489
00490 typedef DWORD (WINAPI *SymGetOptions_t) ();
00491 SymGetOptions_t SymGetOptions;
00492
00493 typedef BOOL (WINAPI *SymInitialize_t) (HANDLE hProc, PCTSTR UserSearchPath,
00494 BOOL invasive);
00495 SymInitialize_t SymInitialize;
00496
00497 typedef BOOL
00498 (WINAPI *StackWalk64_t) (DWORD MachineType, HANDLE hPRoc, HANDLE hThr,
00499 LPSTACKFRAME64 StackFrame, PVOID ContextRecord,
00500 PREAD_PROCESS_MEMORY_ROUTINE64 RMRoutine,
00501 PFUNCTION_TABLE_ACCESS_ROUTINE64 FTARoutine,
00502 PGET_MODULE_BASE_ROUTINE64 GMBRoutine,
00503 PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
00504 StackWalk64_t StackWalk64;
00505
00506 typedef BOOL (WINAPI *SymCleanup_t) (HANDLE hProc);
00507 SymCleanup_t SymCleanup;
00508 } dbghelp_functions;
00509
00510
00511 # pragma warning (push)
00512 # pragma warning (disable:4706)
00513 static bool load_dbghelp_library_if_needed (dbghelp_functions *pDbg)
00514 {
00515
00516
00517
00518 if (!(pDbg->hMod = ACE_TEXT_LoadLibrary (ACE_TEXT ("Dbghelp"))))
00519 return false;
00520
00521
00522
00523 # define LINK(TYPE, NAME) (pDbg->NAME = \
00524 (TYPE) GetProcAddress (pDbg->hMod, #NAME))
00525 # define LINK_T(NAME) LINK (dbghelp_functions::NAME##_t, NAME)
00526 return LINK (PGET_MODULE_BASE_ROUTINE64, SymGetModuleBase64)
00527 && LINK (PFUNCTION_TABLE_ACCESS_ROUTINE64, SymFunctionTableAccess64)
00528 && LINK_T (SymFromAddr) && LINK_T (SymGetLineFromAddr64)
00529 && LINK_T (SymSetOptions)&& LINK_T (SymGetOptions)
00530 && LINK_T (SymInitialize) && LINK_T (StackWalk64) && LINK_T (SymCleanup);
00531 # undef LINK
00532 # undef LINK_T
00533 }
00534 # pragma warning (pop)
00535
00536
00537 struct frame_state {
00538 STACKFRAME64 sf;
00539 PSYMBOL_INFO pSym;
00540 dbghelp_functions *pDbg;
00541 };
00542
00543 static int
00544 add_frame_to_buf (struct frame_state const *fs, void *usrarg)
00545 {
00546 if (fs == 0 || usrarg == 0)
00547 return -1;
00548
00549 char *buf = static_cast<char *> (usrarg);
00550
00551 DWORD64 disp;
00552 DWORD64 dwModBase = fs->pDbg->SymGetModuleBase64 (GetCurrentProcess (),
00553 fs->sf.AddrPC.Offset);
00554 if (fs->pDbg->SymFromAddr (GetCurrentProcess (),
00555 fs->sf.AddrPC.Offset, &disp, fs->pSym))
00556 {
00557 IMAGEHLP_LINE64 line = {sizeof (IMAGEHLP_LINE64)};
00558 DWORD lineDisp;
00559 if (fs->pDbg->SymGetLineFromAddr64 (GetCurrentProcess (),
00560 fs->sf.AddrPC.Offset,
00561 &lineDisp, &line))
00562 {
00563 (void) ACE_OS::snprintf (buf, ACE_Stack_Trace::SYMBUFSIZ,
00564 "%s%s() %s: %d + 0x%x\n",
00565 buf, fs->pSym->Name, line.FileName,
00566 line.LineNumber, lineDisp);
00567 }
00568 else
00569 {
00570 (void) ACE_OS::snprintf (buf, ACE_Stack_Trace::SYMBUFSIZ,
00571 "%s%s()+0x%x [0x%x]\n",
00572 buf, fs->pSym->Name, disp,
00573 fs->sf.AddrPC.Offset - dwModBase);
00574 }
00575 }
00576 else
00577 {
00578 (void) ACE_OS::snprintf (buf, ACE_Stack_Trace::SYMBUFSIZ,
00579 "%s[0x%x]\n",
00580 buf, fs->sf.AddrPC.Offset - dwModBase);
00581 }
00582 return 0;
00583 }
00584
00585 static void emptyStack () { }
00586
00587 #if defined (_MSC_VER)
00588 # pragma warning(push)
00589
00590
00591
00592 # pragma warning(disable: 4748)
00593 #endif
00594
00595 static int
00596 cs_operate(int (*func)(struct frame_state const *, void *), void *usrarg,
00597 size_t starting_frame, size_t num_frames)
00598 {
00599 dbghelp_functions dbg;
00600 if (!load_dbghelp_library_if_needed (&dbg))
00601 {
00602 ACE_OS::strcpy (static_cast<char *> (usrarg),
00603 "<error loading dbghelp.dll>");
00604 if (dbg.hMod) FreeLibrary (dbg.hMod);
00605 return 1;
00606 }
00607
00608 frame_state fs;
00609 ZeroMemory (&fs.sf, sizeof (fs.sf));
00610 fs.pDbg = &dbg;
00611 emptyStack ();
00612
00613 CONTEXT c;
00614 ZeroMemory (&c, sizeof (CONTEXT));
00615 c.ContextFlags = CONTEXT_FULL;
00616
00617 # if defined (_M_IX86)
00618 DWORD machine = IMAGE_FILE_MACHINE_I386;
00619 __asm {
00620 call x
00621 x: pop eax
00622 mov c.Eip, eax
00623 mov c.Ebp, ebp
00624 mov c.Esp, esp
00625 }
00626 fs.sf.AddrPC.Offset = c.Eip;
00627 fs.sf.AddrStack.Offset = c.Esp;
00628 fs.sf.AddrFrame.Offset = c.Ebp;
00629 fs.sf.AddrPC.Mode = AddrModeFlat;
00630 fs.sf.AddrStack.Mode = AddrModeFlat;
00631 fs.sf.AddrFrame.Mode = AddrModeFlat;
00632 # elif defined (_M_X64)
00633 DWORD machine = IMAGE_FILE_MACHINE_AMD64;
00634 RtlCaptureContext (&c);
00635 fs.sf.AddrPC.Offset = c.Rip;
00636 fs.sf.AddrFrame.Offset = c.Rsp;
00637 fs.sf.AddrStack.Offset = c.Rsp;
00638 fs.sf.AddrPC.Mode = AddrModeFlat;
00639 fs.sf.AddrFrame.Mode = AddrModeFlat;
00640 fs.sf.AddrStack.Mode = AddrModeFlat;
00641 # elif defined (_M_IA64)
00642 DWORD machine = IMAGE_FILE_MACHINE_IA64;
00643 RtlCaptureContext (&c);
00644 fs.sf.AddrPC.Offset = c.StIIP;
00645 fs.sf.AddrFrame.Offset = c.RsBSP;
00646 fs.sf.AddrBStore.Offset = c.RsBSP;
00647 fs.sf.AddrStack.Offset = c.IntSp;
00648 fs.sf.AddrPC.Mode = AddrModeFlat;
00649 fs.sf.AddrFrame.Mode = AddrModeFlat;
00650 fs.sf.AddrBStore.Mode = AddrModeFlat;
00651 fs.sf.AddrStack.Mode = AddrModeFlat;
00652 # endif
00653
00654 fs.pSym = (PSYMBOL_INFO) GlobalAlloc (GMEM_FIXED,
00655 sizeof (SYMBOL_INFO) +
00656 sizeof (ACE_TCHAR) * (SYMSIZE - 1));
00657 fs.pSym->SizeOfStruct = sizeof (SYMBOL_INFO);
00658 fs.pSym->MaxNameLen = SYMSIZE * sizeof (ACE_TCHAR);
00659 dbg.SymSetOptions (SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES
00660 | SYMOPT_FAIL_CRITICAL_ERRORS | dbg.SymGetOptions ());
00661 dbg.SymInitialize (GetCurrentProcess (), 0, true);
00662
00663
00664 for (size_t current_frame = 0; current_frame < num_frames + starting_frame;
00665 ++current_frame)
00666 {
00667 BOOL ok = dbg.StackWalk64 (machine,
00668 GetCurrentProcess (),
00669 GetCurrentThread (),
00670 &fs.sf, &c, 0,
00671 dbg.SymFunctionTableAccess64,
00672 dbg.SymGetModuleBase64, 0);
00673 if (!ok || fs.sf.AddrFrame.Offset == 0)
00674 break;
00675
00676 if (current_frame < starting_frame)
00677 continue;
00678
00679 func (&fs, usrarg);
00680 }
00681
00682 dbg.SymCleanup (GetCurrentProcess ());
00683 GlobalFree (fs.pSym);
00684 FreeLibrary (dbg.hMod);
00685
00686 return 0;
00687 }
00688
00689 #if defined (_MSC_VER)
00690
00691 # pragma warning(pop)
00692 #endif
00693
00694 void
00695 ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset,
00696 size_t num_frames)
00697 {
00698 const size_t MAX_FRAMES = 128;
00699 const ssize_t INITIAL_FRAME = 3;
00700
00701 if (num_frames == 0)
00702 num_frames = MAX_FRAMES;
00703
00704 size_t starting_frame =
00705 determine_starting_frame (INITIAL_FRAME, starting_frame_offset);
00706
00707 cs_operate (&add_frame_to_buf, &this->buf_[0], starting_frame, num_frames);
00708 }
00709
00710 #else // Unsupported platform
00711 void
00712 ACE_Stack_Trace::generate_trace (ssize_t, size_t)
00713 {
00714
00715
00716 #if defined (__HP_aCC)
00717 size_t starting_frame = determine_starting_frame (0, 0);
00718 #endif
00719
00720 ACE_OS::strcpy (&this->buf_[0], UNSUPPORTED);
00721 }
00722 #endif
00723