0xC0000005 Error happens in print function - mfc

Here's the code below.
void SignalView::OnFilePrintPreview()
{
if(RcursorPosX-LcursorPosX<=0){
AfxMessageBox(_T("Please set cursor positions.\nYou can only print out the area between left and right cursors"));
return;
}
CScrollView::OnFilePrintPreview();
}
BOOL SignalView::OnPreparePrinting(CPrintInfo* pInfo)
{
if(RcursorPosX-LcursorPosX>100*4*2)
RcursorPosX = LcursorPosX+100*4*2; //800 = 100 cursor x 4(gridX) x 2(zoomX)
pInfo->SetMinPage(1);
pInfo->SetMaxPage(1);
return DoPreparePrinting(pInfo); //<===========
}
void SignalView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
PRINTDLG* pPrintDlg = new PRINTDLG;
AfxGetApp()->GetPrinterDeviceDefaults(pPrintDlg);
DEVMODE* lpDevMode = (DEVMODE*)::GlobalLock(pPrintDlg->hDevMode);
lpDevMode->dmOrientation = DMORIENT_LANDSCAPE;
while(!pDC->ResetDC(lpDevMode));
::GlobalUnlock(pPrintDlg->hDevMode);
delete pPrintDlg;
}
I'm trying to use print functions. But I remade it because I deleted it and made a new class again which is derived from CScrollView, so I don't use the original view that was made from the beginning.
And now, I achieved what I want but the problem is that an error happens when I try to call and close print event OnFilePrintPreview() around 30-40 times, then it would shut down with an error message 0xC0000005.
And it happens from the function DoPreparePrinting(pInfo), and then it goes to COMMDLG_AFXCTXFUNC(BOOL ,PrintDlgW,(LPPRINTDLGW unnamed1),(unnamed1)) in afxcomctl32.inl file and then it provokes an error message.
Why does this problem happen? And does the code seem to go the right direction?
P.S.
The error happens this part in disassembly mode.
COMMDLG_AFXCTXFUNC(BOOL ,PrintDlgW,(LPPRINTDLGW unnamed1),(unnamed1))
7824CD80 mov edi,edi
7824CD82 push ebp
7824CD83 mov ebp,esp
7824CD85 mov eax,dword ptr [unnamed1]
7824CD88 push eax
7824CD89 call AfxGetModuleState (780F3320h)
7824CD8E mov ecx,dword ptr [eax+94h]
7824CD94 mov ecx,dword ptr [ecx+4]
7824CD97 call CCommDlgWrapper::_PrintDlgW (7824CDB0h)
7824CD9C pop ebp //<======= it's stopped at this point.
7824CD9D ret 4

while(!pDC->ResetDC(lpDevMode));
::GlobalUnlock(pPrintDlg->hDevMode);
This looks like trouble. If loop condition is true the first time and the second time, then there is no guarantee that it will eventually stop.
The following may not be the cause of your error, but you should try to follow these procedures in general.
When declaring new variables set them to zero, so all structure members are zero:
PRINTDLG* pPrintDlg = new PRINTDLG;
memset(pPrintDlg, 0, sizeof(pPrintDlg));
Some structures require to know the size. This has to do with Microsoft version control:
pPrintDlg->lStructSize = sizeof(PRINTDLG);
In this case you don't need to use new to allocate pPrintDlg (but it won't cause problems if you do)
You should be able to intercept the request for printing (before printer device context is created) and change to landscape mode, so Print dialog box is shown in landscape mode.
void SignalView::OnFilePrint()
{
PRINTDLG printDlg = { 0 };
printDlg.lStructSize = sizeof(PRINTDLG);
if (AfxGetApp()->GetPrinterDeviceDefaults(&printDlg))
{
if (printDlg.hDevMode)
{
DEVMODE *dm = (DEVMODE*)::GlobalLock(printDlg.hDevMode);
if (dm)
{
dm->dmFields |= DM_ORIENTATION;
dm->dmOrientation = DMORIENT_LANDSCAPE;
::GlobalUnlock(printDlg.hDevMode);
}
}
}
CScrollView::OnFilePrint();
}
Message map should look like this:
BEGIN_MESSAGE_MAP(SignalView, CScrollView)
ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, OnFilePrint)
//**************************************************
ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
//**************************************************
END_MESSAGE_MAP()
User can change the print mode back to portrait in print dialog box. You can repeat the same code in OnBeginPrinting if you want to force landscape.

Related

opengl32.dll hangs on SetPixelFormat How to replace or hook a custom function

I have a scenario where in some cases when opengl32.setPixelFormat is called it then call _wglDescribePixelFormat ( which is exported function ) which then calls further in the call stack ComputeBitsFromMasks and finally _MaskToBitsAndShift.
The _MaskToBitsAndShift function remains in the loop and never finishes, causing hanging the whole app. Callstack is
opengl32.dll!_MaskToBitsAndShift#12
opengl32.dll!ComputeBitsFromMasks
opengl32.dll!___wglGetBitfieldColorFormat#16
opengl32.dll!_InternalDescribePixelFormat#40
opengl32.dll!_wglDescribePixelFormat#16
opengl32.dll!_wglSetPixelFormat#12
gdi32full.dll!_SetPixelFormat#12
Unmanaged.dll!CGLContext::CreateOffScreenContext
Unmanaged.dll!Shared::Generate3DImages
Decoding the _MaskToBitsAndShift method from asm to c becomes like this.
Asm code
opengl32!MaskToBitsAndShift:
6da7d6f2 8bff mov edi,edi
6da7d6f4 55 push ebp
6da7d6f5 8bec mov ebp,esp
6da7d6f7 56 push esi
6da7d6f8 8b7508 mov esi,dword ptr [ebp+8]
6da7d6fb 33c0 xor eax,eax
6da7d6fd 40 inc eax – initialize eax to 1, used to find highest set bit in the mask
6da7d6fe c60200 mov byte ptr [edx],0
6da7d701 c60600 mov byte ptr [esi],0
6da7d704 84c8 test al,cl
6da7d706 7508 jne opengl32!MaskToBitsAndShift+0x1e (6da7d710)
6da7d708 03c0 add eax,eax – shifts eax (the bit) left
6da7d70a fe06 inc byte ptr [esi] – increases shift count
6da7d70c 85c1 test ecx,eax – ecx is the mask, first param to this function apparently
– and this is the problem. if ecx or mask is 0, test ecx,eax will never set the flag for je to fail, hence infinite loop
6da7d70e 74f8 je opengl32!MaskToBitsAndShift+0x16 (6da7d708)
6da7d710 5e pop esi
6da7d711 eb04 jmp opengl32!MaskToBitsAndShift+0x25 (6da7d717)
6da7d713 03c0 add eax,eax
6da7d715 fe02 inc byte ptr [edx]
6da7d717 85c1 test ecx,eax
6da7d719 75f8 jne opengl32!MaskToBitsAndShift+0x21 (6da7d713)
6da7d71b 5d pop ebp
6da7d71c c20400 ret 4
Equivalant c++ code
void stdcall MaskToBitsAndShift(DWORD mask, BYTE* shiftCount, BYTE* bitCount)
{
// literal translation from asm; could be safer using bittest intrinsics or counted bits but no big deal
DWORD bit = 1;
*shiftCount = 0;
*bitCount = 0;
while (!(mask & bit))
{ *shiftCount += 1; bit <<= 1; }
while (mask & bit)
{ *bitCount += 1; bit <<= 1; }
}
If we notice the mask if 0, the loop will never end.
I cannot hook this function because it is not exported.
Any idea about working around it ? or rewriting the _wglDescribePixelFormat method which is exported but I have no idea how to tranlate that.
The initial call to the setPixelFormat is
bool CGLContext::CreateOffScreenContext(int nWidth, int nHeight, CString* pstrLog /*=NULL*/)
{
if(pstrLog)
pstrLog->Append("Creating Off Screen Context\r\n");
m_eContextType = CONTEXT_TYPE_OFFSCREEN;
// Create a new Device Context
m_pDC = new CDC;
m_pDC->CreateCompatibleDC(NULL);
// Initialize all of the compenents used to select a pixel format
memset(&m_PixelFormatDescriptor, 0, sizeof(m_PixelFormatDescriptor));
m_PixelFormatDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
m_PixelFormatDescriptor.nVersion = 1;
m_PixelFormatDescriptor.dwFlags = PFD_DRAW_TO_BITMAP|PFD_SUPPORT_OPENGL|PFD_SUPPORT_GDI;
m_PixelFormatDescriptor.iPixelType = PFD_TYPE_RGBA;
m_PixelFormatDescriptor.cColorBits = 0;
m_PixelFormatDescriptor.cDepthBits = 0;
m_PixelFormatDescriptor.cAccumBits = 0;
m_PixelFormatDescriptor.cStencilBits = 0;
m_PixelFormatDescriptor.cAuxBuffers = 0;
m_PixelFormatDescriptor.iLayerType = PFD_MAIN_PLANE;
m_hDC = m_pDC->m_hDC;
int nPixelFormat = ChoosePixelFormat(m_hDC, &m_PixelFormatDescriptor);
if(nPixelFormat == 0) {
if(pstrLog)
{
CString str;
str.Format("Unable to Choose Pixel Format: %li\r\n", nPixelFormat);
pstrLog->Append(str);
pstrLog->Append(DescribePFD(m_PixelFormatDescriptor));
return false;
}
else
{
ThrowException("Unable to Choose Pixel Format");
}
}.....

What's a good pattern to calculate a variable only when it is used the first time? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
Not an actual problem but I'm looking for a pattern to improve the following logic:
void PrintToGameMasters()
{
std::string message = GetComplicatedDebugMessage(); // This will create a big string with various info
for (Player* player : GetAllPlayers())
if (player->IsGameMaster())
player->SendMessage(message);
}
This code works, but the issue I have is that in most cases there aren't any gamemasters players so the message composition will be done for nothing.
I'd like to write something that would only create the message on the first use of that variable, but I can't come up with a good solution here.
EDIT:
To make this question more precise, I'm looking for a solution that's not specific to strings, it could be a type without a function to test if it's initialized.
Also big bonus points if we can keep the call to GetComplicatedDebugMessage at the top of the loop, I think a solution involving a wrapper would solve this.
Whereas std::string has empty value which might mean "not computed", you might use more generally std::optional which handle empty string and non default constructible types:
void PrintToGameMasters()
{
std::optional<std::string> message;
for (Player* player : GetAllPlayers()) {
if (player->IsGameMaster()) {
if (!message) {
message = GetComplicatedDebugMessage();
}
player->SendMessage(*message);
}
}
}
Use data-oriented design; keep two lists of players: game masters and non-game masters (or all players like you have now + a separate vector of pointers to game-masters only).
void PrintToGameMasters()
{
auto players = GetGameMasters(); // Returns ONLY game master players
if (players.begin() != players.end()) {
std::string message = GetComplicatedDebugMessage();
for (Player* player : players) {
player->SendMessage(message);
}
}
}
The goal is to minimize if-statements inside loops.
Optimize for the most common case, not the most generic one; the most common case is that a player is not a game master; so avoid looping over them.
P.S. Since you're developing a game, I want to add this link to Mike Acton's cppcon talk which you might find interesting.
Some good ideas here, but I like to keep it a bit more simple:
void PrintToGameMasters()
{
std::string message;
for (Player* player : GetAllPlayers())
{
if (player->IsGameMaster())
{
if (message.empty())
message = GetComplicatedDebugMessage();
player->SendMessage(message);
}
}
}
Everybody can follow this, and it's cheap as chips… plus it's easy as pie to debug.
You can use std::call_once with a lambda to call the function the first time you find a game master like
void PrintToGameMasters()
{
std::once_flag of;
std::string message;
for (Player* player : GetAllPlayers())
if (player->IsGameMaster())
{
std::call_once(of, [&](){ message = GetComplicatedDebugMessage(); });
player->SendMessage(message);
}
}
Wrap the message in a mutable lambda:
auto makeMessage = [message = std::string()]() mutable -> std::string&
{
if (message.empty()) {
message = GetComplicatedDebugMessage();
}
return message;
};
for (Player* player : GetAllPlayers())
if (player->IsGameMaster())
player->SendMessage(makeMessage());
You can extend the approach of using an std::optional (as in Jarod41's answer) with lazy evaluation on top. This would also fulfill the requirement to "keep the call to GetComplicatedDebugMessage at the top of the loop".
template <typename T>
class Lazy : public std::optional<T> {
public:
Lazy(std::function<T()> f) : fn(f) { }
T operator*() {
if (!*this)
std::optional<T>::operator=(fn());
return this->value();
}
private:
std::function<T()> fn;
};
void PrintToGameMasters()
{
Lazy<std::string> message(GetComplicatedDebugMessage);
for (Player* player : GetAllPlayers())
if (player->IsGameMaster())
player->SendMessage(*message);
}
Not sure if this is the best pattern, but you can delay computation with a lambda:
void PrintToGameMasters()
{
std::string message = "";
auto getDebugMessage = [&message]() -> const std::string& {
if (message.empty()) {
message = GetComplicatedDebugMessage();
}
return message;
};
for (Player* player : GetAllPlayers())
if (player->IsGameMaster())
player->SendMessage(getDebugMessage());
}
I'm not sure why you want to keep the definition of message above the loop. If someone's reading the code to analyze what happens in the case where std::end(GetAllPlayers())==std::begin(GetAllPlayers)(), you don't want to clutter their mental workspace with irrelevant variables.
If you're willing to give that up, then static is your friend:
void PrintToGameMasters()
{
for (auto const &player : GetAllPlayers())
if (player->IsGameMaster())
{
//Initialization of a static variable occurs exactly once, even when multithreaded,
//precisely when the defining line is hit for the first time
static auto const &message{GetComplicatedDebugMessage()};
player->SendMessage(message);
}
}
This is literally one of the things std::future is designed to solve:
void PrintToGameMasters()
{
auto message = std::async(
std::launch::deferred,
[]{return GetComplicatedDebugMessage();}
);
for (Player* player : GetAllPlayers())
if (player->IsGameMaster())
player->SendMessage(message.get());
}
Invoking std::async with std::launch::deferred causes the task to be “executed on the calling thread the first time its result is requested”.
This works. As the MIT license would put it:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED
#include <Windows.h>
#include <cstdlib>
#include <cstdio>
#include <string>
struct Player {
bool isGameMaster;
int id;
};
int __stdcall IsGameMaster(Player* self) {
return self->isGameMaster ? 1 : 0;
}
// Could've been "SendMessage"... but Windows.h
void __stdcall SendMessageToPlayer(Player* self, std::string* msg) {
printf("Player %d says: %s\n", self->id - 1000 + 1, msg->c_str());
}
Player g_players[18];
Player* __stdcall GetAllPlayers(void){
return &g_players[0];
}
std::string le_message = "hi, I'm a game master";
std::string* __stdcall GetComplicatedMessage(void) {
puts("GENERATING COMPLICATED MESSAGE. HOGGING CPU FOR 3 DAYS!");
return &le_message; // to make my assembly life easier
}
__declspec(naked) void PrintToGameMasters(void){
__asm {
push ebp;
mov ebp, esp;
sub esp, 8;
call GetAllPlayers;
mov [ebp-4], eax;
// this is 'i', the loop iteration counter
// I chose esi because it is preserved by stdcalls
xor esi, esi;
do_loop:
// Player* player = &g_players[i];
mov ebx, esi;
imul ebx, SIZE Player;
add ebx, [ebp-4]; // ebx = g_players + sizeof(Player) * i, or &g_players[i]
// if (player->IsGameMaster()) {
push ebx;
call IsGameMaster;
test eax, eax;
jz no_print;
// msg = GetComplicatedMessage();
get_msg_start:
call GetComplicatedMessage;
mov [ebp-8], eax;
jmp short delete_self;
get_msg_end:
// player->SendMessage(msg);
push [ebp-8];
push ebx;
call SendMessageToPlayer;
// }
no_print:
inc esi;
cmp esi, 18;
jb do_loop;
mov esp, ebp;
pop ebp;
ret;
delete_self:
mov ecx, get_msg_start;
mov eax, get_msg_end;
sub eax, ecx;
mov byte ptr [ecx], 0xEB; // jmp short
mov byte ptr [ecx+1], al; // relative offset
jmp get_msg_end;
}
}
int main(){
for (int i = 0; i < 18; i++) {
g_players[i].isGameMaster = (i == 12 || i == 15); // players 13 and 16
g_players[i].id = i + 1000;
}
DWORD oldProtect;
VirtualProtect(&PrintToGameMasters, 0x1000, PAGE_EXECUTE_READWRITE, &oldProtect);
PrintToGameMasters();
return 0;
}
It is much faster than the if (!message) message = GetMessage() approach, unless you have a CPU with a branch predictor (which you likely do). In that case, it's slower (or maybe equally fast, but not faster), uglier, less portable, and will likely get you killed by a psychopath.
You can use a custom local type with a conversion operator:
void PrintToGameMasters()
{
struct {
operator std::string const &(void)
{
static auto const real_value{GetComplicatedDebugMessage()};
return real_value;
}
} message;
for (auto const &player : GetAllPlayers())
if (player->IsGameMaster())
player->SendMessage(message);
}
Of course, this assumes that GetComplicatedDebugMessage is in fact stateless. Otherwise, you'll need to resort to capturing a lambda, or similar tricks described in the other answers here.
Really hope this helps
Try maybe implementing this logic:
#include <iostream>
using namespace std;
int main()
{
bool GameMaster,first_time,used_before;
GameMaster = true;
first_time = false;
used_before = false;
GameMaster = first_time;
first_time = used_before;
for( int i = 0; i < 5; i++ ) {
if(GameMaster==used_before) {
cout<<" First Time";
GameMaster = true;
}
if(GameMaster!=used_before) {
cout<<" Old News";
}
}
return 0;
}
With Response:
First Time Old News Old News Old News Old News Old News
static variables are initialized on first time through. So:
void PrintToGameMasters()
{
for (Player* player : GetAllPlayers())
if (player->IsGameMaster()) {
static std::string message = GetComplicatedDebugMessage(); // This will create a big string with various info
player->SendMessage(message);
}
}
This is, of course, assuming that calculating the value once at most (rather than once per call at most) is a valid way of proceeding. It's not clear from how you phrased your task whether this is the case.

Program was killed after function returning

My program was killed when the function "dbmSetIndex" was returned.
You can see the killed position below. (=> part)
Could you explain what happened?
(x86 intel)
0x0000000000420723 <+83>: mov rdi,r14
0x0000000000420726 <+86>: call 0x405260 <dbmSetIndex#plt>
0x000000000042072b <+91>: test eax,eax
0x000000000042072d <+93>: mov ebp,eax
=> 0x000000000042072f <+95>: mov DWORD PTR [r12],eax
0x0000000000420733 <+99>: jne 0x4207d0 <FnDBBase::SelectSecurity(s_oms_security*, char*)+256>
0x0000000000420739 <+105>: lea rsi,[rip+0x4197d] # 0x4620bd
Here is the dbmSetIndex code.
I can't find what part of this code caused this problem.
int dbmSetIndex ( dbmHandle* aHandle, const char* aTable, const char* aIndexName )
{
dbmInternalHandle* pHandle = NULL;
_TRY
{
pHandle = (dbmInternalHandle*)aHandle->mHandle;
// Water Mark가 다르면 걍 리턴해라.
if ( unlikely ( aHandle->mMark != DBM_HANDLE_MARK ) )
{
DBM_ERR ( "invalide magic number (%ld)", aHandle->mMark );
_THROW( ERR_DBM_INVALID_HANDLE );
}
if( pHandle->mRemote != NULL )
{
if( pHandle->mRemote->mSockFd > 0 )
{
_CALL( dbmRemoteSetIndex( aHandle, aTable, aIndexName ) );
_RETURN;
}
}
/****************************************
* DataObject 맵핑.
****************************************/
memset_s( &pHandle->mData, 0x00, sizeof( pHandle->mData ) );
memcpy_s ( pHandle->mData.mTableName, aTable, strlen_s ( aTable ) + 1 );
pHandle->mData.mTransType = DBM_SET_INDEX;
pHandle->mData.mUserData = (char*)aIndexName;
/****************************************
* mAct 호출.
****************************************/
_CALL( pHandle->mTrans->mAct ( pHandle ) );
}
_CATCH
{
_CATCH_ERR;
}
_FINALLY
_END
}
You provided a little bit of dissassembly which shows that the call to the function you provided returned already. The crash did not occur within the function, but afterwards:
Call of your function:
0x0000000000420726 <+86>: call 0x405260 <dbmSetIndex#plt>
Here you returned already:
0x000000000042072b <+91>: test eax,eax
The critical line is a memory access to the address stored in register r12 (write):
0x000000000042072f <+95>: mov DWORD PTR [r12],eax
Let your debugger show the registers and have a look at the content of r12. It is very likely that it is 0x0000000000000000 or a small value, thus a null pointer (or null reference), but it could contain, too, an invalid address (uninitialised pointer!).
There is little more left to tell from the information you provide, though. You will have to look at the code location where the function is called -- it must be within function FnDBBase::SelectSecurity(s_oms_security*, char*) because you jump (jne) to an offset within this function ([...] + 256). There should be an if involved (test + jne instructions) and probably some pointer assignment. Possibly something like this:
SomeClass* s = [...];
s->someMember = dbmSetIndex([...]); // (*)
if(*s->someMember)
(*): Failure location, error happened during assignment after the function completed already. Don't count 100% on finding such an assignment, it could be, too, a call to an inlined setter function.
And here we see, too, why r12 is not necessarily 0: it would contain the precalculated offset of someMember within SomeClass, i. e. &(s->someMember) which could well be, if s is 0, e. g. 16, 28, ... Precisely, the value contained then is equal to offsetof(SomeClass, somemember).

fontComboBox QSettings application unexpectedly quits

I am trying to implement QSettings in an editor of mine. I am trying to implement it for font changes. However, whenever I start up my program it exits immediately.
Here's my code:
When I change the font in my font box.
void SquareIDE::on_fontBox_currentFontChanged(const QFont &f)
{
ui->fontBox->setFont(f);
ui->textEdit->setMarginsFont(f);
lexer1->setFont(f);
settings.setValue("font", f);
}
On start up when it loads the settings.
void SquareIDE::loadSettings()
{
dee = settings.value("dee", true).toBool();
autosave = settings.value("autosave", true).toBool();
font = settings.value("font", f).toString();
QFont font1 = font;
if (dee == true) {
ui->dee->setChecked(true);
}
if (autosave == true) {
ui->autosave->setChecked(true);
}
ui->fontBox->setCurrentFont(font1);
}
Debugger Output:
Function: _ZN9SquareIDE29on_fontBox_currentFontChangedERK5QFont
0x4099ce <+0x004e> add %al,(%rax)
0x4099d0 <+0x0050> mov 0x90(%rbx),%rdi
0x4099d7 <+0x0057> mov $0xffffffff,%edx
0x4099dc <+0x005c> mov %rbp,%rsi
0x4099df <+0x005f> mov (%rdi),%rax
0x4099e2 <+0x0062> callq *0x150(%rax)
0x4099e8 <+0x0068> mov %rbp,%rsi
0x4099eb <+0x006b> mov %r12,%rdi
0x4099ee <+0x006e> callq 0x406020 <_ZNK5QFontcv8QVariantEv#plt>
0x4099f3 <+0x0073> lea 0x8a7b(%rip),%rdi # 0x412475
0x4099fa <+0x007a> mov $0x4,%esi
0x4099ff <+0x007f> callq 0x405c70 <_ZN7QString16fromAscii_helperEPKci#plt>
0x409a04 <+0x0084> lea 0x98(%rbx),%rdi
0x409a0b <+0x008b> mov %r12,%rdx
0x409a0e <+0x008e> mov %rsp,%rsi
0x409a11 <+0x0091> mov %rax,(%rsp)
0x409a15 <+0x0095> mov %rsp,%rbp
0x409a18 <+0x0098> callq 0x406430 <_ZN9QSettings8setValueERK7QStringRK8QVariant#plt>
0x409a1d <+0x009d> mov (%rsp),%rdi
0x409a21 <+0x00a1> mov (%rdi),%eax
0x409a23 <+0x00a3> test %eax,%eax
0x409a25 <+0x00a5> jne 0x409a60 <_ZN9SquareIDE29on_fontBox_currentFontChangedERK5QFont+224>
0x409a27 <+0x00a7> mov $0x8,%edx
0x409a2c <+0x00ac> mov $0x2,%esi
0x409a31 <+0x00b1> callq 0x406250 <_ZN10QArrayData10deallocateEPS_mm#plt>
0x409a36 <+0x00b6> mov %r12,%rdi
0x409a39 <+0x00b9> callq 0x405cd0 <_ZN8QVariantD1Ev#plt>
0x409a3e <+0x00be> mov 0x28(%rsp),%rax
0x409a43 <+0x00c3> xor %fs:0x28,%rax
See when I comment out the new QSettings code:
void SquareIDE::loadSettings()
{
dee = settings.value("dee", true).toBool();
autosave = settings.value("autosave", true).toBool();
//font = settings.value("font", f).toString();
//QFont font1 = font;
if (dee == true) {
ui->dee->setChecked(true);
}
if (autosave == true) {
ui->autosave->setChecked(true);
}
//ui->fontBox->setCurrentFont(font1);
}
I compiles and runs fine.
QFont f can be used outside the function because it was also defined in squareide.h
private:
...
QFont f;
You seem to have infinite recursion - in your fontBox currentFontChanged slot, you change the font, which will cause the event to run again:
void SquareIDE::on_fontBox_currentFontChanged(const QFont &f)
{
ui->fontBox->setFont(f);
You don't need that line.
And your stack trace, almost useless as it is, shows the crash is occurring inside the currentFontChanged slot on the line
settings.setValue("font", a);
What is a? It is used in your code in several places but not declared in what you posted. Appears to be an invalid variant at the time of that setValue() call.
The program seemed to have a problem with this one line:
lexer1->setFont(f);
So, I figured I would make it so that way every time the lexer was changed I would make it so the lexer automatically sets its font to the font set in the font combo box like so:
void SquareIDE::on_comboBox_currentIndexChanged(QString i)
{
if (i=="JavaScript") {
QsciLexer *lexer1(new QsciLexerJavaScript);
lexer1->setFont(ui->fontBox->currentFont());
}
if (i=="HTML") {
QsciLexer *lexer1(new QsciLexerHTML);
lexer1->setFont(ui->fontBox->currentFont());
}
if (i=="SquareScript") {
QsciLexer *lexer1(new QsciLexerJavaScript);
lexer1->setFont(ui->fontBox->currentFont());
QsciAPIs *api = new QsciAPIs(lexer1);
api->add("clear");
api->add("canvas");
api->add("stroke");
api->add("fill");
api->add("noStroke");
api->add("noFill");
api->add("rect");
api->add("triangle");
api->add("circle");
api->add("arc");
api->add("font");
api->add("text");
api->add("h1");
api->add("h2");
api->add("h3");
api->add("h4");
api->add("h5");
api->add("h6");
api->add("p");
api->add("title");
api->add("video");
api->add("mute");
api->add("controls");
api->add("preload");
api->add("autoplay");
api->add("audio");
api->add("loop");
api->prepare();
ui->textEdit->setLexer(lexer1);
}
}
Then I was able to call this function on the font change:
void SquareIDE::on_fontBox_currentFontChanged(const QFont &f)
{
this->setFont(f);
ui->fontBox->setFont(f);
ui->textEdit->setMarginsFont(f);
settings.setValue("font", f);
on_comboBox_currentIndexChanged(ui->comboBox->currentText());
}
This completely solved my problem.

How can a private member be changed without calling a non-const method?

I have a problem. I spend around 5 hours trying everything, but I was not even able to reproduce it properly so I include the simplified original source code. I apologize for the extent, but I wanted to include all the relevant information I found out so far. This is one of the few times I feel completely powerless and kindly request your help. Any ideas are welcome. Also any comments that can bring at least some light to the matter. The behaviour in this case is a complete mystery to me.
I am programming in QtCreator in Ubuntu. I am trying to develop a framework to solve mathematical problems using a Population of candidate solutions, which should evolve into the true solution.
There are 3 classes involved: Population, PopulationMember and Problem:
class PopulationMember
{
QVector<Number> x_;
QVector<Number> y_;
Population* population_; EDIT: Sorry, this is a pointer
void evaluate();
friend class Population;
};
class Population
{p
public:
QList<PopulationMember*> members_; // created on the heap
Problem* problem_; // created on the heap
const Problem* readProblem() const;p
void evaluate();
void report() const;
...
};
class Problem
{
public:
void evaluate(PopulationMember&)const;
};
Usually my program runs in loops, where the population calls its various methods. One of them is Population::evaluate(). My program ran great until I introduced some new methods of Population.
for (int i = 1; i != 101; ++i)
{
Population->evaluate();
Population->someMethod1();
Population temp = Population->clone();
temp->someMethod2();
Population->append(temp);
Population->someNewMethod();
Population->someSorting();
if (i % 10 == 0)
Population->report();
}
Then I get a segmentation error in the middle of program. The strangest thing is that it happens only after the 10 loops, after the population executed report(). Also after some experimentation, when I excluded all the operations which require dynamic allocation of some sort (strings) from the report() method, I do not get the error. Conversely when I disable the sorting method (uses either std::sort or qSort) the problem stops. Also when I leave the actions done by the temp Population, there is no problem. So I started to debug the program. I let it complete 10 loops and started to debug step by step. I went into Population->evaluate();
void Population::evaluate()
{
for (Iterator it = begin(); it != end(); ++it)
{
std::cout << problem_; // debug see bellow:
(*it) -> evaluate(); // If I change to problem_->evaluate(**it); the program works.
}
}
debug:
The addres printed out is 0xbffff628. This is same as the previous 10 * population_->members_.count() printouts.
I go inside the (*it) -> evaluate(); Here I switch to assembly code:
864 (*it) -> evaluate();
0x805380c <+122>: lea -0x10(%ebp),%eax
0x805380f <+125>: mov %eax,(%esp)
0x8053812 <+128>: call 0x8055d84 <QList<PopulationMember*>::iterator::operator*() const>
0x8053817 <+133>: mov (%eax),%eax
0x8053819 <+135>: mov %eax,(%esp)
0x805381c <+138>: call 0x805ae08 <PopulationMember::evaluate()>
I go inside the call of function at the last instruction. At the instant I do this, all the attributes in problem_ become not accessible according to my debugger.
At this point all is lost.
void PopulationMember::evaluate()
{
population_ -> readProblem() -> evaluate(*this);
}
135 {
0x805ae08 <+000>: push %ebp
0x805ae09 <+001>: mov %esp,%ebp
0x805ae0b <+003>: sub $0x18,%esp
136 population_ -> readProblem() -> evaluate(*this);
0x805ae0e <+006>: mov 0x8(%ebp),%eax
0x805ae11 <+009>: mov 0x4(%eax),%eax
0x805ae14 <+012>: mov %eax,(%esp)
0x805ae17 <+015>: call 0x8051bc4 <Population::readProblem() const>
0x805ae1c <+020>: mov 0x8(%ebp),%edx
0x805ae1f <+023>: mov %edx,0x4(%esp)
0x805ae23 <+027>: mov %eax,(%esp)
0x805ae26 <+030>: call 0x804e962 <Problem::evaluate(PopulationMember&) const>
137 }
0x805ae2b <+035>: leave
0x805ae2c <+036>: ret
0x805ae2d nop
const Problem* Population::readProblem() const
{
std::cout << problem_ << std::endl; // debug see bellow:
return problem_;
}
debug:
Finally the address the problem_ is pointing at becomes 0xbffff780 instead of 0xbffff628. An increment of 344
This happens always. The increment is 344. If I make some minor changes in the program, the address changes, but the difference between these two addresses remains 344. This is all the more puzzling, since the size of all my three classes is less than 100.
The program crashes inside the void Problem::evaluate(PopulationMember&)const; method as soon as some logic is involved.
EDIT:
Population Population::clone()
{
Population temp(*this);
return temp;
}
Population::Population(const Population& population)
{
this->setProblem(population.problem_);
Population::ConstIterator cit;
for (cit = population.constBegin(); cit != population.constEnd(); ++cit)
this->addCopy(*cit);
this->ownsMembers_ = true;
}
void Population::addCopy (PopulationMember* populationMember)
{
PopulationMember *temp = new PopulationMember(*populationMember); // Memberwise
temp -> population_ = this;
members_.push_back(populationMember);
}
Population::~Population()
{
if (ownsMembers_)
foreach (PopulationMember* X, members_)
delete X;
}
void Population::append(Population& population)
{
if (population.ownsMembers_)
{
members_.append(population.members_);
population.ownsMembers_ = false;
}
else
members_.append(population.members_);
}
Population Population::clone()
{
Population temp(*this);
return temp;
}
You are copying around Population-instances quite a bit: 1. you are returning a local copy by value, 2. copying again by assigning into another local with
Population temp = Population->clone();
All these instances get pointers to PopulationMember and ownsMembers_ is always set true - this looks quite a bit fishy and you might want to debug with breakpoints in your destructors/constructors to find out the lifecycle of each population and its members.
EDIT: append method
void Population::append(Population& population)
{
if (population.ownsMembers_)
{
members_.append(population.members_);
population.ownsMembers_ = false;
}
...
This means that the members to not point to the correct Population anymore! The value of Population& is stored on stack and gets deleted after the for loop ends, but the PopulationMembers still point to these Populations.
Edit: Fix
please try this:
void Population::append(Population& population)
{
if (population.ownsMembers_)
{
for (cit = population.constBegin(); cit != population.constEnd(); ++cit)
(*cit)-> population_ = this;
population.ownsMembers_ = false;
}
members_.append(population.members_);
}