A module that hooks into the debugger to provide it with a demangle() so at least when using C++ in the kernel stack crawls are meaningful.
It does its job by using part of libsupc++, with fake malloc and friends to make sure it won't double fault. Works here, but cp-demangle must be extracted by hand from the lib, can't get the rule to work as I want, Ingo ? Maybe using it directly without malloc hack would be ok with 16KB buffer, but I'm not sure of that. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26581 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4e99b4683e
commit
8881176ff3
@ -111,6 +111,9 @@ extern bool print_debugger_command_usage(const char* command);
|
||||
|
||||
extern void _user_debug_output(const char *userString);
|
||||
|
||||
extern void debug_set_demangle_hook(const char *(*hook)(const char *));
|
||||
extern const char *debug_demangle(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -2,6 +2,7 @@ SubDir HAIKU_TOP src add-ons kernel debugger ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel debugger auto_stack_trace ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel debugger bochs ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel debugger demangle ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel debugger hangman ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel debugger invalidate_on_exit ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel debugger laplinkll ;
|
||||
|
43
src/add-ons/kernel/debugger/demangle/Jamfile
Normal file
43
src/add-ons/kernel/debugger/demangle/Jamfile
Normal file
@ -0,0 +1,43 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel debugger demangle ;
|
||||
|
||||
if $(HAIKU_GCC_VERSION[1]) >= 4 {
|
||||
|
||||
UsePrivateHeaders kernel ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src system kernel debug ] ;
|
||||
|
||||
|
||||
rule ExtractObject
|
||||
{
|
||||
SetupKernel $(2) ;
|
||||
Depends $(1) : $(2) ;
|
||||
Objects $(1) ;
|
||||
|
||||
MakeLocateDebug $(1) ;
|
||||
}
|
||||
|
||||
actions ExtractObject
|
||||
{
|
||||
#$(TARGET_AR) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ;
|
||||
pwd
|
||||
echo $(TARGET_AR) -x "$(2)" "$(1)"
|
||||
}
|
||||
|
||||
ExtractObject cp-demangle.o : $(TARGET_STATIC_LIBSUPC++) foo ;
|
||||
|
||||
KernelMergeObject demangle_module.o :
|
||||
demangle.cpp
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
|
||||
|
||||
KernelAddon <kdebug>demangle :
|
||||
demangle.cpp
|
||||
#demangle_module.o
|
||||
cp-demangle.o
|
||||
;
|
||||
|
||||
#LINKFLAGS on <kdebug>demangle = -lsupc++ ;
|
||||
|
||||
}
|
194
src/add-ons/kernel/debugger/demangle/demangle.cpp
Normal file
194
src/add-ons/kernel/debugger/demangle/demangle.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2008, François Revol, revol@free.fr
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <cxxabi.h>
|
||||
#include <debug.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DEMANGLE_BUFFER_SIZE (16*1024)
|
||||
static char sDemangleBuffer[DEMANGLE_BUFFER_SIZE];
|
||||
|
||||
extern "C" void set_debug_demangle_hook(const char *(*demangle_hook)(const char *));
|
||||
|
||||
/* gcc's __cxa_demangle calls malloc and friends...
|
||||
* we don't want to let it call the real one from inside the kernel debugger...
|
||||
* instead we just return it a static buffer.
|
||||
*/
|
||||
|
||||
void *malloc(size_t len)
|
||||
{
|
||||
if (len < DEMANGLE_BUFFER_SIZE)
|
||||
return sDemangleBuffer;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void free(void *ptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void *realloc(void * old_ptr, size_t new_size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* doesn't work, va_list sux... */
|
||||
#if 0
|
||||
class DemangleDebugOutputFilter : public DebugOutputFilter {
|
||||
public:
|
||||
DemangleDebugOutputFilter();
|
||||
virtual ~DemangleDebugOutputFilter();
|
||||
void SetChain(DebugOutputFilter *chain);
|
||||
virtual void PrintString(const char* string);
|
||||
virtual void Print(const char* format, va_list args);
|
||||
private:
|
||||
DebugOutputFilter *fChained;
|
||||
};
|
||||
|
||||
|
||||
DemangleDebugOutputFilter::DemangleDebugOutputFilter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DemangleDebugOutputFilter::~DemangleDebugOutputFilter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DemangleDebugOutputFilter::SetChain(DebugOutputFilter *chain)
|
||||
{
|
||||
fChained = chain;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DemangleDebugOutputFilter::PrintString(const char* string)
|
||||
{
|
||||
fChained->PrintString(string);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DemangleDebugOutputFilter::Print(const char* format, va_list args)
|
||||
{
|
||||
int i;
|
||||
const char *p = format;
|
||||
while ((p = strchr(p, '%'))) {
|
||||
if (p[1] == '%') {
|
||||
p+=2;
|
||||
continue;
|
||||
}
|
||||
p++;
|
||||
while (*p && !isalpha(*p))
|
||||
p++;
|
||||
switch (*p) {
|
||||
case 's':
|
||||
{
|
||||
const char **ptr = &va_arg(args, char *);
|
||||
//char *symbol = va_arg(args, char *);
|
||||
char *symbol = *ptr;
|
||||
char *demangled;
|
||||
size_t length = DEMANGLE_BUFFER_SIZE;
|
||||
int status;
|
||||
|
||||
demangled = abi::__cxa_demangle(symbol, sDemangleBuffer, &length, &status);
|
||||
if (status > 0) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
case 'i':
|
||||
{
|
||||
int d;
|
||||
d = va_arg(args, int);
|
||||
break;
|
||||
}
|
||||
case 'L':
|
||||
{
|
||||
long long d;
|
||||
d = va_arg(args, long long);
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
{
|
||||
float f;
|
||||
f = va_arg(args, float);
|
||||
break;
|
||||
}
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
panic("unknown printf format\n");
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
fChained->Print(format, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *kdebug_demangle(const char *sym)
|
||||
{
|
||||
char *demangled;
|
||||
size_t length = DEMANGLE_BUFFER_SIZE;
|
||||
int status;
|
||||
|
||||
demangled = abi::__cxa_demangle(sym, sDemangleBuffer, &length, &status);
|
||||
if (status == 0)
|
||||
return demangled;
|
||||
// something bad happened
|
||||
return sym;
|
||||
}
|
||||
|
||||
static void
|
||||
exit_debugger()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
std_ops(int32 op, ...)
|
||||
{
|
||||
if (op == B_MODULE_INIT) {
|
||||
#if 0
|
||||
DebugOutputFilter *old;
|
||||
DemangleDebugOutputFilter *filter = new(std::nothrow) DemangleDebugOutputFilter;
|
||||
old = set_debug_output_filter(filter);
|
||||
filter->SetChain(old);
|
||||
#endif
|
||||
debug_set_demangle_hook(kdebug_demangle);
|
||||
|
||||
return B_OK;
|
||||
} else if (op == B_MODULE_UNINIT) {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
static struct debugger_module_info sModuleInfo = {
|
||||
{
|
||||
"debugger/demangle/v1",
|
||||
B_KEEP_LOADED,
|
||||
&std_ops
|
||||
},
|
||||
|
||||
NULL,
|
||||
exit_debugger,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *)&sModuleInfo,
|
||||
NULL
|
||||
};
|
||||
|
@ -98,6 +98,10 @@ lookup_symbol(struct thread* thread, addr_t address, addr_t *_baseAddress,
|
||||
}
|
||||
}
|
||||
|
||||
if (status == B_OK) {
|
||||
*_symbolName = debug_demangle(*_symbolName);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,8 @@ static const uint32 kMaxDebuggerModules = sizeof(sDebuggerModules)
|
||||
static char sLineBuffer[HISTORY_SIZE][LINE_BUFFER_SIZE] = { "", };
|
||||
static int32 sCurrentLine = 0;
|
||||
|
||||
static const char *(*sDemangleHook)(const char *) = NULL;
|
||||
|
||||
#define distance(a, b) ((a) < (b) ? (b) - (a) : (a) - (b))
|
||||
|
||||
|
||||
@ -1383,3 +1385,20 @@ dump_block(const char *buffer, int size, const char *prefix)
|
||||
dprintf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
debug_set_demangle_hook(const char *(*hook)(const char *))
|
||||
{
|
||||
sDemangleHook = hook;
|
||||
}
|
||||
|
||||
|
||||
extern const char *
|
||||
debug_demangle(const char *sym)
|
||||
{
|
||||
if (sDemangleHook)
|
||||
return sDemangleHook(sym);
|
||||
return sym;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user