Showing posts with label Debug. Show all posts
Showing posts with label Debug. Show all posts

2008-03-13

關於使用DirectShow 在 debug mode 產生Protection Error

Ref: http://jewelry-wolf.spaces.live.com/blog/cns!9041D1290EF347B0!279.entry

恩,我先描述一下情况,
我自己开发了一个Soure Filter,从网络上获取多媒体并且本地解码播放
内置使用的是WMV解码器,输出的OutputPin直接连接Render Filter,
原来一切运行正常,
但是最近切换到了2005的平台结果突然出现了问题,
一直报“protection error: win32 debugger detected!"
说什么我有softice之类的东西

现在问题解决了,
其实,上述描述的东西都与解决问题无关,
这个问题的出现一定是在该进程中关于debugger检测的代码
呢么既然原来运行正常,为何现在会出错呢?

很简单,呵呵
既然是directshow,那么就有可能发生其他的filter或恶意或无意的进入你的graph
然后它负责报错

最常见的情况也就是我自己碰到的情况,
这个罪魁祸首的filter就是nero的filter
加入代码查看一下后台的出错源,就是ahead公司的代码
可以发现nero的filter由于把merit值设太高了,
所以常常侵入正常的graph

遇到这种情况不用慌张,首先你与nero肯定可以共存,
因为检测debugger并不会影响无debugger代码的运行
其次如果需要调试那就卸载nero把,

==
問題出在 Nero,
因為 Nero 裡的 filter 的 merit 值設的過高。
移除 Nero 後就可以 debug

2008-01-30

error LNK2001: unresolved external symbol

FrameGrabberDemoDlg.obj : error LNK2001: unresolved external symbol _IID_ISampleGrabber
FrameGrabberDemoDlg.obj : error LNK2001: unresolved external symbol _CLSID_SampleGrabber
Debug/FrameGrabberDemo.exe : fatal error LNK1120: 2 unresolved externals

Here is the solution:

1. Open the VS-project in Samples\C++\DirectShow\BaseClasses
2. Compile it as Win32 Release
3. Copy the Release\Strmbase.lib file into your DirectX SDK\lib folder
4. Add #pragma comment(lib,"strmbase.lib") below the #include directives in your header file

--
My solution :
在 project setting 中的 Link 加入 Strmbase.lib

2007-09-03

Visual C++ Debugging: Why does program work in debug mode, but fail in release mode?

Ref: http://www.codeguru.com/forum/showthread.php?t=269905

Q: Why does program work in debug mode, but fail in release mode?

A: First of all, there is no such thing as 'debug mode' or 'release mode'. The VC++ IDE offers the possibility to define configurations which include a set of project settings (like compiler / linker options, output directories etc.) When a project is created using AppWizard, you get two default configurations: "Win32 Debug" and "Win32 Release". These are just convenient starter configurations with several preset options which are suitable for typical debug builds or release builds respectively, but you are by no means restricted to those settings. Actually, you can modify those configurations, delete them, or create new ones. Now let's see what the two default configurations typically include and what distinguishes them:

Win32 Debug:
* Subdirectory 'Debug' used for temporary and output files
* Preprocessor symbol _DEBUG defined
* Debug version of the runtime libraries is used
* All compiler optimizations turned off
* Generate debug info

Win32 Release:
* Subdirectory 'Release' used for temporary and output files
* Preprocessor symbol NDEBUG defined
* Release version of the runtime libraries is used
* Various compiler optimizations turned on
* Generate no debug info


There are a few other differences, but these are the most important ones. Now, what's the first implication of all this? That, as opposed to a common misunderstanding, you can debug a release build. Just go to 'Project -> Settings', choose the Win32 Release configuration, tab 'C/C++', 'General' and set 'Debug Info' to 'Program Database'. Then go to the tab 'Linker', and turn on 'Generate Debug Info'. If you rebuild your project now, you will be able to run it in the debugger. Regardless of whether your program crashes or just doesn't behave as expected, running it in the debugger will show you why. Note however, that due to optimizations turned on in the release build, the instruction pointer will sometimes be off by a few code lines, or even skip lines altogether (as the optimizer didn't generate code for them). This shouldn't be a concern, if it is, turn off optimizations.

When debugging your release build this way, you will probably discover that at a certain point during execution, a variable has a different value in the release and in the debug build, causing the differing behaviour. And if you go back and see where the value of that variable is set, you will most probably find out that it isn't: You simply forgot to initialize that variable. The reason why the debug build seemed to work is that the debug version of the runtime library initializes dynamic memory and stack variables to known values (in order to track down memory allocation and overwrite errors), while the release version of the runtime library doesn't. This is by far the most frequent single cause for different behaviour between debug and release builds, so chances are good that this fixes your problem (and for the future, remember to always initialize your variables).

If uninitialized variables were not the cause of your problem, let's look at the next possible difference between debug and release builds: The preprocessor symbols _DEBUG and NDEBUG. If you have any code inside an #ifdef _DEBUG / #endif block, it will not be contained in a release build. What's worse, the dependency of those symbols can be hidden inside other macros. A typical candidate for this is ASSERT: It expands to the assertion testing code if _DEBUG is defined, and to nothing if it is not. Therefore, be careful to have no code with side effects inside an ASSERT macro. For example, the following code will work in a debug build, but fail in a release build:

code:
CSomeDialog dlg;
ASSERT(dlg.Create(IDD_SOME_DLG));
dlg.ShowWindow(SW_SHOW);


As a rule, never put code which needs to be executed inside an ASSERT. (A side note: Conditions which can be expected to fail at runtime, like the 'Create()' call in the example, should never be tested with ASSERTs anyway. Assertions are a tool to assert pre- and postconditions regarding your code, not runtime error conditions.)

At this point, you have most probably found out why your code failed in the release build. If not, this might be one of the very rare cases where the compiler optimizations caused your code to behave differently (the VC++ compiler had several optimizer bugs in the past, and I doubt they have all been fixed). To exclude this, first turn all the optimizations off (Project -> Settings, tab 'C/C++', category 'Optimizations', option 'Disable (Debug)'). If your code works now, selectively turn optimization options on until you found the culprit. Simply leave it turned off, or upgrade to a newer version of the compiler (or install the most recent service packs) which might hopefully fix that bug.

This should help you get your release build running in most of the situations. For a more in-depth discussion about the differences between debug and release builds, see the excellent article Surviving the Release Version
====================================================================================

Incorrectly prototyped message handlers !

Thats another big goof up everyone makes atleast once ...
In the debug build, if you have incorrect message handler signatures this doesnt cause any problems.

But MFC does a couple of naughty type casts in the message map macros. So when you build the same code in release mode, you are gauranteed to run into trouble. As soon as your message handler returns, your stack frame gets trashed and you get a neat little GPF.

debug and release mode

作者 littleshan (我要加入劍道社!) 看板 C_and_CPP
標題 Re: [問題] debug and release mode
時間 Tue May 30 23:59:21 2006
───────────────────────────────────────

※ 引述《Amati (Amati)》之銘言:
: 請問一下各位前輩
: 在我寫好的程式中用debug mode可以成功執行
: 但是當我切換到release mode時卻會發生程式終止
: 而程式終止的原因應該是記憶體配置錯誤 就是陣列或指標over range那一種
                        ^^^^^^^^^^^^^^

: 但是在debug mode下 我明明執行的很爽阿
debug mode 編出的程式可能保留了一些沒用到的變數
成為非法記憶體存取的犧牲者
而 release mode 中這些變數會被去掉
因此亂動記憶體馬上會讓程式掛掉

當然也可能是其它原因
但可以確定的是
debug mode 能跑是你運氣好

還有另一種情況是你不自覺地寫出一些不能開 optimization 的程式碼
像這樣:

#include
using namespace std;
int main()
{
float f = 0.0f;
*(int*)(&f) = 0x3F800000; // IEEE754 representation for 1.0f
cout << f << endl;
}

若用我的 compiler (gcc-4.0.3) 編
不開最佳化結果是 1
開最佳化結果是 0
當然這不是 gcc 的問題,而是 code 本身的問題 (原因請見 gcc 的 faq)

2007-08-26

fatal error C1010: unexpected end of file while looking for precompiled header directive

fatal error C1010: unexpected end of file while looking for precompiled header directive

如果cpp設定有使用Precompiled header, 你就必須在.cpp #include 相關的head
加上#include "stdafx.h"

2007-08-08

LINK : warning LNK4089: all references to "xxx.dll" discarded by /OPT:REF

[copy from https://dirty.csie.org/mt/archives/000108.html]

For example:

LINK : warning LNK4089: all references to "GDI32.dll" discarded by /OPT:REF

The warning means that your program contains functions that call GDI, but the functions are never called, so the link to GDI is never actually used. For exmaple, this program will raise the
warning:

void CallGDI()
{
GetStockObject(WHITE_BRUSH);
}

int main(int argc, char**argv)
{
// notice that this function never calls the CallGDI function
return 1;
}

The linker is saying, "Um, you wrote some functions that use GDI, but you never called those functions, so I'm not sure what you're trying to do here."

This is just the compiler trying to help you create a smaller program since you are not using the GDI functions anyway. If you want to avoid the message, use /OPT:NOREF but it will leave you with a larger executable.

PS. This is of course documented under the /OPT keyword.

You can prevent the warning message by adding the following to your linker options.

/IGNORE:4089