Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have some code that programs a dialog box to take in information from an outside instrument and display the values on the screen. When I compile and run my code in Debug mode it runs just fine, but when I switch to Release the program crashes and tells me I am accessing something incorrectly. After some searching on the web I configured my compiler to run without optimizations and also tried to enable debugging info in the project configurations (for Release). However, it does not stop at breakpoints in the Release version and so troubleshooting has been difficult. I get the impression that there is something not being initialized correctly, but I cannot find the problem. Can anyone help?

Here is the implementation file for the dialog box.

C++
#include "stdafx.h"
#include "winstm.h"
#include "Dlg_Channel_Meter.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifdef HARDWARE_NI
/////////////////////////////////////////////////////////////////////////////
// CDlg_Channel_Meter dialog


CDlg_Channel_Meter::CDlg_Channel_Meter(CWnd* pParent /*=NULL*/)
	: CDialog(CDlg_Channel_Meter::IDD, pParent)
	, m_DAC_Dev(0)
{

	theInst = ((CWinSTMApp*)AfxGetApp())->GetInstrument();

	m_Scan_Chan[0] = 0;
	m_Scan_Chan[1] = 1;
	m_Scan_Chan[2] = 2;
	m_Scan_Chan[3] = 3;
	m_Scan_Chan[4] = 4;
	m_Scan_Chan[5] = 5;
	m_Scan_Chan[6] = 6;
	m_Scan_Chan[7] = 7;

	m_pThread = NULL;
	//{{AFX_DATA_INIT(CDlg_Channel_Meter)
	m_ADC0 = _T("");
	m_ADC1 = _T("");
	m_ADC2 = _T("");
	m_ADC3 = _T("");
	m_ADC4 = _T("");
	m_ADC5 = _T("");
	m_ADC6 = _T("");
	m_ADC7 = _T("");

	ticks = 0;
	counts = 0;
	upperlimit = 10;  //any number up to 100, 10 = 10 cyles, each cycle = 100 ms, so 10 = 1 seconds

	for (int i = 0; i < 8; i++)
	{
		m_ADC_data[i]=0;
		m_ADC_ddata[i]=0;
		for (int c = 0; c < upperlimit; c++)
		{
			m_ADC_a_array[i][c] = 0;
		}
	}

	m_ADC_a.SetSize (8);
	m_ADC_std.SetSize (8);

	m_ADC_a[0] = _T("");
	m_ADC_a[1] = _T("");
	m_ADC_a[2] = _T("");
	m_ADC_a[3] = _T("");
	m_ADC_a[4] = _T("");
	m_ADC_a[5] = _T("");
	m_ADC_a[6] = _T("");
	m_ADC_a[7] = _T("");

	m_ADC_std[0] = _T("");
	m_ADC_std[1] = _T("");
	m_ADC_std[2] = _T("");
	m_ADC_std[3] = _T("");
	m_ADC_std[4] = _T("");
	m_ADC_std[5] = _T("");
	m_ADC_std[6] = _T("");
	m_ADC_std[7] = _T("");

	//}}AFX_DATA_INIT

	if(AfxGetApp()->GetProfileInt("UEI DAC","Enable",0))
		m_DAC_Dev = -1;
	else
		m_DAC_Dev = theInst->m_DAQ.m_6508_Device;

}


void CDlg_Channel_Meter::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlg_Channel_Meter)
	DDX_Text(pDX, IDC_6052E_ADC0, m_ADC0);
	DDX_Text(pDX, IDC_6052E_ADC1, m_ADC1);
	DDX_Text(pDX, IDC_6052E_ADC2, m_ADC2);
	DDX_Text(pDX, IDC_6052E_ADC3, m_ADC3);
	DDX_Text(pDX, IDC_6052E_ADC4, m_ADC4);
	DDX_Text(pDX, IDC_6052E_ADC5, m_ADC5);
	DDX_Text(pDX, IDC_6052E_ADC6, m_ADC6);
	DDX_Text(pDX, IDC_6052E_ADC7, m_ADC7);

	DDX_Text(pDX, IDC_6052E_ADC0_a, m_ADC_a[0]);
	DDX_Text(pDX, IDC_6052E_ADC1_a, m_ADC_a[1]);
	DDX_Text(pDX, IDC_6052E_ADC2_a, m_ADC_a[2]);
	DDX_Text(pDX, IDC_6052E_ADC3_a, m_ADC_a[3]);
	DDX_Text(pDX, IDC_6052E_ADC4_a, m_ADC_a[4]);
	DDX_Text(pDX, IDC_6052E_ADC5_a, m_ADC_a[5]);
	DDX_Text(pDX, IDC_6052E_ADC6_a, m_ADC_a[6]);
	DDX_Text(pDX, IDC_6052E_ADC7_a, m_ADC_a[7]);

	DDX_Text(pDX, IDC_6052E_ADC0_std, m_ADC_std[0]);
	DDX_Text(pDX, IDC_6052E_ADC1_std, m_ADC_std[1]);
	DDX_Text(pDX, IDC_6052E_ADC2_std, m_ADC_std[2]);
	DDX_Text(pDX, IDC_6052E_ADC3_std, m_ADC_std[3]);
	DDX_Text(pDX, IDC_6052E_ADC4_std, m_ADC_std[4]);
	DDX_Text(pDX, IDC_6052E_ADC5_std, m_ADC_std[5]);
	DDX_Text(pDX, IDC_6052E_ADC6_std, m_ADC_std[6]);
	DDX_Text(pDX, IDC_6052E_ADC7_std, m_ADC_std[7]);

	DDX_Text(pDX, IDC_STATIC_CH0, theInst->m_ADC_Description[0]);
	DDX_Text(pDX, IDC_STATIC_CH1, theInst->m_ADC_Description[1]);
	DDX_Text(pDX, IDC_STATIC_CH2, theInst->m_ADC_Description[2]);
	DDX_Text(pDX, IDC_STATIC_CH3, theInst->m_ADC_Description[3]);
	DDX_Text(pDX, IDC_STATIC_CH4, theInst->m_ADC_Description[4]);
	DDX_Text(pDX, IDC_STATIC_CH5, theInst->m_ADC_Description[5]);
	DDX_Text(pDX, IDC_STATIC_CH6, theInst->m_ADC_Description[6]);
	DDX_Text(pDX, IDC_STATIC_CH7, theInst->m_ADC_Description[7]);

	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlg_Channel_Meter, CDialog)
	//{{AFX_MSG_MAP(CDlg_Channel_Meter)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlg_Channel_Meter message handlers

BOOL CDlg_Channel_Meter::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	theInst->ADC_ScanSetup(8,&m_Scan_Chan[0]);

	for(int i = 0; i <8 ; i++)
	{
		m_6052_IO_State[i] = false;
		/////////////////////////m_6704_IO_State[i] = false;
	}

	// set update timer
	SetTimer(1,100,NULL); // JJS, second parameter is 100 ms

	UpdateData(false);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CDlg_Channel_Meter::OnTimer(UINT nIDEvent) 
{
	theInst->ADCread(8,m_Scan_Chan,m_ADC_data);
	theInst->DAQ_VScale(m_6052_Device,8,m_ADC_data,m_ADC_ddata);

	for (int i = 0; i < 8; i++)
	{
		m_ADC_a_array[i][counts] = m_ADC_ddata[i];
	}

	counts++;
	ticks++;

	CStatic *stat=NULL;
	
	if (ticks >= 1)
	{
		m_ADC0.Format("%.4f V",m_ADC_ddata[0]);
		m_ADC1.Format("%.4f V",m_ADC_ddata[1]);
		m_ADC2.Format("%.4f V",m_ADC_ddata[2]);
		m_ADC3.Format("%.4f V",m_ADC_ddata[3]);
		m_ADC4.Format("%.4f V",m_ADC_ddata[4]);
		m_ADC5.Format("%.4f V",m_ADC_ddata[5]);
		m_ADC6.Format("%.4f V",m_ADC_ddata[6]);
		m_ADC7.Format("%.4f V",m_ADC_ddata[7]);

		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC0);
		stat->SetWindowText(m_ADC0);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC1);
		stat->SetWindowText(m_ADC1);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC2);
		stat->SetWindowText(m_ADC2);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC3);
		stat->SetWindowText(m_ADC3);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC4);
		stat->SetWindowText(m_ADC4);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC5);
		stat->SetWindowText(m_ADC5);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC6);
		stat->SetWindowText(m_ADC6);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC7);
		stat->SetWindowText(m_ADC7);
		ticks = 0;
	}

	if (counts >= upperlimit)
	{
		double average[8];
		double std[8];
		for (int i = 0; i < 8; i++)
		{
			average[i] = 0;
			std[i] = 0;
		}

		for (int i = 0; i < 8; i++)
		{
			for (int c = 0; c < upperlimit; c++)
			{
				average[i] += m_ADC_a_array[i][c];
			}
			average[i] = average[i] / upperlimit;
			for (int c = 0; c < upperlimit; c++)
			{
				double diff = (average[i] - m_ADC_a_array[i][c]);
				std[i] += (diff * diff);
			}
			std[i] = sqrt(std[i] / upperlimit);

			m_ADC_a[i].Format("%.4f V",average[i]);
			m_ADC_std[i].Format("%.4f V",std[i]);
		}

		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC0_a);
		stat->SetWindowText(m_ADC_a[0]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC1_a);
		stat->SetWindowText(m_ADC_a[1]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC2_a);
		stat->SetWindowText(m_ADC_a[2]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC3_a);
		stat->SetWindowText(m_ADC_a[3]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC4_a);
		stat->SetWindowText(m_ADC_a[4]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC5_a);
		stat->SetWindowText(m_ADC_a[5]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC6_a);
		stat->SetWindowText(m_ADC_a[6]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC7_a);
		stat->SetWindowText(m_ADC_a[7]);

		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC0_std);
		stat->SetWindowText(m_ADC_std[0]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC1_std);
		stat->SetWindowText(m_ADC_std[1]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC2_std);
		stat->SetWindowText(m_ADC_std[2]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC3_std);
		stat->SetWindowText(m_ADC_std[3]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC4_std);
		stat->SetWindowText(m_ADC_std[4]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC5_std);
		stat->SetWindowText(m_ADC_std[5]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC6_std);
		stat->SetWindowText(m_ADC_std[6]);
		stat = (CStatic*)GetDlgItem(IDC_6052E_ADC7_std);
		stat->SetWindowText(m_ADC_std[7]);

		for (int i = 0; i < 8; i++)
		{
			for (int c = 0; c < upperlimit; c++)
			{
				m_ADC_a_array[i][c] = 0;
			}
		}
		counts = 0;
	}
}


	/////////////////////////////////////////
// THIS MUST GO AT END OF FILE
#endif // #ifdef HARDWARE_NI
/////////////////////////////////////////
Posted
Updated 27-Sep-12 12:26pm
v2
Comments
Sergey Alexandrovich Kryukov 27-Sep-12 18:25pm    
That happens, unfortunately. You see, this is not the complete project, so, the first thing to suspect is "race condition". If there more then one thread, by any chance?
--SA
AndrewG1231 27-Sep-12 19:15pm    
Yes, it seems so. The dialog is listed as the Main Thread, but there are several Worker Threads listed. The worker threads are catagorized as Win32 Thread and _TppWaiterpthread@4. Thanks for the fomating update, it seems the site has changed its look.
Sergey Alexandrovich Kryukov 27-Sep-12 18:27pm    
Code format fixed. Put the code in the tag <pre lang="C++">...</pre>
--SA
TRK3 27-Sep-12 19:03pm    
A couple of things to watch for:

1. When you compile for debug, Microsoft initializes uninitialized stack variables and heap data to specific values -- when you compile for release, those uninitialized values are whatever is in memory.

2. If you have static variables that are initialized to instances of some class, the constructors for those instances are called at startup -- but not in any specified order. The actual order is defined at compile/link time but isn't defined per the spec and seems to differ between debug and release code sometimes. So, if you have static objects where the order of construction matters, you have to instantiate them yourself after startup.

3. When you can't use the debugger, you can always resort to logging messages to a file. With enough logging statements, you can narrow down where your code is failing.
Sergey Alexandrovich Kryukov 27-Sep-12 19:39pm    
Good points, really. I described one more, but... look at the code. Such things don't work, usually; and when their work... it's worse than if they did not.
Please see my answer... this is sad...
--SA

1 solution

[After OP answered the question about possible multiple threads, see the comments to the question:]

So, more then one thread could be the case? OK. One of the known reasons of different results in different configurations (and anything different in environment as well) is the incorrect dependency on the order of execution, also know as under a "jargon" name "race condition". Generally, the code does not work correctly in all cases, but in some configurations it works by some random reason, because one thread comes to some point sooner then the other one. It creates an illusion that everything is correct. The change in configuration (or anything in the environment) changes timing, and this "random" illusion of correctness disappears.

(One trivial "non-fatal" example: imagine that one thread multiply one shared variable by 3, and another one adds 4 to the result. Imagine that the shared access is written correctly. Nevertheless, the final result depends on which thread was the first.)

Please see: http://en.wikipedia.org/wiki/Race_condition[^].

How to detect it? Difficult. And often the detection does not even makes sense, because the code should be designed accurately, and then such problems do not appear, so the design should be changed anyway, even without spotting the exact bug.

Besides, this is not the only possible reason for the problem. Now, the code does not show anything to suspect specifically, but has all the signs of the very, very illiterate programming, so I would not be surprised by any kind of problem. In particular, 12 identical fragments of code are repeated 8 times each. What, you don't know how to use the cycle? No, you use some. Don't know how to abstract out some values by making the function parameters? Maybe; the code shows only one function. In any non-nonsense programming, nothing is ever repeated in code.

This is not code at all, no sense to continue it in any way. What to do? I don't know; learn some basic programming, may be.

Sorry, not very optimistic conclusions, but what else could I possibly advise? Even if I was able to spot and fix your problem at once, it would not make your code acceptable.

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900