Get abending line number in C++ using Visual Studio - c++

Okay, I've been beating my head against a brick wall for a couple of days now...
I have a __try __except piece of code with this in it:
__except(ExFilter(GetExceptionCode(),GetExceptionInformation())){
// Print the message ExFilter set up
MessageBox(NULL, (LPTSTR)outline, "setup/LoadSettingsFromIni error", MB_OK);
if(ExFilter_rc > 0) { // should we abend?
exit(9) ; // yes
}
} // end of __except...
and in the ExFilter code:
LONG ExFilter(DWORD error,LPEXCEPTION_POINTERS lpExceptionInfo){
void *addressPtr;
EXCEPTION_RECORD *myExecptionRecord;
myExecptionRecord = lpExceptionInfo->ExceptionRecord;
addressPtr = myExecptionRecord->ExceptionAddress;
At this point, addressPtr points to:
0x00007ff73b70d4c8 {Regshot-x64-ANSI-dbg.exe!LoadSettingsFromIni(HWND__ * hDlg), Line 355}
More of the code gets the program name using "GetModuleFileName" etc.
But I already know the program name.
I've tried many ways to get the data "Line 355" but no luck.
How do I get at it so I can put it in a message?
Thanks.

I'm sure many people have found a way around this, but here is my "poor man's solution" for trapping errors I suddenly thought of the other day:
I added a counter to areas in my code that might cause a problem, and then in the __except filter added code to show the counter, which would give me a more concise area to look at.
Here is what I did:
char outline[1310] ; // __except output line
size_t rc2 ; // lth of outline
int ctr ;
__try {
code
..
ctr = 1 ;
code
..
ctr = 2 ;
code
..
ctr = 3 ;
code
..
} // end of try
__except(ExFilter(GetExceptionCode(),GetExceptionInformation())){
// Print the message ExFilter set up
MessageBox(NULL, (LPTSTR)outline, "setup/LoadSettingsFromIni error", MB_OK);
if(ExFilter_rc > 0) { // should we abend?
exit(9) ; // yes
}
} // end of __except...
and in the ExFilter code:
LONG ExFilter(DWORD error,LPEXCEPTION_POINTERS
lpExceptionInfo){
void *addressPtr;
EXCEPTION_RECORD *myExecptionRecord;
myExecptionRecord = lpExceptionInfo->ExceptionRecord;
addressPtr = myExecptionRecord->ExceptionAddress;
sprintf(outline, ""); // blank outline
rc2 = strlen(outline);
rc = error ; // GetExceptionCode() passed by __except
if (rc == EXCEPTION_INT_DIVIDE_BY_ZERO) {
sprintf(outline+rc2, "Divide by Zero!");
goto f_end7a ; // continue
}
... more code for each trapped error.....
f_end7a: ;
rc2 = strlen(outline);
sprintf(outline+rc2, "\n\nError occured after instruction \"ctr = %i ;\" \n", ctr);
return EXCEPTION_EXECUTE_HANDLER; // return to __except...
So if an error occurs, a message is displayed, with a line like:
Error occurred after instruction "ctr = 2"
and I know approximately where it happened, between ctr = 2 and ctr = 3.
This may be "Mickey Mouse", but it's better than nothing.

Related

How to get the progress of a TRichEdit?

I have a simple 'brut' big text file (20MB). I would like to show it in a TRichEdit. The problem is that it takes 6 seconds for the showing. I would like to put a progess bar in the bottom of the application to avoid this bad UX design.
My question is how to get the progress of the TRichEdit showing ? With the TRichEdit::LoadFromStream method, it goes from 0 to 100% fast (less than 1 second) but after the application wait 6 secondes during the first show.
I created this class FileStreamProgress with TFileStream inherit. I overide the TFileStream::Read()
int __fastcall FileStreamProgress::Read(void *Buffer, int Count)
{
__int64 previousPosition = this->Position;
int ret = TFileStream::Read(Buffer, Count);
if (this->Position == 0 || this->Position == this->Size || (previousPosition/128000) != (this->Position/128000)) {
ProgressCallBack(ProgressCallBackParam1, this->Position, this->Size);
}
return ret;
}
static void FileStreamProgress::ProgressCallBack(void*thiz, int i, int max)
{
TProgressBar* ProgressBar = (TProgressBar*)thiz;
if (ProgressBar)
{
if (max > 0)
{
ProgressBar->Position = int(i * 100 / max);
}
if (Application)
{
Sleep(1);
Application->ProcessMessages();
}
}
}
This is how I test it :
void MyApp::CreatePage(AnsiString filename)
{
ProgressBar->Visible = true;
FileStreamProgress::ProgressCallBackParam1 = (void*)this->ProgressBar;
TFileStream * stream = new FileStreamProgress(filename.c_str(), fmOpenRead);
TPageMemo* Page = new TPageMemo(this);
Page->Parent = PControl;
Page->PageControl = PControl;
MessageDlg("111",mtError,TMsgDlgButtons()<<mbOK,0);
Page->Texte->Lines->LoadFromStream(stream);
MessageDlg("222",mtError,TMsgDlgButtons()<<mbOK,0);
PControl->ActivePage = Page;
}
There are 7 secondes between the 2 message dialogs "111" and "222". And my progress bar wait 6 secondes at 100% (during the showing)
I tried to go deeper with the win32 API's SendMessage and Handle without the expected result.
At the end, I used a TMemo yesterday cuz it's a brut text. It's very fast (instant open) but some functions are missing like FindTextW(). I rewrote it. Thanks
http://docwiki.embarcadero.com/RADStudio/Rio/en/Memo_and_Rich_Edit_Controls
was curious so I tested the TRichEdit and came up with this:
//---------------------------------------------------------------------------
void load_text(TRichEdit *re,AnsiString filename,TProgressBar *pb)
{
// variables
int hnd,adr,siz,len,i;
const int _buf=128*1024; // buffer size
AnsiString s,s0;
char buf[_buf+1];
// open file and detect size
hnd=FileOpen(filename,fmOpenRead); if (hnd<0) return;
siz=FileSeek(hnd,0,2);
FileSeek(hnd,0,0);
// prepare progress bar
pb->Position=0;
pb->Max=siz;
pb->Visible=true;
// process txt file by chunks
for (s0="",adr=0;adr<siz;)
{
// update progress bar and GUI
pb->Position=adr;
Application->ProcessMessages();
// load chunk
len=FileRead(hnd,buf,_buf);
adr+=len; buf[len]=0;
// handle cutted lines by chunk size
s=s0; s0="";
// ignore last 2 lines for chunks (except last chunk)
if (len==_buf)
{
// skip last line
for (i=len-1;i>=0;i--)
if ((buf[i]==13)||(buf[i]==10))
{
i--;
if (i>=0)
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
break;
}
// skip another line to avoid inserting empty line if eol is cutted
for (;i>=0;i--)
if ((buf[i]==13)||(buf[i]==10))
{
s0+=buf+i+1; // copy last 2 lines into s0
i--;
if (i>=0)
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
i++; if (i<0) i=0; buf[i]=0; // end of string
break;
}
}
// last chunk ignore last eol
else{
// skip last line
i=len-1;
if ((buf[i]==13)||(buf[i]==10)) // eol code
{
i--;
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
i++; if (i<0) i=0; buf[i]=0; // end of string
}
}
// add actual chunk
s+=buf;
re->Lines->Add(s);
}
// tidy up
pb->Visible=false;
FileClose(hnd); hnd=-1;
}
//---------------------------------------------------------------------------
Looks like it works without the ending pause you describe however that might be related to version of IDE/VCL/compiler I am using BDS2006 Turbo C++. When Tested on ~23 MByte STL file the load time is ~10sec (TMemo takes twice of that god know why)...
The saved file (while PlainText=true) is identical to the loaded one so the code should be correct.
Here animated GIF of preview:
while used like this:
void __fastcall TForm1::FormActivate(TObject *Sender)
{
//tbeg();
load_text(re_txt,"in.txt",pb_progress);
//tend();
//Caption=tstr();
re_txt->Lines->SaveToFile("out.txt");
}
where pb_progress is the TProgressBar and and re_txt is the TRichEdit.
As you can see no callback is needed ...
PS. If you want to measure the time like I did (the commented lines) the implementations of tbeg/tend/tstr functions are here:
performance.h

SetPerTcpConnectionEStats fails and can't get GetPerTcpConnectionEStats multiple times c++

I am following the example in https://learn.microsoft.com/en-gb/windows/win32/api/iphlpapi/nf-iphlpapi-getpertcp6connectionestats?redirectedfrom=MSDN to get the TCP statistics. Although, I got it working and get the statistics in the first place, still I want to record them every a time interval (which I haven't managed to do so), and I have the following questions.
The SetPerTcpConnectionEStats () fails with status != NO_ERROR and equal to 5. Although, it fails, I can get the statistics. Why?
I want to get the statistics every, let's say 1 second. I have tried two different ways; a) to use a while loop and use a std::this_thread::sleep_for(1s), where I could get the statistics every ~1sec, but the whole app was stalling (is it because of the this), I supposed that I am blocking the operation of the main, and b) (since a) failed) I tried to call TcpStatistics() from another function (in different class) that is triggered every 1 sec (I store clientConnectRow to a global var). However, in that case (b), GetPerTcpConnectionEStats() fails with winStatus = 1214 (ERROR_INVALID_NETNAME) and of course TcpStatistics() cannot get any of the statistics.
a)
ClassB::ClassB()
{
UINT winStatus = GetTcpRow(localPort, hostPort, MIB_TCP_STATE_ESTAB, (PMIB_TCPROW)clientConnectRow);
ToggleAllEstats(clientConnectRow, TRUE);
thread t1(&ClassB::TcpStatistics, this, clientConnectRow);
t1.join();
}
ClassB::TcpStatistics()
{
while (true)
{
GetAndOutputEstats(row, TcpConnectionEstatsBandwidth)
// some more code here
this_thread::sleep_for(milliseconds(1000));
}
}
b)
ClassB::ClassB()
{
MIB_TCPROW client4ConnectRow;
void* clientConnectRow = NULL;
clientConnectRow = &client4ConnectRow;
UINT winStatus = GetTcpRow(localPort, hostPort, MIB_TCP_STATE_ESTAB, (PMIB_TCPROW)clientConnectRow);
m_clientConnectRow = clientConnectRow;
TcpStatistics();
}
ClassB::TcpStatistics()
{
ToggleAllEstats(m_clientConnectRow , TRUE);
void* row = m_clientConnectRow;
GetAndOutputEstats(row, TcpConnectionEstatsBandwidth)
// some more code here
}
ClassB::GetAndOutputEstats(void* row, TCP_ESTATS_TYPE type)
{
//...
winStatus = GetPerTcpConnectionEStats((PMIB_TCPROW)row, type, NULL, 0, 0, ros, 0, rosSize, rod, 0, rodSize);
if (winStatus != NO_ERROR) {wprintf(L"\nGetPerTcpConnectionEStats %s failed. status = %d", estatsTypeNames[type], winStatus); //
}
else { ...}
}
ClassA::FunA()
{
classB_ptr->TcpStatistics();
}
I found a work around for the second part of my question. I am posting it here, in case someone else find it useful. There might be other solutions too, more advanced, but this is how I did it myself. We have to first Obtain MIB_TCPROW corresponding to the TCP connection and then to Enable Estats collection before dumping current stats. So, what I did was to add all of these in a function and call this instead, every time I want to get the stats.
void
ClassB::FunSetTcpStats()
{
MIB_TCPROW client4ConnectRow;
void* clientConnectRow = NULL;
clientConnectRow = &client4ConnectRow;
//this is for the statistics
UINT winStatus = GetTcpRow(lPort, hPort, MIB_TCP_STATE_ESTAB, (PMIB_TCPROW)clientConnectRow); //lPort & hPort in htons!
if (winStatus != ERROR_SUCCESS) {
wprintf(L"\nGetTcpRow failed on the client established connection with %d", winStatus);
return;
}
//
// Enable Estats collection and dump current stats.
//
ToggleAllEstats(clientConnectRow, TRUE);
TcpStatistics(clientConnectRow); // same as GetAllEstats() in msdn
}

Exception thrown with OpenCV's SVM training, c++

I have a problem with the Support Vector Machine , coding with visual studio, c++.
Tried to replicate the example of the tutorial at the following link
https://docs.opencv.org/3.4.0/d1/d73/tutorial_introduction_to_svm.html and the situation is
(having a breakpoint at "return 0;" line)
1) In debug , x64 I run the solution, and after "return 0" statement I have an exception thrown
at memory location (not unhandled, luckily) and then the program exit correctly.
2) In release, x64, I run the solution, and after "return 0" statement I have an exception thrown
at memory location but clicking on "continue" button, this appears (of mat.inl.hpp)
inline
void Mat::release()
{
if( u && CV_XADD(&u->refcount, -1) == 1 )
deallocate();
u = NULL;
datastart = dataend = datalimit = data = 0;
for(int i = 0; i < dims; i++)
----> size.p[i] = 0; <----- // (that's the exact line)!
#ifdef _DEBUG
flags = MAGIC_VAL;
dims = rows = cols = 0;
if(step.p != step.buf)
{
fastFree(step.p);
step.p = step.buf;
size.p = &rows;
}
#endif
}
And I have the correct exit of the program only clicking on "continue" bottom several times.
This happens only in release mode.
How to fix it?

Win32 ListView - handle invalid after LVM_INSERTITEM

I have a problem a window handle (window class = WC_LISTVIEW) after calling
SendMessage(hListView_, LVM_INSERTITEM , 0, (LPARAM)&lvItem);
where
hListView_
is a handle to a list view window and
lvItem
is an LVITEM structure. The following code
std::cout << "Last error: " << GetLastError() << std::endl;
SendMessage(hListView_, LVM_INSERTITEM , 0, (LPARAM)&lvItem);
std::cout << "Last error: " << GetLastError() << std::endl;
prints
Last error: 0
Last error: 6
According to Win32 System Error Codes code 6 means ERROR_INVALID_HANDLE.
I create the LVITEM structure as follows:
// define a char-buffer
char szBuffer[256];
szBuffer[0] = '\0';
// create new list view item
LVITEM lvItem;
lvItem.cchTextMax = 256;
lvItem.mask = LVIF_TEXT;
lvItem.iItem = 0;
lvItem.stateMask = 0;
lvItem.state = 0;
lvItem.iSubItem = 0;
snprintf(szBuffer, 256, "%s", myString.c_str());
lvItem.pszText = szBuffer;
This code is called from the same thread which created the window (list view).
Also note that I have
lvItem.iSubItem = 0;
which is required according to LVM_INSERTITEM. The list view is empty prior to this call. Moreover, I can actually see the value being inserted in the list view (i.e. I can see the item in the list view in the GUI).
However, when I try to use the window handle after this the application crashes (no exception, just crashes).
Greatful for any hints on what might cause this.
Thank you.
Thank you David Heffernan for your help. I did at last find the problem, which was (as you suggested) in a different place in the code.
I had missed the following line (in a different function which I call prior to the code I posted above)
lvItem.pszText = szBuffer;
where
char szBuffer[256]; // char-buffer
when doing the follwing call
SendMessage(hListView_, LVM_GETITEMTEXT, (WPARAM) i, (LPARAM) &lvItem);
Thanks a lot for your help!
Edit: If I had done
lvItem.pszText = myString.c_str();
rather than the char-buffer this would probably not have happened, so thanks for that hint!
There's no reason for you to call GetLastError. The documentation for LVM_INSERTITEM doesn't say that you should do so. All it says is that SendMessage returns the index of the new item on success, and -1 on failure. So, check for errors by inspecting the value returned by SendMessage.
The other problem is that you are not initialising all the fields of LVITEM. That's always a mistake. You can use an initialising declaration like this:
LVITEM lvItem = { 0 };
There's no real need for a separate buffer for the text. You can do it all like this:
LVITEM lvItem = { 0 };
lvItem.mask = LVIF_TEXT;
lvItem.cchTextMax = myString.length() + 1;
lvItem.pszText = myString.c_str();
int indexOfNewItem = SendMessage(hListView_, LVM_INSERTITEM, 0, (LPARAM)&lvItem);
if (indexOfNewItem == -1)
// deal with failure
It's quite possible that your error lies elsewhere in fact. I don't see any particular reason for that SendMessage call to lead to an application crash. At least now you know how to check for errors when sending LVM_INSERTITEM. If that does not result in an error then the evidence would be that the crash is caused by some other code and you have mistakenly identified this code because you erroneously called GetLastError when its value was meaningless.

switch case avoid loop

I have the following code:
int send_cmd( int sock, char * buffer, int lbuffer )
{
int err = 0;
//do_something part 1
while(1)
switch(check_status(buffer)){
case 1:
return 0;
break;
case 0:
if (err > 0)
break;
//do_something part 2
err = 1;
}
return -1;
}
I don't think this is well coded but I didn't know how to optimize it.
I wanna run the "part 2 code" only once and only if "part 1 code" gives an error.
Can you tell me how to make it run correctly? Cause right now doesn't return anything after part 2 is executed once.
I wanna run the "part 2 code" only once and only if "part 1 code" gives an error.
There's no need for a while loop or a switch statement.
// Do something part 1
if (check_status(buffer) == 1) {
return 0;
}
// Do something part 2
if (check_status(buffer) == 1) {
return 0;
}
else {
return -1;
}
If you don't need the loop, you can just use an if and return. Since you don't use err, you can omit it as well.
// first command
int status = check_status(buffer);
if (status == 1)
return 0;
// second command
status = check_status(buffer);
if (status == 1)
return 0;
return -1;
At least in this simple case, switch is not better or faster than if. There might be cases, where this is true, but I won't bet on it. Usually, the optimizer is good enough to emit optimal machine code, whether you use switch or if. So go for the simple, readable and maintainable code.
Looking at your, i think this is what you are trying to achieve using the err variable :
//Part 1
if ( check_status(buffer) ) return 0; //No error
//Part 2
if ( check_status(buffer) ) return 1; //One error
else return -1; //Two errors
You dont need any while loops to do this.