* Reorganized the image management. Introduced a SharedImage which knows the
symbols and is identified by name. Image does still represent a team-bound image, but it refers to a SharedImage for the symbols, now. This allows us to load the symbols for a shared object only once and share the data for all teams referring to it. * Made the area used for system profiling writable. "-a -f" would segfault since the return addresses are sorted in-place. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30170 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -14,8 +14,9 @@
|
||||
|
||||
|
||||
struct HitSymbol {
|
||||
int64 hits;
|
||||
Symbol* symbol;
|
||||
int64 hits;
|
||||
Symbol* symbol;
|
||||
image_id imageID;
|
||||
|
||||
inline bool operator<(const HitSymbol& other) const
|
||||
{
|
||||
@@ -146,6 +147,7 @@ BasicThreadProfileResult::PrintResults()
|
||||
HitSymbol& hitSymbol = hitSymbols[hitSymbolCount++];
|
||||
hitSymbol.hits = symbolHits[i];
|
||||
hitSymbol.symbol = symbols[i];
|
||||
hitSymbol.imageID = image->ID();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,10 +182,9 @@ BasicThreadProfileResult::PrintResults()
|
||||
"---------------------------------------\n");
|
||||
for (int32 k = 0; k < imageCount; k++) {
|
||||
BasicThreadImage* image = images[k];
|
||||
const image_info& imageInfo = image->GetImage()->Info();
|
||||
fprintf(gOptions.output, " %10lld %10lld %7ld %s\n",
|
||||
image->TotalHits(), image->UnknownHits(), imageInfo.id,
|
||||
imageInfo.name);
|
||||
image->TotalHits(), image->UnknownHits(),
|
||||
image->GetImage()->ID(), image->GetImage()->Name());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +199,7 @@ BasicThreadProfileResult::PrintResults()
|
||||
const Symbol* symbol = hitSymbol.symbol;
|
||||
fprintf(gOptions.output, " %10lld %10lld %6.2f %6ld %s\n",
|
||||
hitSymbol.hits, hitSymbol.hits * fInterval,
|
||||
100.0 * hitSymbol.hits / totalTicks, symbol->image->ID(),
|
||||
100.0 * hitSymbol.hits / totalTicks, hitSymbol.imageID,
|
||||
symbol->Name());
|
||||
}
|
||||
} else
|
||||
|
||||
@@ -271,7 +271,7 @@ CallgrindThreadProfileResult::_PrintFunction(FILE* out,
|
||||
int32 index = fNextImageOutputIndex++;
|
||||
image->SetOutputIndex(index);
|
||||
fprintf(out, "%sob=(%ld) %s:%ld\n", called ? "c" : "", index,
|
||||
image->GetImage()->Info().name, image->ID());
|
||||
image->GetImage()->Name(), image->ID());
|
||||
} else {
|
||||
// image is already known
|
||||
// TODO: We may not need to print it at all!
|
||||
|
||||
@@ -5,115 +5,22 @@
|
||||
|
||||
#include "Image.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
|
||||
#include <debug_support.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include "Options.h"
|
||||
|
||||
|
||||
Image::Image(const image_info& info, team_id owner, int32 creationEvent)
|
||||
Image::Image(SharedImage* image, const image_info& info, team_id owner,
|
||||
int32 creationEvent)
|
||||
:
|
||||
fInfo(info),
|
||||
fImage(image),
|
||||
fID(info.id),
|
||||
fOwner(owner),
|
||||
fSymbols(NULL),
|
||||
fSymbolCount(0),
|
||||
fLoadDelta((addr_t)info.text - (addr_t)image->Info().text),
|
||||
fCreationEvent(creationEvent),
|
||||
fDeletionEvent(-1)
|
||||
{
|
||||
fImage->AddReference();
|
||||
}
|
||||
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
if (fSymbols != NULL) {
|
||||
for (int32 i = 0; i < fSymbolCount; i++)
|
||||
delete fSymbols[i];
|
||||
delete[] fSymbols;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Image::LoadSymbols(debug_symbol_lookup_context* lookupContext)
|
||||
{
|
||||
// fprintf(sOptions.output, "Loading symbols of image \"%s\" (%ld)...\n",
|
||||
// fInfo.name, fInfo.id);
|
||||
|
||||
// create symbol iterator
|
||||
debug_symbol_iterator* iterator;
|
||||
status_t error = debug_create_image_symbol_iterator(lookupContext,
|
||||
fInfo.id, &iterator);
|
||||
if (error != B_OK) {
|
||||
fprintf(stderr, "Failed to init symbol iterator: %s\n",
|
||||
strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
// iterate through the symbols
|
||||
BObjectList<Symbol> symbols(512, true);
|
||||
char symbolName[1024];
|
||||
int32 symbolType;
|
||||
void* symbolLocation;
|
||||
size_t symbolSize;
|
||||
while (debug_next_image_symbol(iterator, symbolName, sizeof(symbolName),
|
||||
&symbolType, &symbolLocation, &symbolSize) == B_OK) {
|
||||
// printf(" %s %p (%6lu) %s\n",
|
||||
// symbolType == B_SYMBOL_TYPE_TEXT ? "text" : "data",
|
||||
// symbolLocation, symbolSize, symbolName);
|
||||
if (symbolSize > 0 && symbolType == B_SYMBOL_TYPE_TEXT) {
|
||||
Symbol* symbol = new(std::nothrow) Symbol(this,
|
||||
(addr_t)symbolLocation, symbolSize, symbolName);
|
||||
if (symbol == NULL || !symbols.AddItem(symbol)) {
|
||||
delete symbol;
|
||||
fprintf(stderr, "%s: Out of memory\n", kCommandName);
|
||||
debug_delete_symbol_iterator(iterator);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_delete_symbol_iterator(iterator);
|
||||
|
||||
// sort the symbols
|
||||
fSymbolCount = symbols.CountItems();
|
||||
fSymbols = new(std::nothrow) Symbol*[fSymbolCount];
|
||||
if (fSymbols == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
for (int32 i = fSymbolCount - 1; i >= 0 ; i--)
|
||||
fSymbols[i] = symbols.RemoveItemAt(i);
|
||||
|
||||
std::sort(fSymbols, fSymbols + fSymbolCount, SymbolComparator());
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Image::FindSymbol(addr_t address) const
|
||||
{
|
||||
// binary search the function
|
||||
int32 lower = 0;
|
||||
int32 upper = fSymbolCount;
|
||||
|
||||
while (lower < upper) {
|
||||
int32 mid = (lower + upper) / 2;
|
||||
if (address >= fSymbols[mid]->base + fSymbols[mid]->size)
|
||||
lower = mid + 1;
|
||||
else
|
||||
upper = mid;
|
||||
}
|
||||
|
||||
if (lower == fSymbolCount)
|
||||
return -1;
|
||||
|
||||
const Symbol* symbol = fSymbols[lower];
|
||||
if (address >= symbol->base && address < symbol->base + symbol->size)
|
||||
return lower;
|
||||
return -1;
|
||||
fImage->RemoveReference();
|
||||
}
|
||||
|
||||
@@ -5,73 +5,35 @@
|
||||
#ifndef IMAGE_H
|
||||
#define IMAGE_H
|
||||
|
||||
#include <image.h>
|
||||
#include <OS.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "Referenceable.h"
|
||||
|
||||
|
||||
class debug_symbol_lookup_context;
|
||||
class Image;
|
||||
|
||||
|
||||
class Symbol {
|
||||
public:
|
||||
Symbol(Image* image, addr_t base, size_t size, const char* name)
|
||||
:
|
||||
image(image),
|
||||
base(base),
|
||||
size(size),
|
||||
name(name)
|
||||
{
|
||||
}
|
||||
|
||||
const char* Name() const { return name.String(); }
|
||||
|
||||
Image* image;
|
||||
addr_t base;
|
||||
size_t size;
|
||||
BString name;
|
||||
};
|
||||
|
||||
|
||||
struct SymbolComparator {
|
||||
inline bool operator()(const Symbol* a, const Symbol* b) const
|
||||
{
|
||||
return a->base < b->base;
|
||||
}
|
||||
};
|
||||
#include "SharedImage.h"
|
||||
|
||||
|
||||
class Image : public Referenceable {
|
||||
public:
|
||||
Image(const image_info& info, team_id owner,
|
||||
Image(SharedImage* image,
|
||||
const image_info& info, team_id owner,
|
||||
int32 creationEvent);
|
||||
~Image();
|
||||
|
||||
inline const image_id ID() const;
|
||||
inline const image_info& Info() const;
|
||||
inline const char* Name() const;
|
||||
inline team_id Owner() const;
|
||||
|
||||
inline int32 CreationEvent() const;
|
||||
inline int32 DeletionEvent() const;
|
||||
inline void SetDeletionEvent(int32 event);
|
||||
|
||||
status_t LoadSymbols(
|
||||
debug_symbol_lookup_context* lookupContext);
|
||||
|
||||
inline Symbol** Symbols() const;
|
||||
inline int32 SymbolCount() const;
|
||||
|
||||
inline bool ContainsAddress(addr_t address) const;
|
||||
int32 FindSymbol(addr_t address) const;
|
||||
inline int32 FindSymbol(addr_t address) const;
|
||||
|
||||
private:
|
||||
image_info fInfo;
|
||||
SharedImage* fImage;
|
||||
image_id fID;
|
||||
team_id fOwner;
|
||||
Symbol** fSymbols;
|
||||
int32 fSymbolCount;
|
||||
addr_t fLoadDelta;
|
||||
int32 fCreationEvent;
|
||||
int32 fDeletionEvent;
|
||||
};
|
||||
@@ -83,14 +45,14 @@ private:
|
||||
const image_id
|
||||
Image::ID() const
|
||||
{
|
||||
return fInfo.id;
|
||||
return fID;
|
||||
}
|
||||
|
||||
|
||||
const image_info&
|
||||
Image::Info() const
|
||||
const char*
|
||||
Image::Name() const
|
||||
{
|
||||
return fInfo;
|
||||
return fImage->Name();
|
||||
}
|
||||
|
||||
|
||||
@@ -125,22 +87,28 @@ Image::SetDeletionEvent(int32 event)
|
||||
Symbol**
|
||||
Image::Symbols() const
|
||||
{
|
||||
return fSymbols;
|
||||
return fImage->Symbols();
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Image::SymbolCount() const
|
||||
{
|
||||
return fSymbolCount;
|
||||
return fImage->SymbolCount();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Image::ContainsAddress(addr_t address) const
|
||||
{
|
||||
return address >= (addr_t)fInfo.text
|
||||
&& address <= (addr_t)fInfo.data + fInfo.data_size - 1;
|
||||
return fImage->ContainsAddress(address - fLoadDelta);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Image::FindSymbol(addr_t address) const
|
||||
{
|
||||
return fImage->FindSymbol(address - fLoadDelta);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ BinCommand profile
|
||||
BasicThreadProfileResult.cpp
|
||||
CallgrindThreadProfileResult.cpp
|
||||
Image.cpp
|
||||
SharedImage.cpp
|
||||
Team.cpp
|
||||
Thread.cpp
|
||||
profile.cpp
|
||||
|
||||
@@ -78,37 +78,6 @@ Team::Init(team_id teamID, port_id debuggerPort)
|
||||
return error;
|
||||
}
|
||||
|
||||
// create symbol lookup context
|
||||
debug_symbol_lookup_context* lookupContext;
|
||||
error = debug_create_symbol_lookup_context(ID(), &lookupContext);
|
||||
if (error != B_OK) {
|
||||
fprintf(stderr, "%s: Failed to create symbol lookup context for "
|
||||
"team %ld: %s\n", kCommandName, teamID, strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
// load the team's images and their symbols
|
||||
error = _LoadSymbols(lookupContext, ID());
|
||||
debug_delete_symbol_lookup_context(lookupContext);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// also try to load the kernel images and symbols
|
||||
if (gOptions.profile_kernel) {
|
||||
// create symbol lookup context
|
||||
error = debug_create_symbol_lookup_context(B_SYSTEM_TEAM,
|
||||
&lookupContext);
|
||||
if (error != B_OK) {
|
||||
fprintf(stderr, "%s: Failed to create symbol lookup context "
|
||||
"for the kernel team: %s\n", kCommandName, strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
// load the kernel's images and their symbols
|
||||
_LoadSymbols(lookupContext, B_SYSTEM_TEAM);
|
||||
debug_delete_symbol_lookup_context(lookupContext);
|
||||
}
|
||||
|
||||
// set team debugging flags
|
||||
int32 teamDebugFlags = B_TEAM_DEBUG_THREADS
|
||||
| B_TEAM_DEBUG_TEAM_CREATION | B_TEAM_DEBUG_IMAGES;
|
||||
@@ -230,32 +199,28 @@ Team::Exec(int32 event)
|
||||
|
||||
|
||||
status_t
|
||||
Team::AddImage(const image_info& imageInfo, team_id owner, int32 event)
|
||||
Team::AddImage(SharedImage* sharedImage, const image_info& imageInfo,
|
||||
team_id owner, int32 event)
|
||||
{
|
||||
// create symbol lookup context
|
||||
debug_symbol_lookup_context* lookupContext;
|
||||
status_t error = debug_create_symbol_lookup_context(owner, &lookupContext);
|
||||
if (error != B_OK) {
|
||||
fprintf(stderr, "%s: Failed to create symbol lookup context for "
|
||||
"team %ld: %s\n", kCommandName, owner, strerror(error));
|
||||
return error;
|
||||
}
|
||||
// create the image
|
||||
Image* image = new(std::nothrow) Image(sharedImage, imageInfo, owner,
|
||||
event);
|
||||
if (image == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
Image* image;
|
||||
error = _LoadImageSymbols(lookupContext, imageInfo, owner, event,
|
||||
&image);
|
||||
debug_delete_symbol_lookup_context(lookupContext);
|
||||
if (!fImages.AddItem(image)) {
|
||||
delete image;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
// Although we generally synchronize the threads' images lazily, we have
|
||||
// to add new images at least, since otherwise images could be added
|
||||
// and removed again, and the hits inbetween could never be matched.
|
||||
if (error == B_OK) {
|
||||
ThreadList::Iterator it = fThreads.GetIterator();
|
||||
while (Thread* thread = it.Next())
|
||||
thread->AddImage(image);
|
||||
}
|
||||
ThreadList::Iterator it = fThreads.GetIterator();
|
||||
while (Thread* thread = it.Next())
|
||||
thread->AddImage(image);
|
||||
|
||||
return error;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -285,54 +250,6 @@ Team::FindImage(image_id id) const
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Team::_LoadSymbols(debug_symbol_lookup_context* lookupContext,
|
||||
team_id owner)
|
||||
{
|
||||
// iterate through the team's images and collect the symbols
|
||||
image_info imageInfo;
|
||||
int32 cookie = 0;
|
||||
while (get_next_image_info(owner, &cookie, &imageInfo) == B_OK) {
|
||||
status_t error = _LoadImageSymbols(lookupContext, imageInfo,
|
||||
owner, 0);
|
||||
if (error == B_NO_MEMORY)
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Team::_LoadImageSymbols(debug_symbol_lookup_context* lookupContext,
|
||||
const image_info& imageInfo, team_id owner, int32 event, Image** _image)
|
||||
{
|
||||
Image* image = new(std::nothrow) Image(imageInfo, owner, event);
|
||||
if (image == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = image->LoadSymbols(lookupContext);
|
||||
if (error != B_OK) {
|
||||
TRACE("Failed to load symbols of image %ld: %s\n", image->ID(),
|
||||
strerror(error));
|
||||
delete image;
|
||||
return error;
|
||||
}
|
||||
|
||||
TRACE("image %ld: loaded %ld symbols\n", image->ID(), image->SymbolCount());
|
||||
|
||||
if (!fImages.AddItem(image)) {
|
||||
delete image;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (_image != NULL)
|
||||
*_image = image;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::_RemoveImage(int32 index, int32 event)
|
||||
{
|
||||
|
||||
@@ -28,8 +28,9 @@ public:
|
||||
|
||||
void Exec(int32 event);
|
||||
|
||||
status_t AddImage(const image_info& imageInfo,
|
||||
team_id owner, int32 event);
|
||||
status_t AddImage(SharedImage* sharedImage,
|
||||
const image_info& imageInfo, team_id owner,
|
||||
int32 event);
|
||||
status_t RemoveImage(image_id imageID, int32 event);
|
||||
|
||||
inline const BObjectList<Image>& Images() const;
|
||||
@@ -38,13 +39,6 @@ public:
|
||||
inline team_id ID() const;
|
||||
|
||||
private:
|
||||
status_t _LoadSymbols(
|
||||
debug_symbol_lookup_context* lookupContext,
|
||||
team_id owner);
|
||||
status_t _LoadImageSymbols(
|
||||
debug_symbol_lookup_context* lookupContext,
|
||||
const image_info& imageInfo, team_id owner,
|
||||
int32 event, Image** _image = NULL);
|
||||
void _RemoveImage(int32 index, int32 event);
|
||||
|
||||
bool _SynchronousProfiling() const
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <new>
|
||||
#include <string>
|
||||
|
||||
#include <debugger.h>
|
||||
#include <OS.h>
|
||||
@@ -20,6 +22,7 @@
|
||||
#include <syscalls.h>
|
||||
#include <system_profiler_defs.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <debug_support.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Referenceable.h>
|
||||
@@ -98,6 +101,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
~ThreadManager()
|
||||
{
|
||||
// release image references
|
||||
for (ImageMap::iterator it = fImages.begin(); it != fImages.end(); ++it)
|
||||
it->second->RemoveReference();
|
||||
}
|
||||
|
||||
status_t AddTeam(team_id teamID, Team** _team = NULL)
|
||||
{
|
||||
return _AddTeam(teamID, NULL, _team);
|
||||
@@ -186,16 +196,24 @@ public:
|
||||
|
||||
status_t AddImage(team_id teamID, const image_info& imageInfo, int32 event)
|
||||
{
|
||||
// get a shared image
|
||||
SharedImage* sharedImage;
|
||||
status_t error = _GetSharedImage(teamID, imageInfo, &sharedImage);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
if (teamID == B_SYSTEM_TEAM) {
|
||||
// a kernel image -- add it to all teams
|
||||
int32 count = fTeams.CountItems();
|
||||
for (int32 i = 0; i < count; i++)
|
||||
fTeams.ItemAt(i)->AddImage(imageInfo, teamID, event);
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
fTeams.ItemAt(i)->AddImage(sharedImage, imageInfo, teamID,
|
||||
event);
|
||||
}
|
||||
}
|
||||
|
||||
// a userland team image -- add it to that image
|
||||
if (Team* team = FindTeam(teamID))
|
||||
return team->AddImage(imageInfo, teamID, event);
|
||||
return team->AddImage(sharedImage, imageInfo, teamID, event);
|
||||
|
||||
return B_BAD_TEAM_ID;
|
||||
}
|
||||
@@ -227,7 +245,7 @@ private:
|
||||
|
||||
status_t error = addedInfo != NULL
|
||||
? team->Init(addedInfo)
|
||||
: team->Init(teamID, fDebuggerPort);
|
||||
: _InitDebuggedTeam(team, teamID);
|
||||
if (error != B_OK) {
|
||||
delete team;
|
||||
return error;
|
||||
@@ -241,6 +259,43 @@ private:
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t _InitDebuggedTeam(Team* team, team_id teamID)
|
||||
{
|
||||
// init the team
|
||||
status_t error = team->Init(teamID, fDebuggerPort);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// add the team's images
|
||||
error = _LoadTeamImages(team, teamID);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// add the kernel images
|
||||
return _LoadTeamImages(team, B_SYSTEM_TEAM);
|
||||
}
|
||||
|
||||
status_t _LoadTeamImages(Team* team, team_id teamID)
|
||||
{
|
||||
// iterate through the team's images and collect the symbols
|
||||
image_info imageInfo;
|
||||
int32 cookie = 0;
|
||||
while (get_next_image_info(teamID, &cookie, &imageInfo) == B_OK) {
|
||||
// get a shared image
|
||||
SharedImage* sharedImage;
|
||||
status_t error = _GetSharedImage(teamID, imageInfo, &sharedImage);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// add the image to the team
|
||||
error = team->AddImage(sharedImage, imageInfo, teamID, 0);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t _CreateThreadProfileResult(Thread* thread)
|
||||
{
|
||||
ThreadProfileResult* profileResult;
|
||||
@@ -264,9 +319,47 @@ private:
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t _GetSharedImage(team_id teamID, const image_info& imageInfo,
|
||||
SharedImage** _sharedImage)
|
||||
{
|
||||
// check whether the image has already been loaded
|
||||
ImageMap::iterator it = fImages.find(imageInfo.name);
|
||||
if (it != fImages.end()) {
|
||||
*_sharedImage = it->second;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// create the shared image
|
||||
SharedImage* sharedImage = new(std::nothrow) SharedImage;
|
||||
if (sharedImage == NULL)
|
||||
return B_NO_MEMORY;
|
||||
ObjectDeleter<SharedImage> imageDeleter(sharedImage);
|
||||
|
||||
// load the symbols
|
||||
status_t error = teamID == B_SYSTEM_TEAM
|
||||
? sharedImage->Init(teamID, imageInfo.id)
|
||||
: sharedImage->Init(imageInfo.name);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
try {
|
||||
fImages[sharedImage->Name()] = sharedImage;
|
||||
} catch (std::bad_alloc) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
imageDeleter.Detach();
|
||||
*_sharedImage = sharedImage;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::map<string, SharedImage*> ImageMap;
|
||||
|
||||
private:
|
||||
BObjectList<Team> fTeams;
|
||||
BObjectList<Thread> fThreads;
|
||||
ImageMap fImages;
|
||||
port_id fDebuggerPort;
|
||||
};
|
||||
|
||||
@@ -433,7 +526,8 @@ profile_all()
|
||||
// create and area for the sample buffer
|
||||
system_profiler_buffer_header* bufferHeader;
|
||||
area_id area = create_area("profiling buffer", (void**)&bufferHeader,
|
||||
B_ANY_ADDRESS, PROFILE_ALL_SAMPLE_AREA_SIZE, B_NO_LOCK, B_READ_AREA);
|
||||
B_ANY_ADDRESS, PROFILE_ALL_SAMPLE_AREA_SIZE, B_NO_LOCK,
|
||||
B_READ_AREA | B_WRITE_AREA);
|
||||
if (area < 0) {
|
||||
fprintf(stderr, "%s: Failed to create sample area: %s\n", kCommandName,
|
||||
strerror(area));
|
||||
|
||||
Reference in New Issue
Block a user