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:
$(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
$(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
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/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
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 \
include/malloc.h include/timer.h include/dynamic.h include/console.h \
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
# 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/vmvoidtype.cpp \
../../Electronics/Electronics/Conductance/assembly.cpp \
../../Electronics/Electronics/Conductance/opcodes.cpp \
../../Electronics/Electronics/Conductance/virtualmachine.cpp \
../../Electronics/Electronics/Conductance/vmtype.cpp \
../../Electronics/Electronics/Conductance/vmvalue.cpp \
@ -63,7 +62,6 @@ OBJECTS = compoundtype.o \
vmprimitivetype.o \
vmvoidtype.o \
assembly.o \
opcodes.o \
virtualmachine.o \
vmtype.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/vmvoidtype.cpp \
../../Electronics/Electronics/Conductance/assembly.cpp \
../../Electronics/Electronics/Conductance/opcodes.cpp \
../../Electronics/Electronics/Conductance/virtualmachine.cpp \
../../Electronics/Electronics/Conductance/vmtype.cpp \
../../Electronics/Electronics/Conductance/vmvalue.cpp \
@ -693,20 +690,6 @@ assembly.o: ../../Electronics/Electronics/Conductance/assembly.cpp ../../Electro
../../Electronics/Electronics/Tools/binaryreader.hpp
$(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 \
/home/felix/projects/trainOS/include/varargs.h \
/home/felix/projects/trainOS/include/config.h \

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -75,21 +75,13 @@ extern "C" void cpp_init()
typedef void (*destructor)();
/*
// Im Linkerskript definiert
extern "C" destructor start_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()
{
initialiseConstructors();
for (destructor* i = &start_dtors; i != &end_dtors;++i)
(*i)();
}

View file

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

View file

@ -10,6 +10,8 @@
static const uint32_t magic = 0xDEADBEEF;
#define STACKDEPTH 8
typedef struct List
{
#if defined(USE_MAGIC_SECURED_MALLOC)
@ -21,6 +23,7 @@ typedef struct List
#if defined(ENABLE_MALLOC_MONITORING)
const char *allocationFile;
int allocationLine;
void *stacktrace[STACKDEPTH];
#endif
} List;
@ -77,6 +80,16 @@ void malloc_print_list(int freeList)
list->used ? list->allocationLine : 0,
list->used,
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",
list,
@ -191,6 +204,14 @@ void *malloc(size_t len)
newl->next = cursor->next;
#if defined(USE_MAGIC_SECURED_MALLOC)
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
cursor->next = newl;

View file

@ -55,35 +55,6 @@ ExceptionCode printArguments(VMValue &, const VMArray &args)
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 {
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()
{
// intr_set_handler(0x20, vm_handle_interrupt);
intr_set_handler(0x21, vm_handle_interrupt);
VirtualMachine machine;
machine.type("CPUSTATE") = csl::CpuStateType;
machine.import("print") = printArguments;
machine.import("inb") = csl::inb;
machine.import("outb") = csl::outb;
{
VirtualMachine machine;
machine.type("CPUSTATE") = csl::CpuStateType;
machine.import("print") = printArguments;
machine.import("shutdown") = shutdown;
machine.import("toInt8") = csl::toInt8;
machine.import("toInt16") = csl::toInt16;
machine.import("toInt32") = csl::toInt32;
machine.import("toUInt8") = csl::toUInt8;
machine.import("toUInt16") = csl::toUInt16;
machine.import("toUInt32") = csl::toUInt32;
machine.import("inb") = csl::inb;
machine.import("outb") = csl::outb;
Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size);
if(assembly == nullptr) {
kprintf("failed to load assembly :(\n");
return;
}
machine.import("toInt8") = csl::toInt8;
machine.import("toInt16") = csl::toInt16;
machine.import("toInt32") = csl::toInt32;
machine.import("toUInt8") = csl::toUInt8;
machine.import("toUInt16") = csl::toUInt16;
machine.import("toUInt32") = csl::toUInt32;
Process *irqService = machine.createProcess(assembly, true);
if(irqService == nullptr) {
kprintf("Failed to create process.\n");
return;
}
Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size);
if(assembly == nullptr) {
kprintf("failed to load assembly :(\n");
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())
{
// check for IRQ requests
do
{
// atomic checking for existing IRQ item
irq_disable();
bool hasItem = (irqFiFo.read < irqFiFo.write);
irq_enable();
bool osIsFailed = false;
if(hasItem == false) {
break; // we don't have anything to read
}
while((shutdownRequested == false) && machine.step())
{
// 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);
thread->start({
VMValue::Int32(cpu->intr),
csl::createCpuState(cpu)
});
CpuState *cpu = &irqFiFo.items[irqFiFo.read];
irqFiFo.read += 1;
/*
Thread *thread = irqService->createThread(irqRoutine);
thread->start({
VMValue::Int32(cpu->intr),
csl::createCpuState(cpu)
});
thread->release();
// */
irqFiFo.read += 1;
irq_disable();
// When fifo is emptied, reset list pointers
if(irqFiFo.read == irqFiFo.write) {
irqFiFo.read = 0;
irqFiFo.write = 0;
}
irq_enable();
} while(true);
irq_disable();
// When fifo is emptied, reset list pointers
if(irqFiFo.read == irqFiFo.write) {
irqFiFo.read = 0;
irqFiFo.write = 0;
}
irq_enable();
} while(true);
if(mainThread->isRunning() == false) {
if(osIsFailed == false) {
osIsFailed = true;
if(mainThread->isRunning() == false) {
if(osIsFailed == false) {
osIsFailed = true;
kprintf("OS failed with: %s\n", execptionName(mainThread->exception()));
}
}
}
mainThread->release();
kprintf("OS failed with: %s\n", execptionName(mainThread->exception()));
irqService->release();
irqService = nullptr;
shutdownRequested = true;
}
}
}
mainThread->release();
mainThread = nullptr;
assembly->release();
irqService->release();
irqService = nullptr;
assembly->release();
assembly = nullptr;
}
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