Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit e1d4b2e

Browse files
committed
DWARF: allow enabling tracing at runtime
Introduce `logDWARF` and the associated environment variable `LIBUNWIND_PRINT_DWARF` to trace the CFI instructions. git-svn-id: https://llvm.org/svn/llvm-project/libunwind/trunk@292722 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d8c14f5 commit e1d4b2e

File tree

2 files changed

+80
-89
lines changed

2 files changed

+80
-89
lines changed

src/DwarfParser.hpp

Lines changed: 68 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@
2323

2424
#include "AddressSpace.hpp"
2525

26+
extern "C" bool logDWARF();
27+
28+
#define _LIBUNWIND_TRACE_DWARF(...) \
29+
do { \
30+
if (logDWARF()) \
31+
fprintf(stderr, __VA_ARGS__); \
32+
} while (0)
33+
2634
namespace libunwind {
2735

2836
/// CFI_Parser does basic parsing of a CFI (Call Frame Information) records.
@@ -364,13 +372,12 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
364372
const CIE_Info &cieInfo, pint_t pcoffset,
365373
PrologInfoStackEntry *&rememberStack,
366374
PrologInfo *results) {
367-
const bool logDwarf = false;
368375
pint_t p = instructions;
369376
pint_t codeOffset = 0;
370377
PrologInfo initialState = *results;
371-
if (logDwarf)
372-
fprintf(stderr, "parseInstructions(instructions=0x%0" PRIx64 ")\n",
373-
(uint64_t)instructionsEnd);
378+
379+
_LIBUNWIND_TRACE_DWARF("parseInstructions(instructions=0x%0" PRIx64 ")\n",
380+
static_cast<uint64_t>(instructionsEnd));
374381

375382
// see DWARF Spec, section 6.4.2 for details on unwind opcodes
376383
while ((p < instructionsEnd) && (codeOffset < pcoffset)) {
@@ -386,35 +393,30 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
386393
++p;
387394
switch (opcode) {
388395
case DW_CFA_nop:
389-
if (logDwarf)
390-
fprintf(stderr, "DW_CFA_nop\n");
396+
_LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n");
391397
break;
392398
case DW_CFA_set_loc:
393399
codeOffset =
394400
addressSpace.getEncodedP(p, instructionsEnd, cieInfo.pointerEncoding);
395-
if (logDwarf)
396-
fprintf(stderr, "DW_CFA_set_loc\n");
401+
_LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n");
397402
break;
398403
case DW_CFA_advance_loc1:
399404
codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
400405
p += 1;
401-
if (logDwarf)
402-
fprintf(stderr, "DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",
403-
(uint64_t)codeOffset);
406+
_LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",
407+
static_cast<uint64_t>(codeOffset));
404408
break;
405409
case DW_CFA_advance_loc2:
406410
codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
407411
p += 2;
408-
if (logDwarf)
409-
fprintf(stderr, "DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",
410-
(uint64_t)codeOffset);
412+
_LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",
413+
static_cast<uint64_t>(codeOffset));
411414
break;
412415
case DW_CFA_advance_loc4:
413416
codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
414417
p += 4;
415-
if (logDwarf)
416-
fprintf(stderr, "DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",
417-
(uint64_t)codeOffset);
418+
_LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",
419+
static_cast<uint64_t>(codeOffset));
418420
break;
419421
case DW_CFA_offset_extended:
420422
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -426,21 +428,18 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
426428
}
427429
results->savedRegisters[reg].location = kRegisterInCFA;
428430
results->savedRegisters[reg].value = offset;
429-
if (logDwarf)
430-
fprintf(stderr,
431-
"DW_CFA_offset_extended(reg=%" PRIu64 ", offset=%" PRId64 ")\n",
432-
reg, offset);
431+
_LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", "
432+
"offset=%" PRId64 ")\n",
433+
reg, offset);
433434
break;
434435
case DW_CFA_restore_extended:
435436
reg = addressSpace.getULEB128(p, instructionsEnd);
436-
;
437437
if (reg > kMaxRegisterNumber) {
438438
_LIBUNWIND_LOG("malformed DWARF DW_CFA_restore_extended, reg too big");
439439
return false;
440440
}
441441
results->savedRegisters[reg] = initialState.savedRegisters[reg];
442-
if (logDwarf)
443-
fprintf(stderr, "DW_CFA_restore_extended(reg=%" PRIu64 ")\n", reg);
442+
_LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n", reg);
444443
break;
445444
case DW_CFA_undefined:
446445
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -449,8 +448,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
449448
return false;
450449
}
451450
results->savedRegisters[reg].location = kRegisterUnused;
452-
if (logDwarf)
453-
fprintf(stderr, "DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
451+
_LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
454452
break;
455453
case DW_CFA_same_value:
456454
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -465,8 +463,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
465463
results->savedRegisters[reg].location = kRegisterUnused;
466464
// set flag to disable conversion to compact unwind
467465
results->sameValueUsed = true;
468-
if (logDwarf)
469-
fprintf(stderr, "DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
466+
_LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
470467
break;
471468
case DW_CFA_register:
472469
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -483,9 +480,8 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
483480
results->savedRegisters[reg].value = (int64_t)reg2;
484481
// set flag to disable conversion to compact unwind
485482
results->registersInOtherRegisters = true;
486-
if (logDwarf)
487-
fprintf(stderr, "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n",
488-
reg, reg2);
483+
_LIBUNWIND_TRACE_DWARF(
484+
"DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2);
489485
break;
490486
#if !defined(_LIBUNWIND_NO_HEAP)
491487
case DW_CFA_remember_state:
@@ -498,8 +494,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
498494
} else {
499495
return false;
500496
}
501-
if (logDwarf)
502-
fprintf(stderr, "DW_CFA_remember_state\n");
497+
_LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n");
503498
break;
504499
case DW_CFA_restore_state:
505500
if (rememberStack != NULL) {
@@ -510,8 +505,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
510505
} else {
511506
return false;
512507
}
513-
if (logDwarf)
514-
fprintf(stderr, "DW_CFA_restore_state\n");
508+
_LIBUNWIND_TRACE_DWARF("DW_CFA_restore_state\n");
515509
break;
516510
#endif
517511
case DW_CFA_def_cfa:
@@ -523,9 +517,8 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
523517
}
524518
results->cfaRegister = (uint32_t)reg;
525519
results->cfaRegisterOffset = (int32_t)offset;
526-
if (logDwarf)
527-
fprintf(stderr, "DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64 ")\n",
528-
reg, offset);
520+
_LIBUNWIND_TRACE_DWARF(
521+
"DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64 ")\n", reg, offset);
529522
break;
530523
case DW_CFA_def_cfa_register:
531524
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -534,26 +527,23 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
534527
return false;
535528
}
536529
results->cfaRegister = (uint32_t)reg;
537-
if (logDwarf)
538-
fprintf(stderr, "DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg);
530+
_LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg);
539531
break;
540532
case DW_CFA_def_cfa_offset:
541533
results->cfaRegisterOffset = (int32_t)
542534
addressSpace.getULEB128(p, instructionsEnd);
543535
results->codeOffsetAtStackDecrement = (uint32_t)codeOffset;
544-
if (logDwarf)
545-
fprintf(stderr, "DW_CFA_def_cfa_offset(%d)\n",
546-
results->cfaRegisterOffset);
536+
_LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset(%d)\n",
537+
results->cfaRegisterOffset);
547538
break;
548539
case DW_CFA_def_cfa_expression:
549540
results->cfaRegister = 0;
550541
results->cfaExpression = (int64_t)p;
551542
length = addressSpace.getULEB128(p, instructionsEnd);
552543
p += length;
553-
if (logDwarf)
554-
fprintf(stderr, "DW_CFA_def_cfa_expression(expression=0x%" PRIx64
555-
", length=%" PRIu64 ")\n",
556-
results->cfaExpression, length);
544+
_LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64
545+
", length=%" PRIu64 ")\n",
546+
results->cfaExpression, length);
557547
break;
558548
case DW_CFA_expression:
559549
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -565,10 +555,10 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
565555
results->savedRegisters[reg].value = (int64_t)p;
566556
length = addressSpace.getULEB128(p, instructionsEnd);
567557
p += length;
568-
if (logDwarf)
569-
fprintf(stderr, "DW_CFA_expression(reg=%" PRIu64
570-
", expression=0x%" PRIx64 ", length=%" PRIu64 ")\n",
571-
reg, results->savedRegisters[reg].value, length);
558+
_LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", "
559+
"expression=0x%" PRIx64 ", "
560+
"length=%" PRIu64 ")\n",
561+
reg, results->savedRegisters[reg].value, length);
572562
break;
573563
case DW_CFA_offset_extended_sf:
574564
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -581,10 +571,9 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
581571
addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
582572
results->savedRegisters[reg].location = kRegisterInCFA;
583573
results->savedRegisters[reg].value = offset;
584-
if (logDwarf)
585-
fprintf(stderr, "DW_CFA_offset_extended_sf(reg=%" PRIu64
586-
", offset=%" PRId64 ")\n",
587-
reg, offset);
574+
_LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", "
575+
"offset=%" PRId64 ")\n",
576+
reg, offset);
588577
break;
589578
case DW_CFA_def_cfa_sf:
590579
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -596,29 +585,26 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
596585
}
597586
results->cfaRegister = (uint32_t)reg;
598587
results->cfaRegisterOffset = (int32_t)offset;
599-
if (logDwarf)
600-
fprintf(stderr,
601-
"DW_CFA_def_cfa_sf(reg=%" PRIu64 ", offset=%" PRId64 ")\n", reg,
602-
offset);
588+
_LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_sf(reg=%" PRIu64 ", "
589+
"offset=%" PRId64 ")\n",
590+
reg, offset);
603591
break;
604592
case DW_CFA_def_cfa_offset_sf:
605593
results->cfaRegisterOffset = (int32_t)
606594
(addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor);
607595
results->codeOffsetAtStackDecrement = (uint32_t)codeOffset;
608-
if (logDwarf)
609-
fprintf(stderr, "DW_CFA_def_cfa_offset_sf(%d)\n",
610-
results->cfaRegisterOffset);
596+
_LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset_sf(%d)\n",
597+
results->cfaRegisterOffset);
611598
break;
612599
case DW_CFA_val_offset:
613600
reg = addressSpace.getULEB128(p, instructionsEnd);
614601
offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
615602
* cieInfo.dataAlignFactor;
616603
results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
617604
results->savedRegisters[reg].value = offset;
618-
if (logDwarf)
619-
fprintf(stderr,
620-
"DW_CFA_val_offset(reg=%" PRIu64 ", offset=%" PRId64 "\n", reg,
621-
offset);
605+
_LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", "
606+
"offset=%" PRId64 "\n",
607+
reg, offset);
622608
break;
623609
case DW_CFA_val_offset_sf:
624610
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -630,10 +616,9 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
630616
addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
631617
results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
632618
results->savedRegisters[reg].value = offset;
633-
if (logDwarf)
634-
fprintf(stderr,
635-
"DW_CFA_val_offset_sf(reg=%" PRIu64 ", offset=%" PRId64 "\n",
636-
reg, offset);
619+
_LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", "
620+
"offset=%" PRId64 "\n",
621+
reg, offset);
637622
break;
638623
case DW_CFA_val_expression:
639624
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -645,16 +630,14 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
645630
results->savedRegisters[reg].value = (int64_t)p;
646631
length = addressSpace.getULEB128(p, instructionsEnd);
647632
p += length;
648-
if (logDwarf)
649-
fprintf(stderr, "DW_CFA_val_expression(reg=%" PRIu64
650-
", expression=0x%" PRIx64 ", length=%" PRIu64 ")\n",
651-
reg, results->savedRegisters[reg].value, length);
633+
_LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", "
634+
"expression=0x%" PRIx64 ", length=%" PRIu64 ")\n",
635+
reg, results->savedRegisters[reg].value, length);
652636
break;
653637
case DW_CFA_GNU_args_size:
654638
length = addressSpace.getULEB128(p, instructionsEnd);
655639
results->spExtraArgSize = (uint32_t)length;
656-
if (logDwarf)
657-
fprintf(stderr, "DW_CFA_GNU_args_size(%" PRIu64 ")\n", length);
640+
_LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_args_size(%" PRIu64 ")\n", length);
658641
break;
659642
case DW_CFA_GNU_negative_offset_extended:
660643
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -667,9 +650,8 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
667650
* cieInfo.dataAlignFactor;
668651
results->savedRegisters[reg].location = kRegisterInCFA;
669652
results->savedRegisters[reg].value = -offset;
670-
if (logDwarf)
671-
fprintf(stderr, "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n",
672-
offset);
653+
_LIBUNWIND_TRACE_DWARF(
654+
"DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);
673655
break;
674656
default:
675657
operand = opcode & 0x3F;
@@ -680,25 +662,22 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
680662
* cieInfo.dataAlignFactor;
681663
results->savedRegisters[reg].location = kRegisterInCFA;
682664
results->savedRegisters[reg].value = offset;
683-
if (logDwarf)
684-
fprintf(stderr, "DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
685-
operand, offset);
665+
_LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
666+
operand, offset);
686667
break;
687668
case DW_CFA_advance_loc:
688669
codeOffset += operand * cieInfo.codeAlignFactor;
689-
if (logDwarf)
690-
fprintf(stderr, "DW_CFA_advance_loc: new offset=%" PRIu64 "\n",
691-
(uint64_t)codeOffset);
670+
_LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n",
671+
static_cast<uint64_t>(codeOffset));
692672
break;
693673
case DW_CFA_restore:
694674
reg = operand;
695675
results->savedRegisters[reg] = initialState.savedRegisters[reg];
696-
if (logDwarf)
697-
fprintf(stderr, "DW_CFA_restore(reg=%" PRIu64 ")\n", reg);
676+
_LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n",
677+
static_cast<long>(operand));
698678
break;
699679
default:
700-
if (logDwarf)
701-
fprintf(stderr, "unknown CFA opcode 0x%02X\n", opcode);
680+
_LIBUNWIND_TRACE_DWARF("unknown CFA opcode 0x%02X\n", opcode);
702681
return false;
703682
}
704683
}

src/libunwind.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,5 +371,17 @@ bool logUnwinding() {
371371
return log;
372372
}
373373

374+
_LIBUNWIND_HIDDEN
375+
bool logDWARF() {
376+
// do manual lock to avoid use of _cxa_guard_acquire or initializers
377+
static bool checked = false;
378+
static bool log = false;
379+
if (!checked) {
380+
log = (getenv("LIBUNWIND_PRINT_DWARF") != NULL);
381+
checked = true;
382+
}
383+
return log;
384+
}
385+
374386
#endif // NDEBUG
375387

0 commit comments

Comments
 (0)