|
There was no pointer bugs at all. I declared no pointers, but the structure-
RECT lrct.
And some local variables too.
Compiler allocated them in a stack and added some temporary variables. In a such way:
_lrct$=-212;
tv5476=-204;
It is a time bomb, which might explode in any time. And it did. That's all. So simple.
|
|
|
|
|
a_matseevsky wrote: I declared no pointers
You have a C++ application and do not use pointers ANYWHERE in the application?
(Again is has NOTHING to do with pointers directly associated with the code where you think the bug is.)
|
|
|
|
|
I do not think where the bug is. I know it. I know exactly where variables was incorrectly allocated in stack and which command overwrote data. What are you talking about pointers? I do use them, of course, but they was not the cause. It is pointless to discuss here what might happens, ignoring all available info.
|
|
|
|
|
a_matseevsky wrote: What are you talking about pointers?
Either you didn't read what I said in my previous replies or didn't understand what I said.
|
|
|
|
|
jschell wrote:
Either you didn't read what I said in my previous replies or didn't understand what I said.
I did. It was you who did not read (or did not understand what he read). Look at quotes from your messages:
I want to emphasize again that the pointer bug could be anywhere. The behavior you are seing is a symptom not a cause.
Don't know how to state this more clearly.
Either you have a pointer bug or there is a compiler problem. If the latter then reducing the code will demonstrate it AND changing code far from it and unrelated will NOT impact it.
Conversely if the former then you will not be able to reduce it because the code that you are looking at is not the source of the problem.
You have a C++ application and do not use pointers ANYWHERE in the application?
(Again is has NOTHING to do with pointers directly associated with the code where you think the bug is.)
There are empty words about what might happens. Nothing common with real situation.
Compiler placed temporary variable too close to another one and when the tv5476 was used, RECT structure was partially overwritten. So simple. It is no pointer's problem- the compiler's one.
|
|
|
|
|
a_matseevsky wrote: I did. It was you who did not read
I read the following which you posted.
"but occurred again after some insignificant change in code (which was made far from the procedure, where problem occurred!)"
Presumably you do not understand what that statement means in terms of what I said and in terms of what you are claiming.
|
|
|
|
|
jschell wrote: I read the following which you posted.
"but occurred again after some insignificant change in code (which was made far from the procedure, where problem occurred!)"
Presumably you do not understand what that statement means in terms of what I said and in terms of what you are claiming.
I do know. Assume you have a pointer, which points yo some array. Sentence like *(p+k)=a may cause a problem if k is greater than array's size. This is the typical problem, associated with pointers. In my case all was different. What I wrote clearly meant that I had changed the source C++ code, then compiler built executable and the problem disappeared. Then I changed code again, recompiled it and the problem occurred again. That's just what I meant. Where do you see pointers? Moreover, at that very moment when I wrote aforementioned text, I did not know, where the problem was. I only noticed, that code worked correctly when I had excluded max and min. But problem occurred again! The most remarkable was the fact that I did not change suspicious procedure- changes had made far from it. But if one single line of code has been changed, compiler compiles the whole file with this line of code. I got compiler to build release with debug info and ran procedure under debugger. This was how I found where the problem is- I noticed that very command, which overwrote RECT structure and immediately found, why it happened. That's all.
|
|
|
|
|
a_matseevsky wrote: Where do you see pointers?
Explaining it again...
- Pointer errors can show up far from the code where the bug actually is.
- Pointer errors do NOT automatically show up. An application can have a pointer error for years and run without problem.
- Changing code changes the execution path. BECAUSE of that a pointer error that previously did not impact the application can now impact the application.
Feel free to explain yourself, excluding pointer errors, why the code you change some where completely different is now causing this compiler bug to show up now.
|
|
|
|
|
I explained you point by point where the problem is and how it occurred. Despite of it, you repeat your ideas about pointers. It is rather ridiculous, because I have the source code, generated asm file and result of disassembling of exe file (which can be compared with the asm file, generated by compiler). Finally, I can (and I did) run my exe file under debugger. You have no such options at all. Under such circumstances it is very strange idea to try to explain me not what actually happened, but what might happen!
|
|
|
|
|
The purpose of the code is to convert an XPS file to PDF using the external GhostXPS converter program (gxps.exe).
It's a fairly simple process and works flawlessly with everything tested up to Windows 8. It has been tested on XP, various flavors of Windows 7 and Server 2008 R2. Even using the same instructions from cmd line in Windows 8 is successful.
for clarity:
"path" is the entire path where gxps.exe is installed.
"filename" is the complete path of the xps file to convert
"retStr" is the complete path of the pdf file as converted (same as filename only with a pdf extension).
The file paths of filename and retStr are C:\Users\"username"\AppData\Local\Temp directory so permission issues should not be a concern.
Code follows:
CString progName( path + _T("gxps.exe ") );
sParam.Format(_T("-sDEVICE=pdfwrite -sOutputFile=%s -dNOPAUSE %s"), retStr, filename );
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.hwnd = NULL;
sei.lpVerb = NULL;
sei.lpFile = progName;
sei.lpParameters = sParam;
sei.lpDirectory = NULL;
sei.nShow = SW_HIDE;
sei.hInstApp = NULL;
if ( ShellExecuteEx(&sei) )
{
::WaitForSingleObject(sei.hProcess, INFINITE);
}
CloseHandle(sei.hProcess);
Curiously, the gxps program executes without indicated error. The result of execution is "42" which according to the MSDN docs is a success code. However the result is always a blank 760 byte pdf with no content. Breakpoints indicate the XPS is completely valid before conversion.
I've never seen a command line program return a different result when executed from cmd or ShellExecuteEx and am completely baffled.
Does anyone have any ideas on what is happening here or has anyone else experienced a similar problem with ShellExecuteEx?
Thanks in advance for any assistance.
|
|
|
|
|
Have you tried running filemon to see if you get any errors on that input file?
I'm guessing - it may be an issue with the input file being locked or some other security issue ?
|
|
|
|
|
Thank you for responding.
I ran Process Monitor(current version of Filemon) per your suggestion. Indeed it produced some curious results.
I compared Win 7 processes with 8 and noticed the file IO is at least described differently between the two.
With 7 ReadFile and WriteFile operations are shown.
With 8 these operations are called FASTIO_READ and FASTIO_WRITE.
Intermixed with the FASTIO_WRITE operations with SUCCESS result there are a curious mix of FAST IO DISALLOWED results. I am unsure what this may indicate.
Apparently some write operations were permitted while other write operations were not. This would be consistent with the end result but there is no indication why some of the writes were disallowed. There was also no general failure to the gxps process when these were encountered.
Hopefully this sparks someone's interest with more knowledge of the win 8 architecture than mine and can help lead to a solution.
|
|
|
|
|
This is only a guess - but I have a feeling the input file (XPS) may be buffered/cached and not completely written to disk yet when you try to open it with GS.
Just before your shellexecute setup - why don't you try to open the xps file low level in non shared mode and then close it? You may notice what is going on with that xps file via errors. The idea here is to see if you can open it - and view all the contents (and then close it after of course).
Your output file is not the problem - it's your input that's the issue....
|
|
|
|
|
Rene Pilon wrote: The idea here is to see if you can open it - and view all the contents (and then close it after of course).
Your guess was right on. It is definitely a problems with the input file.
I added code to open and display the xps just prior to conversion. The default win 8 reader was unable to open the file: "There is a problem with the file format".
This indicates to me that the xps is not fully formed yet for whatever reason.
A great help, thank you.
I'll try to see what's holding up the xps process and let you know the resolution.
|
|
|
|
|
The file produced by MS XPS printer is inaccessible to even file copy.
Yet, the very same xps file can be attached and sent via email.
I attempted to have the program copy the original file after it was sent to email since it is obviously closed and ready for MAPI to use. The emailed version produced a perfectly usable attachment. But then, CopyFile results in ERROR_ACCESS_DENIED. Setting file attribute to "normal" results in the same inability to use the file.
I used:
if ( CopyFile(original.xps,new.xps,TRUE) )
The Email process is making a copy of the file, so why can't CopyFile? Any ideas? I'm at a loss why this xps is so resistant.
|
|
|
|
|
What happens when you run that directly in a command window?
Veni, vidi, abiit domum
|
|
|
|
|
Thanks for responding,
When run from the command line it executes perfectly.
|
|
|
|
|
I want to define a 3D array like this:
Type ary[3][6][7];
Is it possible in C++? I'm using Visual Studio 2010, Boost library is not allowed. If it's possible, please tell me how to initialize each dimension?
|
|
|
|
|
You cannot do that since an array must be typed at its declaration, and that defines the type of each element in the array. You could declare an array of unsigned int and then use casts to set different types in some cells, but it would still be somewhat confusing. Perhaps you should explain what problem you are trying to solve.
Veni, vidi, abiit domum
|
|
|
|
|
+5... when you need to support multiple types, use the largest (byte-wise) and cast... but yes, it may be a bit confusing to others reading the code
|
|
|
|
|
Thanks. Personally, I think it's a daft idea.
Veni, vidi, abiit domum
|
|
|
|
|
You seem to understand the question as storing elements of different types, but I think the request is about using alternate types of index values. See my response.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
Stefan_Lang wrote: You seem to understand the question as storing elements of different types Well that's what the OP asked for.
Veni, vidi, abiit domum
|
|
|
|
|
(Wathever you want to do) it doesn't look possible.
Veni, vidi, vici.
|
|
|
|
|
If you mean that the type of the index value needs to be different, then the only way to achieve this is defining your own subscript operator overloads, and that means you need to define your own array class(es).
Here's an example of how to define and use such overloads to create a 3D array like you describe:
enum EMyColors {
C_RED,
C_GREEN,
C_YELLOW
};
template <class Base, int n_elements>
class CMyArray1 {
std::vector<Base> values;
public:
CMyArray1() : values(n_elements) {} Base& operator[](const wchar_t wc) {
size_t index = wc - L'a'; assert(index < values.size());
return values[index];
}
};
template <class Base, int n_vectors, int n_elements>
class CMyArray2 {
std::vector< CMyArray1<Base, n_elements> > vectors;
public:
CMyArray2() : vectors(n_vectors) {} CMyArray1<Base, n_elements>& operator[](int i) {
size_t index = i - 1; assert(index < vectors.size());
return vectors[index];
}
};
template <class Base, int n_arrays, int n_vectors, int n_elements>
class CMyArray3 {
std::vector< CMyArray2<Base, n_vectors, n_elements> > arrays;
public:
CMyArray3() : arrays(n_arrays) {} CMyArray2<Base, n_vectors, n_elements>& operator[](EMyColors c) {
size_t index;
switch (c) {
case C_RED:
index = 0;
break;
case C_GREEN:
index = 1;
break;
default:
index = 2;
break;
}
return arrays[index];
}
};
int foo() {
CMyArray3<int, 3, 5, 8> my_array;
my_array[C_GREEN][3][L'c'] = 17;
}
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|