~n-muench/ubuntu/oneiric/open-vm-tools/open-vm-tools.fix-836277

« back to all changes in this revision

Viewing changes to lib/user/util.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-07-30 12:56:49 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730125649-97sfj5li8axiseoo
Tags: 2009.07.22-179896-2
* Temporarily building without dumbnet, the recently uploaded
  new dumbnet upstream version broke down (Closes: #539006).
* Using more common name to store local debian additions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
99
99
#ifdef UTIL_BACKTRACE_USE_UNWIND
100
100
#include <unwind.h>
101
101
 
 
102
#define MAX_SKIPPED_FRAMES 10
 
103
 
102
104
struct UtilBacktraceFromPointerData {
103
105
   uintptr_t        basePtr;
104
106
   Util_OutputFunc  outFunc;
105
107
   void            *outFuncData;
106
108
   unsigned int     frameNr;
 
109
   unsigned int     skippedFrames;
107
110
};
108
111
 
109
112
struct UtilBacktraceToBufferData {
258
261
/*
259
262
 *-----------------------------------------------------------------------------
260
263
 *
261
 
 * Util_LogWrapper --
 
264
 * UtilLogWrapper --
262
265
 *
263
266
 *      Adapts the Log function to meet the interface required by backtracing
264
267
 *      functions by adding an ignored void* argument.
265
268
 *
 
269
 *      NOTE: This function needs to be static on linux (and any other
 
270
 *      platform appLoader might be ported to).  See bug 403780.
 
271
 *
266
272
 * Results:
267
273
 *      Same effect as Log(fmt, ...)
268
274
 *
271
277
 *
272
278
 *-----------------------------------------------------------------------------
273
279
 */
274
 
void
275
 
Util_LogWrapper(void *ignored, const char *fmt, ...)
 
280
 
 
281
static void
 
282
UtilLogWrapper(void *ignored,    // IN:
 
283
               const char *fmt,  // IN:
 
284
               ...)              // IN:
276
285
{
 
286
   uint32 len;
277
287
   va_list ap;
278
288
   char thisLine[UTIL_BACKTRACE_LINE_LEN];
279
289
 
280
290
   va_start(ap, fmt);
281
 
   Str_Vsnprintf(thisLine, UTIL_BACKTRACE_LINE_LEN-1, fmt, ap);
282
 
   thisLine[UTIL_BACKTRACE_LINE_LEN-1] = '\0';
 
291
   len = Str_Vsnprintf(thisLine, UTIL_BACKTRACE_LINE_LEN - 2, fmt, ap);
283
292
   va_end(ap);
284
293
 
 
294
   if (len >= UTIL_BACKTRACE_LINE_LEN - 2) {
 
295
      len = UTIL_BACKTRACE_LINE_LEN - 3;
 
296
   }
 
297
 
 
298
   if (thisLine[len - 1] != '\n') {
 
299
      thisLine[len] = '\n';
 
300
      thisLine[len + 1] = '\0';
 
301
   }
 
302
 
285
303
   Log("%s", thisLine);
286
304
}
287
305
 
340
358
 *
341
359
 * Results:
342
360
 *      _URC_NO_REASON : Please continue with backtrace.
 
361
 *      _URC_END_OF_STACK : Abort backtrace.
343
362
 *
344
363
 * Side effects:
345
364
 *      None.
357
376
   /*
358
377
    * Stack grows down.  So if we are below basePtr, do nothing...
359
378
    */
360
 
   if (cfa >= data->basePtr) {
 
379
 
 
380
   if (cfa >= data->basePtr && data->frameNr < 500) {
361
381
#ifndef VM_X86_64
362
382
#   error You should not build this on 32bit - there is no eh_frame there.
363
383
#endif
 
384
      /* bump basePtr for glibc unwind bug, see [302237] */
 
385
      data->basePtr = cfa + 8;
364
386
      /* Do output without leading '0x' to save some horizontal space... */
365
387
      data->outFunc(data->outFuncData,
366
388
                    "Backtrace[%u] %016lx rip=%016lx rbx=%016lx rbp=%016lx "
370
392
                    _Unwind_GetGR(ctx, 12), _Unwind_GetGR(ctx, 13),
371
393
                    _Unwind_GetGR(ctx, 14), _Unwind_GetGR(ctx, 15));
372
394
      data->frameNr++;
 
395
      return _URC_NO_REASON;
 
396
   } else if (data->skippedFrames < MAX_SKIPPED_FRAMES && !data->frameNr) {
 
397
      /*
 
398
       * Skip over the frames before the specified starting point of the
 
399
       * backtrace.
 
400
       */
 
401
 
 
402
      data->skippedFrames++;
 
403
      return _URC_NO_REASON;
373
404
   }
374
 
   return _URC_NO_REASON;
 
405
   return _URC_END_OF_STACK;
375
406
}
376
407
 
377
408
#if !defined(_WIN32) && !defined(N_PLAT_NLM) && !defined(VMX86_TOOLS)
403
434
   /*
404
435
    * Stack grows down.  So if we are below basePtr, do nothing...
405
436
    */
406
 
   if (cfa >= data->basePtr) {
 
437
 
 
438
   if (cfa >= data->basePtr && data->frameNr < 500) {
407
439
#ifndef VM_X86_64
408
440
#   error You should not build this on 32bit - there is no eh_frame there.
409
441
#endif
410
442
      void *enclFuncAddr;
411
443
      Dl_info dli;
412
444
 
 
445
      /* bump basePtr for glibc unwind bug, see [302237] */
 
446
      data->basePtr = cfa + 8;
413
447
#ifdef __linux__
414
448
      enclFuncAddr = _Unwind_FindEnclosingFunction((void *)_Unwind_GetIP(ctx));
415
449
#else
428
462
                      data->frameNr, cfa, _Unwind_GetIP(ctx));
429
463
      }
430
464
      data->frameNr++;
 
465
      return _URC_NO_REASON;
 
466
   } else if (data->skippedFrames < MAX_SKIPPED_FRAMES && !data->frameNr) {
 
467
      /*
 
468
       * Skip over the frames before the specified starting point of the
 
469
       * backtrace.
 
470
       */
 
471
 
 
472
      data->skippedFrames++;
 
473
      return _URC_NO_REASON;
431
474
   }
432
 
   return _URC_NO_REASON;
 
475
   return _URC_END_OF_STACK;
433
476
}
434
477
#endif
435
478
#endif
455
498
void
456
499
Util_BacktraceFromPointer(uintptr_t *basePtr)
457
500
{
458
 
   Util_BacktraceFromPointerWithFunc(basePtr, Util_LogWrapper, NULL);
 
501
   Util_BacktraceFromPointerWithFunc(basePtr, UtilLogWrapper, NULL);
459
502
}
460
503
 
461
504
 
489
532
   data.outFunc = outFunc;
490
533
   data.outFuncData = outFuncData;
491
534
   data.frameNr = 0;
 
535
   data.skippedFrames = 0;
492
536
   _Unwind_Backtrace(UtilBacktraceFromPointerCallback, &data);
493
537
 
494
538
#if !defined(_WIN32) && !defined(N_PLAT_NLM) && !defined(VMX86_TOOLS)
501
545
   data.outFunc = outFunc;
502
546
   data.outFuncData = outFuncData;
503
547
   data.frameNr = 0;
 
548
   data.skippedFrames = 0;
504
549
   _Unwind_Backtrace(UtilSymbolBacktraceFromPointerCallback, &data);
505
550
#endif
506
551
 
647
692
void
648
693
Util_Backtrace(int bugNr) // IN
649
694
{
650
 
   Util_BacktraceWithFunc(bugNr, Util_LogWrapper, NULL);
 
695
   Util_BacktraceWithFunc(bugNr, UtilLogWrapper, NULL);
651
696
}
652
697
 
653
698