diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index 32d6c40685..6850e1577a 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -248,22 +248,34 @@ DebugReportGenerator::_DumpLoadedImages(BString& _output) AutoLocker< ::Team> locker(fTeam); _output << "\nLoaded Images:\n"; + BObjectList images; BString data; for (ImageList::ConstIterator it = fTeam->Images().GetIterator(); Image* image = it.Next();) { + images.AddItem(image); + } + + images.SortItems(&_CompareImages); + + Image* image = NULL; + data.SetToFormat("\tID\t\tText Base\tText End\tData Base\tData" + " End\tType\t\tName\n\t"); + _output << data; + _output.Append('-', 80); + _output.Append("\n"); + for (int32 i = 0; (image = images.ItemAt(i)) != NULL; i++) { const ImageInfo& info = image->Info(); char buffer[32]; try { target_addr_t textBase = info.TextBase(); target_addr_t dataBase = info.DataBase(); - data.SetToFormat("\t%s (%" B_PRId32 ", %s) " - "Text: %#08" B_PRIx64 " - %#08" B_PRIx64 ", Data: %#08" - B_PRIx64 " - %#08" B_PRIx64 "\n", info.Name().String(), - info.ImageID(), UiUtils::ImageTypeToString(info.Type(), - buffer, sizeof(buffer)), textBase, - textBase + info.TextSize(), dataBase, - dataBase + info.DataSize()); + data.SetToFormat("\t%" B_PRId32 "\t0x%08" B_PRIx64 "\t" + "0x%08" B_PRIx64 "\t0x%08" B_PRIx64 "\t0x%08" B_PRIx64 "\t" + "%-7s\t\t%s\n", info.ImageID(), textBase, textBase + info.TextSize(), + dataBase, dataBase + info.DataSize(), + UiUtils::ImageTypeToString(info.Type(), buffer, + sizeof(buffer)), info.Name().String()); _output << data; } catch (...) { @@ -283,22 +295,27 @@ DebugReportGenerator::_DumpAreas(BString& _output) if (result != B_OK) return result; + areas.SortItems(&_CompareAreas); + _output << "\nAreas:\n"; BString data; + data.SetToFormat("\tID\t\tBase\t\tEnd\t\t\tSize (KiB)\tProtection\tLocking\t\t\t\tName\n\t"); + _output << data; + _output.Append('-', 80); + _output.Append("\n"); AreaInfo* info; BString protectionBuffer; char lockingBuffer[32]; for (int32 i = 0; (info = areas.ItemAt(i)) != NULL; i++) { try { - data.SetToFormat("\t%s (%" B_PRId32 ") " - "Base: %#08" B_PRIx64 ", Size: %" B_PRId64 - ", RAM Size: %" B_PRId64 ",Locking: %s, Protection: %s\n", - info->Name().String(), info->AreaID(), info->BaseAddress(), - info->Size(), info->RamSize(), - UiUtils::AreaLockingFlagsToString(info->Lock(), lockingBuffer, - sizeof(lockingBuffer)), + data.SetToFormat("\t%" B_PRId32 "\t0x%08" B_PRIx64 "\t" + "0x%08" B_PRIx64 "\t%10" B_PRId64 "\t%-11s\t%-17s\t%s\n", + info->AreaID(), info->BaseAddress(), info->BaseAddress() + + info->Size(), info->Size() / 1024, UiUtils::AreaProtectionFlagsToString(info->Protection(), - protectionBuffer).String()); + protectionBuffer).String(), + UiUtils::AreaLockingFlagsToString(info->Lock(), lockingBuffer, + sizeof(lockingBuffer)), info->Name().String()); _output << data; } catch (...) { @@ -306,6 +323,9 @@ DebugReportGenerator::_DumpAreas(BString& _output) } } + _output << "\nProtection Flags: r - read, w - write, x - execute, " + "s - stack, o - overcommit, c - cloneable, S - shared, k - kernel\n"; + return B_OK; } @@ -318,15 +338,20 @@ DebugReportGenerator::_DumpSemaphores(BString& _output) if (result != B_OK) return result; + semaphores.SortItems(&_CompareSemaphores); + _output << "\nSemaphores:\n"; BString data; + data.SetToFormat("\tID\t\tCount\tLast Holder\t\tName\n\t"); + _output << data; + _output.Append('-', 80); + _output.Append("\n"); SemaphoreInfo* info; for (int32 i = 0; (info = semaphores.ItemAt(i)) != NULL; i++) { try { - data.SetToFormat("\t%s (%" B_PRId32 ") " - "Count: %" B_PRId32 ", Latest Holding Thread: %" B_PRId32 "\n", - info->Name().String(), info->SemID(), info->Count(), - info->LatestHolder()); + data.SetToFormat("\t%" B_PRId32 "\t%5" B_PRId32 "\t%11" B_PRId32 + "\t\t%s\n", info->SemID(), info->Count(), + info->LatestHolder(), info->Name().String()); _output << data; } catch (...) { @@ -346,24 +371,30 @@ DebugReportGenerator::_DumpRunningThreads(BString& _output) _output << "\nActive Threads:\n"; BString data; status_t result = B_OK; + BObjectList< ::Thread> threads; + ::Thread* thread; for (ThreadList::ConstIterator it = fTeam->Threads().GetIterator(); - ::Thread* thread = it.Next();) { + (thread = it.Next());) { + threads.AddItem(thread); + } + + threads.SortItems(&_CompareThreads); + for (int32 i = 0; (thread = threads.ItemAt(i)) != NULL; i++) { try { - data.SetToFormat("\t%s %s, id: %" B_PRId32", state: %s", + data.SetToFormat("\tthread %" B_PRId32 ": %s %s", thread->ID(), thread->Name(), thread->IsMainThread() - ? "(main)" : "", thread->ID(), - UiUtils::ThreadStateToString(thread->State(), - thread->StoppedReason())); - - if (thread->State() == THREAD_STATE_STOPPED) { - const BString& stoppedInfo = thread->StoppedReasonInfo(); - if (stoppedInfo.Length() != 0) - data << " (" << stoppedInfo << ")"; - } - + ? "(main)" : ""); _output << data << "\n"; if (thread->State() == THREAD_STATE_STOPPED) { + data.SetToFormat("\t\tstate: %s", + UiUtils::ThreadStateToString(thread->State(), + thread->StoppedReason())); + const BString& stoppedInfo = thread->StoppedReasonInfo(); + if (stoppedInfo.Length() != 0) + data << " (" << stoppedInfo << ")"; + _output << data << "\n\n"; + // we need to release our lock on the team here // since we might need to block and wait // on the stack trace. @@ -554,3 +585,51 @@ DebugReportGenerator::_HandleMemoryBlockRetrieved(TeamMemoryBlock* block, fCurrentBlock = block; release_sem(fTeamDataSem); } + + +/*static*/ int +DebugReportGenerator::_CompareAreas(const AreaInfo* a, const AreaInfo* b) +{ + if (a->BaseAddress() < b->BaseAddress()) + return -1; + + return 1; +} + + +/*static*/ int +DebugReportGenerator::_CompareImages(const Image* a, const Image* b) +{ + if (a->Info().TextBase() < b->Info().TextBase()) + return -1; + + return 1; +} + + +/*static*/ int +DebugReportGenerator::_CompareSemaphores(const SemaphoreInfo* a, + const SemaphoreInfo* b) +{ + if (a->SemID() < b->SemID()) + return -1; + + return 1; +} + + +/*static*/ int +DebugReportGenerator::_CompareThreads(const ::Thread* a, + const ::Thread* b) +{ + // sort stopped threads last, otherwise sort by thread ID + if (a->State() == b->State()) + return a->ID() < b->ID() ? -1 : 1; + + if (a->State() == THREAD_STATE_STOPPED && b->State() + != THREAD_STATE_STOPPED) { + return 1; + } + + return -1; +} diff --git a/src/apps/debugger/controllers/DebugReportGenerator.h b/src/apps/debugger/controllers/DebugReportGenerator.h index f19fa1bf97..13746e9502 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.h +++ b/src/apps/debugger/controllers/DebugReportGenerator.h @@ -15,8 +15,10 @@ class entry_ref; class Architecture; +class AreaInfo; class BString; class DebuggerInterface; +class SemaphoreInfo; class StackFrame; class Team; class Thread; @@ -77,6 +79,13 @@ private: void _HandleMemoryBlockRetrieved( TeamMemoryBlock* block, status_t result); + static int _CompareAreas(const AreaInfo* a, + const AreaInfo* b); + static int _CompareImages(const Image* a, const Image* b); + static int _CompareSemaphores(const SemaphoreInfo* a, + const SemaphoreInfo* b); + static int _CompareThreads(const ::Thread* a, + const ::Thread* b); private: ::Team* fTeam; Architecture* fArchitecture; diff --git a/src/apps/debugger/user_interface/util/UiUtils.cpp b/src/apps/debugger/user_interface/util/UiUtils.cpp index 69d75c379a..947003cf4d 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.cpp +++ b/src/apps/debugger/user_interface/util/UiUtils.cpp @@ -129,19 +129,19 @@ UiUtils::ImageTypeToString(image_type type, char* buffer, size_t bufferSize) { switch (type) { case B_APP_IMAGE: - snprintf(buffer, bufferSize, "Application"); + snprintf(buffer, bufferSize, "app"); break; case B_LIBRARY_IMAGE: - snprintf(buffer, bufferSize, "Library"); + snprintf(buffer, bufferSize, "lib"); break; case B_ADD_ON_IMAGE: - snprintf(buffer, bufferSize, "Add-on"); + snprintf(buffer, bufferSize, "add-on"); break; case B_SYSTEM_IMAGE: - snprintf(buffer, bufferSize, "System"); + snprintf(buffer, bufferSize, "system"); break; default: - snprintf(buffer, bufferSize, "Unknown"); + snprintf(buffer, bufferSize, "unknown"); break; } @@ -155,28 +155,28 @@ UiUtils::AreaLockingFlagsToString(uint32 flags, char* buffer, { switch (flags) { case B_NO_LOCK: - snprintf(buffer, bufferSize, "None"); + snprintf(buffer, bufferSize, "none"); break; case B_LAZY_LOCK: - snprintf(buffer, bufferSize, "Lazy"); + snprintf(buffer, bufferSize, "lazy"); break; case B_FULL_LOCK: - snprintf(buffer, bufferSize, "Full"); + snprintf(buffer, bufferSize, "full"); break; case B_CONTIGUOUS: - snprintf(buffer, bufferSize, "Contiguous"); + snprintf(buffer, bufferSize, "contiguous"); break; case B_LOMEM: - snprintf(buffer, bufferSize, "Lo-mem"); + snprintf(buffer, bufferSize, "lo-mem"); break; case B_32_BIT_FULL_LOCK: - snprintf(buffer, bufferSize, "32-bit Full"); + snprintf(buffer, bufferSize, "32-bit full"); break; case B_32_BIT_CONTIGUOUS: - snprintf(buffer, bufferSize, "32-bit Contiguous"); + snprintf(buffer, bufferSize, "32-bit contiguous"); break; default: - snprintf(buffer, bufferSize, "Unknown"); + snprintf(buffer, bufferSize, "unknown"); break; } @@ -188,56 +188,54 @@ UiUtils::AreaLockingFlagsToString(uint32 flags, char* buffer, UiUtils::AreaProtectionFlagsToString(uint32 protection, BString& _output) { #undef ADD_AREA_FLAG_IF_PRESENT - #define ADD_AREA_FLAG_IF_PRESENT(flag, protection, name, output) \ + #define ADD_AREA_FLAG_IF_PRESENT(flag, protection, name, output, missing)\ if ((protection & flag) != 0) { \ _output += name; \ protection &= ~flag; \ - } + } else \ + _output += missing; \ _output.Truncate(0); uint32 userFlags = protection & B_USER_PROTECTION; - if ((protection & B_USER_PROTECTION) != 0) { - ADD_AREA_FLAG_IF_PRESENT(B_READ_AREA, protection, "r", _output); - ADD_AREA_FLAG_IF_PRESENT(B_WRITE_AREA, protection, "w", _output); - ADD_AREA_FLAG_IF_PRESENT(B_EXECUTE_AREA, protection, "x", _output); - ADD_AREA_FLAG_IF_PRESENT(B_STACK_AREA, protection, "s", _output); - ADD_AREA_FLAG_IF_PRESENT(B_OVERCOMMITTING_AREA, protection, " overcommitting", - _output); - _output += ", "; + bool userProtectionPresent = userFlags != 0; + ADD_AREA_FLAG_IF_PRESENT(B_READ_AREA, protection, "r", _output, + userProtectionPresent ? "-" : " "); + ADD_AREA_FLAG_IF_PRESENT(B_WRITE_AREA, protection, "w", _output, + userProtectionPresent ? "-" : " "); + ADD_AREA_FLAG_IF_PRESENT(B_EXECUTE_AREA, protection, "x", _output, + userProtectionPresent ? "-" : " "); - // if the user versions of these flags are present, - // filter out their kernel equivalents since they're implied. - if ((userFlags & B_READ_AREA) != 0) - protection &= ~B_KERNEL_READ_AREA; - if ((userFlags & B_WRITE_AREA) != 0) - protection &= ~B_KERNEL_WRITE_AREA; - if ((userFlags & B_EXECUTE_AREA) != 0) - protection &= ~B_KERNEL_EXECUTE_AREA; - if ((userFlags & B_STACK_AREA) != 0) - protection &= ~B_KERNEL_STACK_AREA; - } - if ((protection & B_KERNEL_AREA_FLAGS) != 0) { - _output += "kernel:"; - ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_READ_AREA, protection, "r", _output); + // if the user versions of these flags are present, + // filter out their kernel equivalents since they're implied. + if ((userFlags & B_READ_AREA) != 0) + protection &= ~B_KERNEL_READ_AREA; + if ((userFlags & B_WRITE_AREA) != 0) + protection &= ~B_KERNEL_WRITE_AREA; + if ((userFlags & B_EXECUTE_AREA) != 0) + protection &= ~B_KERNEL_EXECUTE_AREA; + + if ((protection & B_KERNEL_PROTECTION) != 0) { + ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_READ_AREA, protection, "r", + _output, "-"); ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_WRITE_AREA, protection, "w", - _output); + _output, "-"); ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_EXECUTE_AREA, protection, "x", - _output); - ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_STACK_AREA, protection, "s", - _output); - ADD_AREA_FLAG_IF_PRESENT(B_USER_CLONEABLE_AREA, protection, " cloneable", - _output); - ADD_AREA_FLAG_IF_PRESENT(B_SHARED_AREA, protection, " shared", _output); - _output += ", "; + _output, "-"); } + ADD_AREA_FLAG_IF_PRESENT(B_STACK_AREA, protection, "s", _output, ""); + ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_STACK_AREA, protection, "s", _output, ""); + ADD_AREA_FLAG_IF_PRESENT(B_OVERCOMMITTING_AREA, protection, _output, "o", + ""); + ADD_AREA_FLAG_IF_PRESENT(B_SHARED_AREA, protection, "S", _output, ""); + ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_AREA, protection, "k", _output, ""); + if (protection != 0) { char buffer[32]; - snprintf(buffer, sizeof(buffer), " Unknown (%#04" B_PRIx32 ")", + snprintf(buffer, sizeof(buffer), ", u:(%#04" B_PRIx32 ")", protection); _output += buffer; - } else if (!_output.IsEmpty()) - _output.Truncate(_output.Length() - 2); + } return _output; }