Is C++ virtual function unavailable in kernel programming?
Posted: Mon Mar 27, 2023 9:00 am
Hello
I am currently programming with virtual functions but every time I call the virtual functions, it generates interrupt 6 (Invalid Opcode).
TextModePresenter m_TextPresenter is a class inherit from base class VideoPresenter, and it overrides pure virtual function Clear()
The assembly code when problem occurs are
I have no idea why it generates exception.
In addition, I found that sometimes it also works correctly (I modified and compiled many times). Have anyone got same problem ever?
According to the explanation about Invalid Opcode, the value of instruction pointer (rip) is 0x16 (push?)
All my source code are commited to GitHubhttps://github.com/0x1021A0/NiteProject
I have asked my linker to generate the map, the value of stack pointer is 0xFFFFFFFF801064BC (0x1DC in ConsoleImpl.o), Now it points to
I suppose there would be some misunderstanding.
---Update 20230328---
There won't be any issue if I call the virtual function in the class constructor, but every time I try to call it in the other function, it crashes. Calling the function within the constructor also not work. This one works correctly, no interrupt generated.
These two examples are NOT OK, it generates invalid opcode.
I am currently programming with virtual functions but every time I call the virtual functions, it generates interrupt 6 (Invalid Opcode).
Code: Select all
void Console::Refresh()
{
m_Init = true;
m_KeyModifiers = 0;
m_TextPresenter->Clear(); [b]<--- Here[/b]
RenderModifiers();
m_TextPresenter->Text({ 0, 2 }, '>', 15, 0);
}
Code: Select all
class VideoPresenter
{
public:
virtual void Clear() = 0;
...
}; // Video.h
class TextModePresenter : public VideoPresenter
{
private:
...
public:
virtual void Clear();
...
}; // TextModePresenter.h
void TextModePresenter::Clear()
{
for (int y = 0; y < 25; y++)
{
for (int x = 0; x < 80; x++)
{
m_TextBuffer[(y * 80) + x] = 0x00;
}
}
} // TextModePresenterImpl.cc
Code: Select all
sub $0x8, %rsp
movb $0x1,0x18(%rdi) <---Here
movb $0x0,0x8(%rdi)
In addition, I found that sometimes it also works correctly (I modified and compiled many times). Have anyone got same problem ever?
According to the explanation about Invalid Opcode, the value of instruction pointer (rip) is 0x16 (push?)
All my source code are commited to GitHubhttps://github.com/0x1021A0/NiteProject
I have asked my linker to generate the map, the value of stack pointer is 0xFFFFFFFF801064BC (0x1DC in ConsoleImpl.o), Now it points to
Code: Select all
1D7: mov (%rdi),%rax
1DA: call *(%rax)
1DC: mov %rbx,%rdi <---Here
1DF: movabs $0x0,%rax
---Update 20230328---
There won't be any issue if I call the virtual function in the class constructor, but every time I try to call it in the other function, it crashes. Calling the function within the constructor also not work.
Code: Select all
Console::Console()
: m_KeyModifiers(0),
m_TextPresenter(new Video::TextModePresenter()),
m_Buffers(new uint8_t[23 * 80]),
m_OffsetX(1),
m_OffsetY(0)
{
m_TextPresenter->Clear();
}
Code: Select all
Console::Console()
: m_KeyModifiers(0),
m_TextPresenter(new Video::TextModePresenter()),
m_Buffers(new uint8_t[23 * 80]),
m_OffsetX(1),
m_OffsetY(0)
{
Refresh();
}
void Console::Refresh()
{
m_TextPresenter->Clear();
}
Code: Select all
Console::Console()
: m_KeyModifiers(0),
m_TextPresenter(new Video::TextModePresenter()),
m_Buffers(new uint8_t[23 * 80]),
m_OffsetX(1),
m_OffsetY(0) { }
/////////////////////////////////////
(new Console())->Refresh(); <--- In other function