If we have a function with an unreachable statement such that the ending debug

information is in an unreachable block, then it's possible that the high/low pc
values won't be set for the dwarf information. E.g., this function:

void abort(void) __attribute__((__noreturn__));
void dead_beef(void) __attribute__ ((noreturn));

int *b;

void dead_beef(void) {
  *b=0xdeadbeef;
  abort();
}

has a call to "@llvm.dbg.region.end" only in the unreachable block:

define void @dead_beef() noreturn nounwind  {
entry:
	call void @llvm.dbg.func.start(...)
	call void @llvm.dbg.stoppoint(...)
...
	call void @abort( ) noreturn nounwind 
	unreachable

return:		; No predecessors!
	call void @llvm.dbg.stoppoint(...)
	call void @llvm.dbg.region.end(...)
	ret void
}

The dwarf information emitted is something like:

0x00000084:     TAG_subprogram [5]  
                 AT_name( "dead_beef" )
                 AT_external( 0x01 )
                 AT_prototyped( 0x01 )
                 AT_decl_file( 0x01 )
                 AT_decl_line( 0x08 )

Note that this is *not* the best fix for this problem, but a band-aid for an
gaping wound. This code needs to be changed when we revamp our debugging
information.

llvm-svn: 56628
This commit is contained in:
Bill Wendling 2008-09-26 00:28:12 +00:00
parent 9dbe45c000
commit 374d7f2b16
5 changed files with 55 additions and 11 deletions

View File

@ -74,7 +74,7 @@ public:
/// EndFunction - Gather and emit post-function debug information.
///
void EndFunction();
void EndFunction(MachineFunction *MF);
};

View File

@ -2031,6 +2031,39 @@ private:
ConstructScope(RootScope, 0, 0, SPDie, Unit);
}
/// ConstructDefaultScope - Construct a default scope for the subprogram.
///
void ConstructDefaultScope(MachineFunction *MF) {
// Find the correct subprogram descriptor.
std::vector<SubprogramDesc *> Subprograms;
MMI->getAnchoredDescriptors<SubprogramDesc>(*M, Subprograms);
for (unsigned i = 0, N = Subprograms.size(); i < N; ++i) {
SubprogramDesc *SPD = Subprograms[i];
if (SPD->getName() == MF->getFunction()->getName()) {
// Get the compile unit context.
CompileUnit *Unit = GetBaseCompileUnit();
// Get the subprogram die.
DIE *SPDie = Unit->getDieMapSlotFor(SPD);
assert(SPDie && "Missing subprogram descriptor");
// Add the function bounds.
AddLabel(SPDie, DW_AT_low_pc, DW_FORM_addr,
DWLabel("func_begin", SubprogramCount));
AddLabel(SPDie, DW_AT_high_pc, DW_FORM_addr,
DWLabel("func_end", SubprogramCount));
MachineLocation Location(RI->getFrameRegister(*MF));
AddAddress(SPDie, DW_AT_frame_base, Location);
return;
}
}
assert(0 && "Couldn't find DIE for machine function!");
}
/// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc
/// tools to recognize the object file contains Dwarf information.
void EmitInitial() {
@ -2588,7 +2621,7 @@ private:
Asm->SwitchToDataSection(TAI->getDwarfARangesSection());
// FIXME - Mock up
#if 0
#if 0
CompileUnit *Unit = GetBaseCompileUnit();
// Don't include size of length
@ -2612,7 +2645,7 @@ private:
Asm->EmitInt32(0); Asm->EOL("EOM (1)");
Asm->EmitInt32(0); Asm->EOL("EOM (2)");
#endif
#endif
Asm->EOL();
}
@ -2822,7 +2855,7 @@ public:
/// EndFunction - Gather and emit post-function debug information.
///
void EndFunction() {
void EndFunction(MachineFunction *MF) {
if (!ShouldEmitDwarf()) return;
// Define end label for subprogram.
@ -2842,7 +2875,18 @@ public:
}
// Construct scopes for subprogram.
ConstructRootScope(MMI->getRootScope());
if (MMI->getRootScope())
ConstructRootScope(MMI->getRootScope());
else
// FIXME: This is wrong. We are essentially getting past a problem with
// debug information not being able to handle unreachable blocks that have
// debug information in them. In particular, those unreachable blocks that
// have "region end" info in them. That situation results in the "root
// scope" not being created. If that's the case, then emit a "default"
// scope, i.e., one that encompasses the whole function. This isn't
// desirable. And a better way of handling this (and all of the debugging
// information) needs to be explored.
ConstructDefaultScope(MF);
DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
MMI->getFrameMoves()));
@ -3922,8 +3966,8 @@ void DwarfWriter::BeginFunction(MachineFunction *MF) {
/// EndFunction - Gather and emit post-function debug information.
///
void DwarfWriter::EndFunction() {
DD->EndFunction();
void DwarfWriter::EndFunction(MachineFunction *MF) {
DD->EndFunction(MF);
DE->EndFunction();
if (MachineModuleInfo *MMI = DD->getMMI() ? DD->getMMI() : DE->getMMI())

View File

@ -461,7 +461,7 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF)
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
// Emit post-function debug information.
DW.EndFunction();
DW.EndFunction(&MF);
// We didn't modify anything.
return false;

View File

@ -617,7 +617,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
// Emit post-function debug information.
DW.EndFunction();
DW.EndFunction(&MF);
// We didn't modify anything.
return false;
@ -809,7 +809,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
// Emit post-function debug information.
DW.EndFunction();
DW.EndFunction(&MF);
// We didn't modify anything.
return false;

View File

@ -260,7 +260,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// Emit post-function debug information.
if (TAI->doesSupportDebugInformation())
DW.EndFunction();
DW.EndFunction(&MF);
// Print out jump tables referenced by the function.
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);