I have a projet with paths :
RootProjet
|--------Application-----Debug
| |--Release
|--------MyProjet
|--------wxWidgets-2.8.12
All compiled dll/exe/resouce (xrc)/translation(mo) are copied to Application/Debug (or release) by project post build steps
All is working fine.
WxWidgets is compiled with :
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=1 UNICODE=1 BUILD=debug VENDOR=%WX_WIDGETS_VENDOR_NAME% USE_XRC=1
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=1 UNICODE=1 BUILD=release VENDOR=%WX_WIDGETS_VENDOR_NAME% USE_XRC=1
The problem I have, is I cannot debug into wxWidgets source code, only inline code (into header only), all wxWidgets-2.8.12\src are not taken into account into the debugger.
How can I make gdb know where read source code of WxWidgets to be able to debug into this lib ?
I have see, into settings/compiler and debugger/debugger setting that there is a Debugger initialization commands that should run command at gdb start. What kind of command should I put ? Like "source $(#wx)\src" ?
Of course I link with debug dynamic library.
I think it is a path problem, gdb doesn't found where src are loated. I'm trying to add :
directory [i]"D:\Dev\TTGest\trunk\wxWidgets-2.8.12\lib\gcc_dll"[/i]
where the are compiled wxWidgets but no effect !
I know the source are located to "D:\Dev\TTGest\trunk\wxWidgets-2.8.12\src" When I write command I can see that all wxWidgets .cpp sources are located to "../../xxxxxxx"
The only thing that working is inline functions present into header files
Other idea ?
This is a gdb problem. There is no way C::B to use "..\..\src\common\string.cpp:200", sorry.
Please report this problem to the GDB devs.
Another options is to modify the wx build commands to use fullpaths, I don't know if this is possible.
@obf, I found a way (maybe a workaround)
1, I build wxWidgets library my self, with the command:
cd wxWidgets-2.8.12\build\msw
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=1 UNICODE=1 BUILD=debug
2, now, I create a wx app project under C::B, which link to wx debug library.
3, now, debug the app, set a breakpoint in the app's source.
with the "step into" command, I can trace into the wx's source (both header files and cpp files)
4, If I use c::b to add a break point in wx's cpp source file, like(Note, c::b use absolute path to set a breakpoint)
>>>>>>cb_gdb:
> break "D:/code/wxWidgets-2.8.12/src/common/string.cpp:158"
Then, gdb.exe will crash and showing a alert message box(application error)
5, If I add a break point manually, through the command below(send it from the debug-log edit control)
break ../../src/common/string.cpp:167
Breakpoint 2 at 0x66d89f57: file ../../src/common/string.cpp, line 167.
Then, this break point works and the app can stops there. But as this breakpoint is added manually, so debugger's breakpoint windows does not have a line about this breakpoint. But this "relative path breakpoint" works fine.
As a conclusion:
for debugging wx's source under Windows system
absolute path break point failed.
relative path break point works OK.
Is it possible that c::b can maintain a "relative path breakpoint", so we can smoothly debug the wx source under Windows. :D :D
take a time at how break point was added.
Mostly, in plugins\debuggergdb\debuggerstate.cpp
/ The compiler now uses absolute paths to source files so we don't need
// any absolute->relative filename conversions here anymore.
// Just adjust the path separators...
wxString DebuggerState::ConvertToValidFilename(const wxString& filename)
{
wxString fname = filename;
fname.Replace(_T("\\"), _T("/"));
return fname;
} // end of ConvertToValidFilename
//......
DebuggerBreakpoint* DebuggerState::AddBreakpoint(const wxString& file, int line, bool temp, const wxString& lineText)
{
wxString bpfile = ConvertToValidFilename(file);
// do we have a bp there?
int idx = HasBreakpoint(bpfile, line);
// if yes, remove old breakpoint first
if (idx != -1)
RemoveBreakpoint(idx, true);
// create new bp
// Manager::Get()->GetLogManager()->DebugLog(F(_T("DebuggerState::AddBreakpoint() : bp: file=%s, bpfile=%s"), file.c_str(), bpfile.c_str()));
DebuggerBreakpoint* bp = new DebuggerBreakpoint;
bp->type = DebuggerBreakpoint::bptCode;
bp->filename = bpfile;
bp->filenameAsPassed = file;
bp->line = line;
bp->temporary = temp;
bp->lineText = lineText;
bp->userData = FindProjectForFile(file);
AddBreakpoint(bp);
return bp;
}
So, from the comments, I can see that the c::b developers did a absolute path -> relative path conversion before, and later, it was removed. :D
blame the file, I found an old revision use this kind of code:
// when the project file is in a subdir, breaking with full filenames
// doesn't work.
// so we check this here and use the file's relative filename if possible.
wxString DebuggerState::ConvertToValidFilename(const wxString& filename)
{
wxString fname = filename;
fname.Replace(_T("\\"), _T("/"));
cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
if (!prj)
return fname;
bool isAbsolute = false;
#ifdef __WXMSW__
isAbsolute = (filename.GetChar(1) == _T(':')) ||
filename.GetChar(0) == _T('/') ||
filename.GetChar(0) == _T('\\');
#else
isAbsolute = filename.GetChar(0) == _T('/') ||
filename.GetChar(0) == _T('~');
#endif
if (isAbsolute)
{
ProjectFile* pf = prj->GetFileByFilename(UnixFilename(filename), false, true);
if (pf)
{
fname = pf->relativeFilename;
fname.Replace(_T("\\"), _T("/"));
}
else
{
// for foreign files, we still should use a relative path
//~ wxFileName f(filename);
//~ f.MakeRelativeTo(prj->GetBasePath());
//~ fname = f.GetFullPath();
}
}
return fname;
}
So, I think if the absolute file path is:
see the debug log:
> step
wxStringBase::InitWith (this=0x23f9b4, psz=0x41221c L"wxWidgets 2.8.12", nPos=0, nLength=4294967295) at ../../src/common/string.cpp:158
D:\code\wxWidgets-2.8.12\build\msw/../../src/common/string.cpp:158:4882:beg:0x66d89ef2
>>>>>>cb_gdb:
absolute file path
D:\code\wxWidgets-2.8.12\src\common\string.cpp
then we supply a base file path
D:\code\wxWidgets-2.8.12\build\msw
Then, we should give a relative file:
../../src/common/string.cpp
Is it easy to calculate? :D
By the way: from the debug log, you can see that the "step" command works fine. :D
Ok, here is my hard-coded change to let setting break point on wxWidgets 's source.
wxString DebuggerState::ConvertToValidFilename(const wxString& filename)
{
wxString fname;
if( filename.StartsWith(_T("D:\\code\\wxWidgets-2.8.12"))
&& filename.EndsWith(_T(".cpp")))
{
wxFileName f(filename);
wxString base = _T("D:\\code\\wxWidgets-2.8.12\\build\\msw");
f.MakeRelativeTo(base);
fname = f.GetFullPath();
}
else
fname = filename;
fname.Replace(_T("\\"), _T("/"));
return fname;
} // end of ConvertToValidFilename
So, the final step is: If we supply database which contains all the candidate "base" file paths, we can solve the problem. :D
Any ideas???
Ok, I also found that this post (http://forums.codeblocks.org/index.php/topic,13306.msg89692.html#msg89692) has some analysis on gdb source.
I just dig into the gdb source and found that in the file "symtab.c" and in function:
/* Check for a symtab of a specific name; first in symtabs, then in
psymtabs. *If* there is no '/' in the name, a match after a '/'
in the symtab filename will also work. */
struct symtab *
lookup_symtab (const char *name)
{
...
I will report to gdb maillist about this issue. Hopefully some one interests in gdb can look into it.
thanks.
Lets see if they approve it and you have the nerves to fill in the FSF Copyright assignment :)
Aha, indeed nerves :D.
By the way, I have create another patch to let the backtrace showing the full file name when debugging wx debug library. This way, it can fix the problem I post here: http://forums.codeblocks.org/index.php/topic,14792.msg99218.html#msg99218
see:
> bt 30
#0 test_debug_wx_libFrame::OnAbout (this=0xb77570, event=...) at f:\cb\test_code\test_debug_wx_lib\test_debug_wx_libmain.cpp:103
#1 0x66d41acc in wxAppConsole::HandleEvent (this=0xb69fa0, handler=0xb77570, func=(void (wxEvtHandler::*)(wxEvtHandler * const, wxEvent &)) 0x401e66 <test_debug_wx_libFrame::OnAbout(wxCommandEvent&)>, event=...) at d:\code\wxwidgets-2.8.12\src\common\appbase.cpp:322
#2 0x66dc1107 in wxEvtHandler::ProcessEventIfMatches (entry=..., handler=0xb77570, event=...) at d:\code\wxwidgets-2.8.12\src\common\event.cpp:1239
#3 0x66dc1734 in wxEvtHandler::SearchDynamicEventTable (this=0xb77570, event=...) at d:\code\wxwidgets-2.8.12\src\common\event.cpp:1421
#4 0x66dc12ad in wxEvtHandler::ProcessEvent (this=0xb77570, event=...) at d:\code\wxwidgets-2.8.12\src\common\event.cpp:1297
#5 0x66e7be55 in wxFrameBase::ProcessCommand (this=0xb77570, id=101) at d:\code\wxwidgets-2.8.12\src\common\framecmn.cpp:224
#6 0x66e248f8 in wxFrame::HandleCommand (this=0xb77570, id=101, cmd=0, control=0x0) at d:\code\wxwidgets-2.8.12\src\msw\frame.cpp:974
#7 0x66e24c1e in wxFrame::MSWWindowProc (this=0xb77570, message=273, wParam=101, lParam=0) at d:\code\wxwidgets-2.8.12\src\msw\frame.cpp:1051
#8 0x66e05ad6 in wxWndProc (hWnd=0x12052c, message=273, wParam=101, lParam=0) at d:\code\wxwidgets-2.8.12\src\msw\window.cpp:2618
#9 0x7e418724 in USER32!GetDC () from C:\WINDOWS\system32\user32.dll
#10 0x0012052c in ?? ()
#11 0x00000111 in ?? ()
warning: (Internal error: pc 0x110 in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x110 in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x110 in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x64 in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x64 in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x64 in read in psymtab, but not in symtab.)
#12 0x00000065 in ?? ()
#13 0x00000000 in ?? ()
>>>>>>cb_gdb:
Now, double click on the call stack window will open the associated wx source file.
here is the patch
569a0e63c18e2fe9dfa82e7feaf51b191669ded4
gdb/stack.c | 14 ++++++++++----
1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/gdb/stack.c b/gdb/stack.c
index 0888b69..9635e57 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -835,15 +835,21 @@ print_frame (struct frame_info *frame, int print_level,
ui_out_text (uiout, ")");
if (sal.symtab && sal.symtab->filename)
{
+ const char *fullname;
annotate_frame_source_begin ();
ui_out_wrap_hint (uiout, " ");
ui_out_text (uiout, " at ");
annotate_frame_source_file ();
- ui_out_field_string (uiout, "file", sal.symtab->filename);
- if (ui_out_is_mi_like_p (uiout))
- {
- const char *fullname = symtab_to_fullname (sal.symtab);
+
+ fullname = symtab_to_fullname (sal.symtab);
+ if (fullname != NULL)
+ ui_out_field_string (uiout, "file", fullname);
+ else
+ ui_out_field_string (uiout, "file", sal.symtab->filename);
+
+ if (ui_out_is_mi_like_p (uiout))
+ {
if (fullname != NULL)
ui_out_field_string (uiout, "fullname", fullname);
}