From b65adbdfbc322bb7d86d74049389c688e9962f15 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Fri, 9 Sep 2016 22:41:07 -0400 Subject: [PATCH] Debugger: Fix #12940. - Add new interface TeamFunctionSourceInformation. Currently this exposes a single function allowing one to query for the currently active source code given a FunctionDebugInfo instance. - Implement TeamFunctionSourceInformation on TeamDebugInfo. - Pass TeamFunctionSourceInformation to Dwarf{Team,Image}DebugInfo. In turn, make use of it in DwarfImageDebugInfo::GetStatement() in order to determine whether to return the corresponding assembly or source statement. With this piece of information, the debugger is now correctly able to determine that the user is currently looking at disassembly despite debug info being available, and consequently adjust its stepping behavior based on that. Previously, the source code statement was always used, leading to it not being possible to single step assembly lines in such a circumstance without manually using run to cursor. Other related cleanups: - TeamDebugInfo now inherits BReferenceable directly, rather than relying on indirectly inheriting it from TeamTypeInformation. - Remove BReferenceable from TeamTypeInformation. The latter is only an interface anyways, and inheriting that base class from multiple locations was causing GCC5 trouble when resolving BReference, even when virtual inheritance was used. --- .../debugger/debug_info/TeamDebugInfo.h | 10 +++-- .../model/TeamFunctionSourceInformation.h | 25 ++++++++++++ .../debugger/model/TeamTypeInformation.h | 5 +-- src/kits/debugger/Jamfile | 1 + .../debug_info/DwarfImageDebugInfo.cpp | 16 +++++++- .../debugger/debug_info/DwarfImageDebugInfo.h | 5 ++- .../debug_info/DwarfTeamDebugInfo.cpp | 8 ++-- .../debugger/debug_info/DwarfTeamDebugInfo.h | 5 ++- .../debugger/debug_info/TeamDebugInfo.cpp | 39 ++++++++++++++++++- .../model/TeamFunctionSourceInformation.cpp | 12 ++++++ 10 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 headers/private/debugger/model/TeamFunctionSourceInformation.h create mode 100644 src/kits/debugger/model/TeamFunctionSourceInformation.cpp diff --git a/headers/private/debugger/debug_info/TeamDebugInfo.h b/headers/private/debugger/debug_info/TeamDebugInfo.h index e95202a038..817f02a688 100644 --- a/headers/private/debugger/debug_info/TeamDebugInfo.h +++ b/headers/private/debugger/debug_info/TeamDebugInfo.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2014, Rene Gollent, rene@gollent.com. + * Copyright 2014-2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_DEBUG_INFO_H @@ -15,9 +15,9 @@ #include "GlobalTypeLookup.h" #include "ImageInfo.h" +#include "TeamFunctionSourceInformation.h" #include "TeamTypeInformation.h" - class Architecture; class DebuggerInterface; class DisassembledCode; @@ -35,7 +35,8 @@ class SourceLocation; class SpecificTeamDebugInfo; -class TeamDebugInfo : public GlobalTypeLookup, public TeamTypeInformation { +class TeamDebugInfo : public BReferenceable, public GlobalTypeLookup, + public TeamTypeInformation, public TeamFunctionSourceInformation { public: TeamDebugInfo( DebuggerInterface* debuggerInterface, @@ -59,6 +60,9 @@ public: virtual bool TypeExistsByName(const BString& name, const TypeLookupConstraints& constraints); + virtual status_t GetActiveSourceCode(FunctionDebugInfo* info, + SourceCode*& _code); + status_t LoadImageDebugInfo(const ImageInfo& imageInfo, LocatableFile* imageFile, ImageDebugInfoLoadingState& state, diff --git a/headers/private/debugger/model/TeamFunctionSourceInformation.h b/headers/private/debugger/model/TeamFunctionSourceInformation.h new file mode 100644 index 0000000000..3c649a75a0 --- /dev/null +++ b/headers/private/debugger/model/TeamFunctionSourceInformation.h @@ -0,0 +1,25 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef TEAM_FUNCTION_SOURCE_INFORMATION_H +#define TEAM_FUNCTION_SOURCE_INFORMATION_H + + +#include + +class FunctionDebugInfo; +class SourceCode; + + +class TeamFunctionSourceInformation { +public: + virtual ~TeamFunctionSourceInformation(); + + virtual status_t GetActiveSourceCode(FunctionDebugInfo* info, + SourceCode*& _code) = 0; + // returns reference +}; + + +#endif // TEAM_FUNCTION_SOURCE_INFORMATION_H diff --git a/headers/private/debugger/model/TeamTypeInformation.h b/headers/private/debugger/model/TeamTypeInformation.h index 6748056ddd..0aafbb7f86 100644 --- a/headers/private/debugger/model/TeamTypeInformation.h +++ b/headers/private/debugger/model/TeamTypeInformation.h @@ -1,12 +1,11 @@ /* - * Copyright 2011-2014, Rene Gollent, rene@gollent.com. + * Copyright 2011-2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_TYPE_INFORMATION_H #define TEAM_TYPE_INFORMATION_H -#include #include @@ -15,7 +14,7 @@ class Type; class TypeLookupConstraints; -class TeamTypeInformation : public BReferenceable { +class TeamTypeInformation { public: virtual ~TeamTypeInformation(); diff --git a/src/kits/debugger/Jamfile b/src/kits/debugger/Jamfile index 6bab1eaddb..36f0956bdc 100644 --- a/src/kits/debugger/Jamfile +++ b/src/kits/debugger/Jamfile @@ -211,6 +211,7 @@ local sources = SystemInfo.cpp TargetHost.cpp Team.cpp + TeamFunctionSourceInformation.cpp TeamInfo.cpp TeamMemory.cpp TeamMemoryBlock.cpp diff --git a/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp index 11e62addb7..054c9b9579 100644 --- a/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -54,6 +54,7 @@ #include "SymbolInfo.h" #include "TargetAddressRangeList.h" #include "Team.h" +#include "TeamFunctionSourceInformation.h" #include "TeamMemory.h" #include "Tracing.h" #include "TypeLookupConstraints.h" @@ -329,7 +330,8 @@ struct DwarfImageDebugInfo::TypeEntryInfo { DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo, DebuggerInterface* interface, Architecture* architecture, FileManager* fileManager, GlobalTypeLookup* typeLookup, - GlobalTypeCache* typeCache, DwarfFile* file) + GlobalTypeCache* typeCache, TeamFunctionSourceInformation* sourceInfo, + DwarfFile* file) : fLock("dwarf image debug info"), fImageInfo(imageInfo), @@ -338,6 +340,7 @@ DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo, fFileManager(fileManager), fTypeLookup(typeLookup), fTypeCache(typeCache), + fSourceInfo(sourceInfo), fTypeNameTable(NULL), fFile(file), fTextSegment(NULL), @@ -809,6 +812,17 @@ DwarfImageDebugInfo::GetStatement(FunctionDebugInfo* _function, return fArchitecture->GetStatement(function, address, _statement); } + SourceCode* sourceCode = NULL; + status_t error = fSourceInfo->GetActiveSourceCode(_function, sourceCode); + BReference sourceReference(sourceCode, true); + if (error != B_OK || dynamic_cast(sourceCode) != NULL) { + // either no source code or disassembly is currently active (i.e. + // due to failing to locate the source file on disk or the user + // deliberately switching to disassembly view). + // return the assembly statement. + return fArchitecture->GetStatement(function, address, _statement); + } + // get the index of the source file in the compilation unit for cheaper // comparison below int32 fileIndex = _GetSourceFileIndex(unit, file); diff --git a/src/kits/debugger/debug_info/DwarfImageDebugInfo.h b/src/kits/debugger/debug_info/DwarfImageDebugInfo.h index db48b9b4fc..05c163cea3 100644 --- a/src/kits/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/kits/debugger/debug_info/DwarfImageDebugInfo.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010-2014, Rene Gollent, rene@gollent.com. + * Copyright 2010-2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_IMAGE_DEBUG_INFO_H @@ -33,6 +33,7 @@ class GlobalTypeCache; class GlobalTypeLookup; class LocatableFile; class SourceCode; +class TeamFunctionSourceInformation; class DwarfImageDebugInfo : public SpecificImageDebugInfo { @@ -43,6 +44,7 @@ public: FileManager* fileManager, GlobalTypeLookup* typeLookup, GlobalTypeCache* typeCache, + TeamFunctionSourceInformation* sourceInfo, DwarfFile* file); virtual ~DwarfImageDebugInfo(); @@ -138,6 +140,7 @@ private: FileManager* fFileManager; GlobalTypeLookup* fTypeLookup; GlobalTypeCache* fTypeCache; + TeamFunctionSourceInformation* fSourceInfo; TypeNameTable* fTypeNameTable; DwarfFile* fFile; ElfSegment* fTextSegment; diff --git a/src/kits/debugger/debug_info/DwarfTeamDebugInfo.cpp b/src/kits/debugger/debug_info/DwarfTeamDebugInfo.cpp index fa035bfbfe..06d8e708b8 100644 --- a/src/kits/debugger/debug_info/DwarfTeamDebugInfo.cpp +++ b/src/kits/debugger/debug_info/DwarfTeamDebugInfo.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2014, Rene Gollent, rene@gollent.com. + * Copyright 2014-2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -23,13 +23,15 @@ DwarfTeamDebugInfo::DwarfTeamDebugInfo(Architecture* architecture, DebuggerInterface* interface, FileManager* fileManager, - GlobalTypeLookup* typeLookup, GlobalTypeCache* typeCache) + GlobalTypeLookup* typeLookup, TeamFunctionSourceInformation* sourceInfo, + GlobalTypeCache* typeCache) : fArchitecture(architecture), fDebuggerInterface(interface), fFileManager(fileManager), fManager(NULL), fTypeLookup(typeLookup), + fSourceInfo(sourceInfo), fTypeCache(typeCache) { fDebuggerInterface->AcquireReference(); @@ -95,7 +97,7 @@ DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo, // create the image debug info DwarfImageDebugInfo* debugInfo = new(std::nothrow) DwarfImageDebugInfo( imageInfo, fDebuggerInterface, fArchitecture, fFileManager, - fTypeLookup, fTypeCache, dwarfState->GetFileState().dwarfFile); + fTypeLookup, fTypeCache, fSourceInfo, dwarfState->GetFileState().dwarfFile); if (debugInfo == NULL) return B_NO_MEMORY; diff --git a/src/kits/debugger/debug_info/DwarfTeamDebugInfo.h b/src/kits/debugger/debug_info/DwarfTeamDebugInfo.h index fa2891b925..ace61427b6 100644 --- a/src/kits/debugger/debug_info/DwarfTeamDebugInfo.h +++ b/src/kits/debugger/debug_info/DwarfTeamDebugInfo.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2014, Rene Gollent, rene@gollent.com. + * Copyright 2014-2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_TEAM_DEBUG_INFO_H @@ -16,6 +16,7 @@ class FileManager; class ImageInfo; class GlobalTypeCache; class GlobalTypeLookup; +class TeamFunctionSourceInformation; class TeamMemory; @@ -25,6 +26,7 @@ public: DebuggerInterface* interface, FileManager* fileManager, GlobalTypeLookup* typeLookup, + TeamFunctionSourceInformation* sourceInfo, GlobalTypeCache* typeCache); virtual ~DwarfTeamDebugInfo(); @@ -41,6 +43,7 @@ private: FileManager* fFileManager; DwarfManager* fManager; GlobalTypeLookup* fTypeLookup; + TeamFunctionSourceInformation* fSourceInfo; GlobalTypeCache* fTypeCache; }; diff --git a/src/kits/debugger/debug_info/TeamDebugInfo.cpp b/src/kits/debugger/debug_info/TeamDebugInfo.cpp index 6424786e41..1736a19713 100644 --- a/src/kits/debugger/debug_info/TeamDebugInfo.cpp +++ b/src/kits/debugger/debug_info/TeamDebugInfo.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2012-2014, Rene Gollent, rene@gollent.com. + * Copyright 2012-2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -346,7 +346,8 @@ TeamDebugInfo::Init() // DWARF DwarfTeamDebugInfo* dwarfInfo = new(std::nothrow) DwarfTeamDebugInfo( - fArchitecture, fDebuggerInterface, fFileManager, this, fTypeCache); + fArchitecture, fDebuggerInterface, fFileManager, this, this, + fTypeCache); if (dwarfInfo == NULL || !fSpecificInfos.AddItem(dwarfInfo)) { delete dwarfInfo; return B_NO_MEMORY; @@ -476,6 +477,40 @@ TeamDebugInfo::HasType(GlobalTypeCache* cache, const BString& name, } +status_t +TeamDebugInfo::GetActiveSourceCode(FunctionDebugInfo* info, SourceCode*& _code) +{ + AutoLocker locker(fLock); + + LocatableFile* file = info->SourceFile(); + if (file != NULL) { + Function* function = FunctionAtSourceLocation(file, + info->SourceStartLocation()); + if (function != NULL) { + if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) { + _code = function->GetSourceCode(); + _code->AcquireReference(); + return B_OK; + } + } + } + + for (int32 i = 0; i < fImages.CountItems(); i++) { + ImageDebugInfo* imageInfo = fImages.ItemAt(i); + FunctionInstance* instance = imageInfo->FunctionAtAddress( + info->Address()); + if (instance != NULL && instance->SourceCodeState() + == FUNCTION_SOURCE_LOADED) { + _code = instance->GetSourceCode(); + _code->AcquireReference(); + return B_OK; + } + } + + return B_ENTRY_NOT_FOUND; +} + + status_t TeamDebugInfo::LoadImageDebugInfo(const ImageInfo& imageInfo, LocatableFile* imageFile, ImageDebugInfoLoadingState& _state, diff --git a/src/kits/debugger/model/TeamFunctionSourceInformation.cpp b/src/kits/debugger/model/TeamFunctionSourceInformation.cpp new file mode 100644 index 0000000000..384d990e3c --- /dev/null +++ b/src/kits/debugger/model/TeamFunctionSourceInformation.cpp @@ -0,0 +1,12 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "TeamFunctionSourceInformation.h" + + +TeamFunctionSourceInformation::~TeamFunctionSourceInformation() +{ +}