Adds traceback tool. Fixes lots of memory leaks.

This commit is contained in:
Felix Queissner 2015-10-12 14:32:38 +02:00
parent 125ffa4333
commit 02d1cf7bd6
12 changed files with 146 additions and 127 deletions

View file

@ -30,8 +30,8 @@ all: kernel
clean: clean:
$(RM) obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o $(RM) obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o
kernel: obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/opcodes.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o kernel: obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o
$(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/opcodes.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o $(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o
# src/console.c # src/console.c
obj/console.o: src/console.c include/console.h include/kstdlib.h \ obj/console.o: src/console.c include/console.h include/kstdlib.h \
@ -99,7 +99,7 @@ obj/cpp-test.o: src/cpp-test.cpp include/console.h include/ker/string.hpp \
obj/vm.o: src/vm.cpp include/kstdlib.h include/varargs.h include/config.h \ obj/vm.o: src/vm.cpp include/kstdlib.h include/varargs.h include/config.h \
include/malloc.h include/timer.h include/dynamic.h include/console.h \ include/malloc.h include/timer.h include/dynamic.h include/console.h \
include/interrupts.h include/cpustate.h src/../csl/cpustatetype.hpp \ include/interrupts.h include/cpustate.h src/../csl/cpustatetype.hpp \
src/../csl/io.hpp src/../csl/casts.hpp include/io.h src/../csl/io.hpp src/../csl/casts.hpp
$(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp $(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp
# csl/casts.cpp # csl/casts.cpp

View file

@ -50,7 +50,6 @@ SOURCES = ../../Electronics/Electronics/Conductance/types/compoundtype.cpp
../../Electronics/Electronics/Conductance/types/vmprimitivetype.cpp \ ../../Electronics/Electronics/Conductance/types/vmprimitivetype.cpp \
../../Electronics/Electronics/Conductance/types/vmvoidtype.cpp \ ../../Electronics/Electronics/Conductance/types/vmvoidtype.cpp \
../../Electronics/Electronics/Conductance/assembly.cpp \ ../../Electronics/Electronics/Conductance/assembly.cpp \
../../Electronics/Electronics/Conductance/opcodes.cpp \
../../Electronics/Electronics/Conductance/virtualmachine.cpp \ ../../Electronics/Electronics/Conductance/virtualmachine.cpp \
../../Electronics/Electronics/Conductance/vmtype.cpp \ ../../Electronics/Electronics/Conductance/vmtype.cpp \
../../Electronics/Electronics/Conductance/vmvalue.cpp \ ../../Electronics/Electronics/Conductance/vmvalue.cpp \
@ -63,7 +62,6 @@ OBJECTS = compoundtype.o \
vmprimitivetype.o \ vmprimitivetype.o \
vmvoidtype.o \ vmvoidtype.o \
assembly.o \ assembly.o \
opcodes.o \
virtualmachine.o \ virtualmachine.o \
vmtype.o \ vmtype.o \
vmvalue.o \ vmvalue.o \
@ -232,7 +230,6 @@ DIST = /usr/lib/qt/mkspecs/features/spec_pre.prf \
../../Electronics/Electronics/Conductance/types/vmprimitivetype.cpp \ ../../Electronics/Electronics/Conductance/types/vmprimitivetype.cpp \
../../Electronics/Electronics/Conductance/types/vmvoidtype.cpp \ ../../Electronics/Electronics/Conductance/types/vmvoidtype.cpp \
../../Electronics/Electronics/Conductance/assembly.cpp \ ../../Electronics/Electronics/Conductance/assembly.cpp \
../../Electronics/Electronics/Conductance/opcodes.cpp \
../../Electronics/Electronics/Conductance/virtualmachine.cpp \ ../../Electronics/Electronics/Conductance/virtualmachine.cpp \
../../Electronics/Electronics/Conductance/vmtype.cpp \ ../../Electronics/Electronics/Conductance/vmtype.cpp \
../../Electronics/Electronics/Conductance/vmvalue.cpp \ ../../Electronics/Electronics/Conductance/vmvalue.cpp \
@ -693,20 +690,6 @@ assembly.o: ../../Electronics/Electronics/Conductance/assembly.cpp ../../Electro
../../Electronics/Electronics/Tools/binaryreader.hpp ../../Electronics/Electronics/Tools/binaryreader.hpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o assembly.o ../../Electronics/Electronics/Conductance/assembly.cpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o assembly.o ../../Electronics/Electronics/Conductance/assembly.cpp
opcodes.o: ../../Electronics/Electronics/Conductance/opcodes.cpp ../../Electronics/Electronics/Conductance/opcodes.hpp \
/home/felix/projects/trainOS/include/ker/dictionary.hpp \
/home/felix/projects/trainOS/include/kernel.h \
/home/felix/projects/trainOS/include/ker/pair.hpp \
/home/felix/projects/trainOS/include/ker/vector.hpp \
/home/felix/projects/trainOS/include/kstdlib.h \
/home/felix/projects/trainOS/include/varargs.h \
/home/felix/projects/trainOS/include/config.h \
/home/felix/projects/trainOS/include/malloc.h \
/home/felix/projects/trainOS/include/ker/new.hpp \
/home/felix/projects/trainOS/include/ker/string.hpp \
../../Electronics/Electronics/Tools/fixedstring.hpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o opcodes.o ../../Electronics/Electronics/Conductance/opcodes.cpp
virtualmachine.o: ../../Electronics/Electronics/Conductance/virtualmachine.cpp /home/felix/projects/trainOS/include/kstdlib.h \ virtualmachine.o: ../../Electronics/Electronics/Conductance/virtualmachine.cpp /home/felix/projects/trainOS/include/kstdlib.h \
/home/felix/projects/trainOS/include/varargs.h \ /home/felix/projects/trainOS/include/varargs.h \
/home/felix/projects/trainOS/include/config.h \ /home/felix/projects/trainOS/include/config.h \

View file

@ -4,6 +4,8 @@
#include <console.h> #include <console.h>
VMText text("hello!");
static CompoundType type { static CompoundType type {
"CPUSTATE", "CPUSTATE",
{ {

View file

@ -94,7 +94,7 @@ namespace ker
~String() ~String()
{ {
if(this->mText != nullptr) { if(this->mText != nullptr) {
free(this->mText); free(this->mText);
} }
} }

View file

@ -27,10 +27,14 @@ SECTIONS
} }
.data ALIGN(4096) : { .data ALIGN(4096) : {
start_ctors = .; start_ctors = .;
KEEP(*( .init_array )); KEEP(*( .init_array ));
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* ))); KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
end_ctors = .; end_ctors = .;
start_dtors = .;
*(.dtors)
end_dtors = .;
*(.data) *(.data)
} }
.rodata ALIGN(4096) : { .rodata ALIGN(4096) : {

View file

@ -1,5 +1,7 @@
NATIVE print(...); NATIVE print(...);
NATIVE shutdown();
NATIVE outb(port : UINT16, value : UINT8); NATIVE outb(port : UINT16, value : UINT8);
NATIVE inb(port : UINT16) → UINT8; NATIVE inb(port : UINT16) → UINT8;
@ -61,6 +63,9 @@ BEGIN
IF id = 33 THEN IF id = 33 THEN
inb(96u16) → scancode; inb(96u16) → scancode;
print("keypress: ", scancode, "\n"); print("keypress: ", scancode, "\n");
IF scancode = 1u8 THEN
shutdown();
END
END END
END END

View file

@ -1,9 +1,10 @@
; ============================================= ; =============================================
; compiled with Copper 1.0 ; compiled with Copper 1.0
; 2015-10-11 12:46:04 ; 2015-10-11 17:43:16
; ============================================= ; =============================================
; native method: print(…) ; native method: print(…)
; native method: shutdown(…)
; native method: outb(…) ; native method: outb(…)
; native method: inb(…) → UINT8 ; native method: inb(…) → UINT8
; native method: toInt8(…) → INT8 ; native method: toInt8(…) → INT8
@ -26,6 +27,7 @@
; 0, sendCommand ; 0, sendCommand
sendCommand: sendCommand:
pushnil ; return value pushnil ; return value
@ -128,6 +130,14 @@ irq:
pusht "keypress: " pusht "keypress: "
calln print 3 calln print 3
load 1
pushi 3 1
op2 5
jmp_if_not _private_7
calln shutdown 0
_private_7:
_private_6: _private_6:
ret ret

View file

@ -75,21 +75,13 @@ extern "C" void cpp_init()
typedef void (*destructor)(); typedef void (*destructor)();
/*
// Im Linkerskript definiert // Im Linkerskript definiert
extern "C" destructor start_dtors; extern "C" destructor start_dtors;
extern "C" destructor end_dtors; extern "C" destructor end_dtors;
extern "C" void initialiseDestructors();
// Ruft die Konstruktoren für globale/statische Objekte auf
void initialiseDestructors()
{
for (destructor* i = &start_dtors;i != &end_dtors;++i)
(*i)();
}
*/
extern "C" void cpp_exit() extern "C" void cpp_exit()
{ {
initialiseConstructors(); for (destructor* i = &start_dtors; i != &end_dtors;++i)
(*i)();
} }

View file

@ -210,7 +210,7 @@ void init(const MultibootStructure *mbHeader)
kputs("\n"); kputs("\n");
vm_start(); vm_start();
irq_disable(); irq_disable();

View file

@ -10,6 +10,8 @@
static const uint32_t magic = 0xDEADBEEF; static const uint32_t magic = 0xDEADBEEF;
#define STACKDEPTH 8
typedef struct List typedef struct List
{ {
#if defined(USE_MAGIC_SECURED_MALLOC) #if defined(USE_MAGIC_SECURED_MALLOC)
@ -21,6 +23,7 @@ typedef struct List
#if defined(ENABLE_MALLOC_MONITORING) #if defined(ENABLE_MALLOC_MONITORING)
const char *allocationFile; const char *allocationFile;
int allocationLine; int allocationLine;
void *stacktrace[STACKDEPTH];
#endif #endif
} List; } List;
@ -77,6 +80,16 @@ void malloc_print_list(int freeList)
list->used ? list->allocationLine : 0, list->used ? list->allocationLine : 0,
list->used, list->used,
list->length); list->length);
serial_printf(SERIAL_COM1," ");
for(int i = 0; i < STACKDEPTH; i++) {
serial_printf(SERIAL_COM1, "%x ", list->stacktrace[i]);
}
serial_printf(SERIAL_COM1,"\n");
serial_printf(SERIAL_COM1,"[");
serial_write(SERIAL_COM1, (char*)list + sizeof(List), list->length);
serial_printf(SERIAL_COM1,"]");
/* /*
kprintf("[%x -> %x] (%s:%d) %d %d\n", kprintf("[%x -> %x] (%s:%d) %d %d\n",
list, list,
@ -191,6 +204,14 @@ void *malloc(size_t len)
newl->next = cursor->next; newl->next = cursor->next;
#if defined(USE_MAGIC_SECURED_MALLOC) #if defined(USE_MAGIC_SECURED_MALLOC)
newl->hash = hash(newl); newl->hash = hash(newl);
newl->stacktrace[0] = __builtin_return_address(1);
newl->stacktrace[1] = __builtin_return_address(2);
newl->stacktrace[2] = __builtin_return_address(3);
newl->stacktrace[3] = __builtin_return_address(4);
newl->stacktrace[4] = __builtin_return_address(5);
newl->stacktrace[5] = __builtin_return_address(6);
newl->stacktrace[6] = __builtin_return_address(7);
newl->stacktrace[7] = __builtin_return_address(8);
#endif #endif
cursor->next = newl; cursor->next = newl;

View file

@ -55,35 +55,6 @@ ExceptionCode printArguments(VMValue &, const VMArray &args)
return ExceptionCode::None; return ExceptionCode::None;
} }
#include <io.h>
ExceptionCode vmOutB(VMValue &, const VMArray &args)
{
if(args.length() != 2)
return ExceptionCode::InvalidArgument;
if(args[0].type() != VMType::UInt16)
return ExceptionCode::InvalidArgument;
if(args[1].type() != VMType::UInt8)
return ExceptionCode::InvalidArgument;
outb(args[0].value<VMUInt16>(), args[1].value<VMUInt8>());
return ExceptionCode::None;
}
ExceptionCode vmInB(VMValue &result, const VMArray &args)
{
if(args.length() != 1)
return ExceptionCode::InvalidArgument;
if(args[0].type() != VMType::UInt16)
return ExceptionCode::InvalidArgument;
result = VMValue::UInt8(
inb(args[0].value<VMUInt16>()));
return ExceptionCode::None;
}
struct dtortest { struct dtortest {
void *mem; void *mem;
@ -146,90 +117,111 @@ const char *execptionName(ExceptionCode ex)
} }
} }
static bool shutdownRequested = false;
ExceptionCode shutdown(VMValue &, const VMArray &)
{
shutdownRequested = true;
return ExceptionCode::None;
}
int ReferenceCounted::counter = 0;
extern "C" void vm_start() extern "C" void vm_start()
{ {
// intr_set_handler(0x20, vm_handle_interrupt); // intr_set_handler(0x20, vm_handle_interrupt);
intr_set_handler(0x21, vm_handle_interrupt); intr_set_handler(0x21, vm_handle_interrupt);
VirtualMachine machine; {
machine.type("CPUSTATE") = csl::CpuStateType; VirtualMachine machine;
machine.import("print") = printArguments; machine.type("CPUSTATE") = csl::CpuStateType;
machine.import("inb") = csl::inb; machine.import("print") = printArguments;
machine.import("outb") = csl::outb; machine.import("shutdown") = shutdown;
machine.import("toInt8") = csl::toInt8; machine.import("inb") = csl::inb;
machine.import("toInt16") = csl::toInt16; machine.import("outb") = csl::outb;
machine.import("toInt32") = csl::toInt32;
machine.import("toUInt8") = csl::toUInt8;
machine.import("toUInt16") = csl::toUInt16;
machine.import("toUInt32") = csl::toUInt32;
Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size); machine.import("toInt8") = csl::toInt8;
if(assembly == nullptr) { machine.import("toInt16") = csl::toInt16;
kprintf("failed to load assembly :(\n"); machine.import("toInt32") = csl::toInt32;
return; machine.import("toUInt8") = csl::toUInt8;
} machine.import("toUInt16") = csl::toUInt16;
machine.import("toUInt32") = csl::toUInt32;
Process *irqService = machine.createProcess(assembly, true); Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size);
if(irqService == nullptr) { if(assembly == nullptr) {
kprintf("Failed to create process.\n"); kprintf("failed to load assembly :(\n");
return; return;
} }
Thread *mainThread = irqService->mainThread(); Process *irqService = machine.createProcess(assembly, true);
if(irqService == nullptr) {
kprintf("Failed to create process.\n");
return;
}
uint32_t irqRoutine = irqService->assembly()->exports()["irq"]; Thread *mainThread = irqService->mainThread();
bool osIsFailed = false; uint32_t irqRoutine = irqService->assembly()->exports()["irq"];
while(machine.step()) bool osIsFailed = false;
{
// check for IRQ requests
do
{
// atomic checking for existing IRQ item
irq_disable();
bool hasItem = (irqFiFo.read < irqFiFo.write);
irq_enable();
if(hasItem == false) { while((shutdownRequested == false) && machine.step())
break; // we don't have anything to read {
} // check for IRQ requests
do
{
// atomic checking for existing IRQ item
irq_disable();
bool hasItem = (irqFiFo.read < irqFiFo.write);
irq_enable();
CpuState *cpu = &irqFiFo.items[irqFiFo.read]; if(hasItem == false) {
break; // we don't have anything to read
}
auto *thread = irqService->createThread(irqRoutine); CpuState *cpu = &irqFiFo.items[irqFiFo.read];
thread->start({
VMValue::Int32(cpu->intr),
csl::createCpuState(cpu)
});
irqFiFo.read += 1; /*
Thread *thread = irqService->createThread(irqRoutine);
thread->start({
VMValue::Int32(cpu->intr),
csl::createCpuState(cpu)
});
thread->release();
// */
irqFiFo.read += 1;
irq_disable(); irq_disable();
// When fifo is emptied, reset list pointers // When fifo is emptied, reset list pointers
if(irqFiFo.read == irqFiFo.write) { if(irqFiFo.read == irqFiFo.write) {
irqFiFo.read = 0; irqFiFo.read = 0;
irqFiFo.write = 0; irqFiFo.write = 0;
} }
irq_enable(); irq_enable();
} while(true); } while(true);
if(mainThread->isRunning() == false) { if(mainThread->isRunning() == false) {
if(osIsFailed == false) { if(osIsFailed == false) {
osIsFailed = true; osIsFailed = true;
kprintf("OS failed with: %s\n", execptionName(mainThread->exception())); kprintf("OS failed with: %s\n", execptionName(mainThread->exception()));
}
}
}
mainThread->release();
irqService->release(); shutdownRequested = true;
irqService = nullptr; }
}
}
mainThread->release();
mainThread = nullptr;
assembly->release(); irqService->release();
irqService = nullptr;
assembly->release();
assembly = nullptr;
}
kprintf("\n"); kprintf("\n");
kprintf("unreleased objects: %d\n", ReferenceCounted::counter);
kprintf("\n");
} }

10
traceback.lua Normal file
View file

@ -0,0 +1,10 @@
io.write("Input stacktrace from kernel:\n")
local line = io.read("*line")
for addr in line:gmatch("(%w+)") do
-- io.write(("-"):rep(80).."\n")
-- io.write("address: " .. addr .. "\n")
-- io.write(("-"):rep(80).."\n")
-- os.execute("objdump -d kernel | grep "..addr:lower().." -A 3 -B 10")
os.execute([[objdump -d kernel | grep -i ]]..addr..[[ -B 50 | grep -e ">:$" | tail -n 1 | sed -E "s|.*<(.*)>:|\1|" | c++filt]])
end