* [patch] avoid the crash of gdb+pretty printer on initialized local variables
[not found] <4ED379D8.4060808@gmail.com>
@ 2011-12-02 4:32 ` asmwarrior
2011-12-02 16:51 ` Tom Tromey
0 siblings, 1 reply; 9+ messages in thread
From: asmwarrior @ 2011-12-02 4:32 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2239 bytes --]
Hi, gdb developers.
When debugger with python pretty printer, I sometimes get the gdb crash
when I try to show the value of uninitialized local variables. As you
know, an uninitialized local variable can contain some random value, so
the pretty printer try to interpret those values, and can cause the gdb
to an long loop or crash.
The patch is just a work-around/hack to handle this problem.
I just first check if the symbol is a local variable, and then check the
current line SAL is smaller than the variable's declaration line. If
true, which means this local variable is OK to show, if not, than I just
skip it.
The first patch try to deal with the "info locals" problem, the local
variable defined later than the current line will be skipped.
The second patch try to skip/filter the same local variables.
For example:
void fun()
{
wxString *psty = (wxString*) NULL;
wxString wxStr(L"wxString");
wxStr += L" Value";
std::string stdStr("std::string");
stdStr.append(" value");
std::map<int, std::string> m;
m[0] = "000";
m[1] = "111"; //break point here, we stop here
wxString& wxStrRef = wxStr;
wxStrRef += L" Ref";
std::string& stdStrRef = stdStr;
stdStrRef += " Ref";
std::list<std::string> l = {"a", "b", "c"};
std::vector<std::string> v = {"a", "b", "c"};
std::queue<std::string> q;
q.push("a");
q.push("b");
std::stack<std::string> s;
s.push("a");
s.push("b");
}
Now, you have stopped on the breakpoint. the local variable "l,v,q" is
after the breakpoint line.
If you try to run "print v", or "info locals", then gdb will crash (I'm
using gdb cvs build under WindowsXP, mingw, python 2.7)
I believe that this patch will not be applied, because it is just a
hack, right?
I just also CC to mingw maillist hope they have some interests.
Basically, gdb should alive with out any crash in any condition, but
sometimes, I think a workaround is also necessary. I have see that in
QTcreator, when they want to show the contents of a stl container, it do
many sanity check. like:
The length of the std::vector should be positive, and it's size should
be limited.
Also many other sanity checks
asmwarrior
ollydbg from codeblocks forum
[-- Attachment #2: avoid_uninitial_crash_stack.patch --]
[-- Type: text/x-c++, Size: 732 bytes --]
gdb/stack.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/gdb/stack.c b/gdb/stack.c
index c51832e..317570d 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1825,6 +1825,10 @@ iterate_over_block_locals (struct block *b,
{
struct dict_iterator iter;
struct symbol *sym;
+ struct frame_info *frame;
+ struct symtab_and_line sal;
+ frame = get_selected_frame (NULL) ;
+ find_frame_sal (frame, &sal);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
@@ -1836,6 +1840,8 @@ iterate_over_block_locals (struct block *b,
case LOC_COMPUTED:
if (SYMBOL_IS_ARGUMENT (sym))
break;
+ if(sym->line>= sal.line)
+ break;
(*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data);
break;
[-- Attachment #3: avoid_uninitial_crash_print.patch --]
[-- Type: text/x-c++, Size: 1621 bytes --]
gdb/symtab.c | 29 +++++++++++++++++++++++++++--
1 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 65e4248..2047351 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1730,6 +1730,8 @@ lookup_block_symbol (const struct block *block, const char *name,
{
struct dict_iterator iter;
struct symbol *sym;
+ struct frame_info *frame;
+ struct symtab_and_line sal;
if (!BLOCK_FUNCTION (block))
{
@@ -1739,7 +1741,20 @@ lookup_block_symbol (const struct block *block, const char *name,
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
SYMBOL_DOMAIN (sym), domain))
- return sym;
+ {
+ if(SYMBOL_CLASS (sym)==LOC_LOCAL
+ ||SYMBOL_CLASS (sym)==LOC_REGISTER
+ ||SYMBOL_CLASS (sym)==LOC_COMPUTED)
+ {
+ frame = get_selected_frame (NULL) ;
+ find_frame_sal (frame, &sal);
+ if( block == get_frame_block (frame, 0)
+ && sym->line >= sal.line)
+ return NULL;
+ }
+ return sym;
+ }
+
}
return NULL;
}
@@ -1763,7 +1778,17 @@ lookup_block_symbol (const struct block *block, const char *name,
sym_found = sym;
if (!SYMBOL_IS_ARGUMENT (sym))
{
- break;
+ if(SYMBOL_CLASS (sym)==LOC_LOCAL
+ ||SYMBOL_CLASS (sym)==LOC_REGISTER
+ ||SYMBOL_CLASS (sym)==LOC_COMPUTED)
+ {
+ frame = get_selected_frame (NULL) ;
+ find_frame_sal (frame, &sal);
+ if(block == get_frame_block (frame, 0)
+ && sym->line >= sal.line)
+ sym_found = NULL;
+ }
+ break;
}
}
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] avoid the crash of gdb+pretty printer on initialized local variables
2011-12-02 4:32 ` [patch] avoid the crash of gdb+pretty printer on initialized local variables asmwarrior
@ 2011-12-02 16:51 ` Tom Tromey
2011-12-04 1:41 ` asmwarrior
0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2011-12-02 16:51 UTC (permalink / raw)
To: asmwarrior; +Cc: gdb-patches
>>>>> ">" == ext asmwarrior <asmwarrior@gmail.com> writes:
>> When debugger with python pretty printer, I sometimes get the gdb crash
>> when I try to show the value of uninitialized local variables.
gdb should not crash.
Is this that mingw-builds-only problem that keeps popping up?
I forget, something to do with not using the right gcc flag?
>> The patch is just a work-around/hack to handle this problem.
>> I just first check if the symbol is a local variable, and then check the
>> current line SAL is smaller than the variable's declaration line. If
>> true, which means this local variable is OK to show, if not, than I just
>> skip it.
This is not ok. First, due to optimization, lines can be smeared
around, leading to the wrong result here. Second, a variable can be
trashed for many reasons, like other bugs in the code. In this second
case it is still unacceptable for gdb to crash.
In theory the existing code will detect memory access errors and cause
printing to stop early. If you have a case where this doesn't work
properly, make a reproducible test case.
>> void fun()
>> {
>> wxString *psty = (wxString*) NULL;
>> wxString wxStr(L"wxString");
>> wxStr += L" Value";
>> std::string stdStr("std::string");
>> stdStr.append(" value");
>> std::map<int, std::string> m;
>> m[0] = "000";
>> m[1] = "111"; //break point here, we stop here
This kind of thing is generally not very reproducible. It relies on
compiler differences, libraries, runtime differences. Something that is
plain C and just writes bad values directly would be better.
>> If you try to run "print v", or "info locals", then gdb will crash (I'm
>> using gdb cvs build under WindowsXP, mingw, python 2.7)
>> I believe that this patch will not be applied, because it is just a
>> hack, right?
I think it is actively wrong in some cases.
>> Basically, gdb should alive with out any crash in any condition, but
>> sometimes, I think a workaround is also necessary. I have see that in
>> QTcreator, when they want to show the contents of a stl container, it do
>> many sanity check. like:
>> The length of the std::vector should be positive, and it's size should
>> be limited.
>> Also many other sanity checks
Adding a sanity check to the vector printer would probably be ok.
That is maintained in libstdc++.
Checking the size is probably not ok. gdb lazily fetch sub-objects; and
respects length limits like "set print elements" or the MI equivalent
for dynamic varobjs. Having the printer check that the length is "short
enough" is generally wrong for this reason.
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] avoid the crash of gdb+pretty printer on initialized local variables
2011-12-02 16:51 ` Tom Tromey
@ 2011-12-04 1:41 ` asmwarrior
[not found] ` <CAF4KFGqyz0WMWWJt9x1HZpO+urMo9jJLyudcRrHxUTqJf8mvqA@mail.gmail.com>
2011-12-05 21:51 ` Tom Tromey
0 siblings, 2 replies; 9+ messages in thread
From: asmwarrior @ 2011-12-04 1:41 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On 2011-12-3 0:50, Tom Tromey wrote:
>>>>>> ">" == ext asmwarrior <asmwarrior@gmail.com> writes:
>
>>> When debugger with python pretty printer, I sometimes get the gdb crash
>>> when I try to show the value of uninitialized local variables.
>
> gdb should not crash.
>
> Is this that mingw-builds-only problem that keeps popping up?
Thanks for the reply and comments.
Yes, I guess it is only the mingw gdb problem, I have no linux at the moment, but in the Codeblocks' forum, I hear no Linux users complained this kind of crash of gdb on linux.
> I forget, something to do with not using the right gcc flag?
My app was build with -O0 and -g, no extra flag is used.
>
>>> The patch is just a work-around/hack to handle this problem.
>>> I just first check if the symbol is a local variable, and then check the
>>> current line SAL is smaller than the variable's declaration line. If
>>> true, which means this local variable is OK to show, if not, than I just
>>> skip it.
>
> This is not ok. First, due to optimization, lines can be smeared
> around, leading to the wrong result here. Second, a variable can be
> trashed for many reasons, like other bugs in the code. In this second
> case it is still unacceptable for gdb to crash.
>
> In theory the existing code will detect memory access errors and cause
> printing to stop early. If you have a case where this doesn't work
> properly, make a reproducible test case.
Yes, agreed, as I said, it is only a work around. I create this patch to only avoid the crash of gdb under mingw.
The sample code below can easily cause the crash under mingw+gdb+python pretty printer.
>
>>> void fun()
>>> {
>>> wxString *psty = (wxString*) NULL;
>>> wxString wxStr(L"wxString");
>>> wxStr += L" Value";
>>> std::string stdStr("std::string");
>>> stdStr.append(" value");
>>> std::map<int, std::string> m;
>>> m[0] = "000";
>>> m[1] = "111"; //break point here, we stop here
>
It was not easy to catch such crash problem under windows.
By the way, I found a way to debug gdb under Codeblocks' IDE, see:
http://forums.codeblocks.org/index.php/topic,15618.msg105064.html#msg105064
It has some advantages than just debug gdb under command line. (mentioned in the above link post)
Hopefully it will help some Windows user to easily check the crash problem in the future.
asmwarrior
ollydbg from codeblocks' forum
^ permalink raw reply [flat|nested] 9+ messages in thread
* Fwd: [patch] avoid the crash of gdb+pretty printer on initialized local variables
[not found] ` <CAF4KFGp2cDOzKdV62MfX0vpHUAxj1D2W0W3cBZnZpYHPYxZEuA@mail.gmail.com>
@ 2011-12-05 10:13 ` Martin Runge
2011-12-05 12:48 ` André Pönitz
2011-12-20 14:38 ` Tom Tromey
0 siblings, 2 replies; 9+ messages in thread
From: Martin Runge @ 2011-12-05 10:13 UTC (permalink / raw)
To: gdb-patches; +Cc: asmwarrior, Tom Tromey
Hello,
I have seen gdb running into very long loops on Linux, too (Ubuntu
11.04, gdb 7.2 and 7.3). It looks like gdb is frozen, but it uses 100%
CPU. When attaching to that gdb process, I observed gdb fetching a lot
of values (address increasing, but the range was by far too large). I
guess this comes from a pretty printer, asking gdb to fetch too many
values. libstdc++ and Qt4 pretty printers were in use in my case.
Although the error is probably somewhere in the pretty_printers, the
user experience is very confusing. E.g. with Eclipse CDT on top, gdb
does not respond to mi commands any more. As gdb does not give any
"progress" of "still alive" messages via mi to Eclipse, it runs into a
timeout and assumes gdb dead, debug session is broken and needs to be
restarted.
I think, only few people write their pretty printers themselves. Most
get them "somewhere from the Internet", so its hard to guarantee
quality or rely on it.
Would it be a good idea in your eyes, if
- gdb would guarantee a response time to mi commands ( limit the time
spent in a mi command -> stop fetching values when time is over)?
- gdb gave some progress reports "still working, nn% done" in regular
intervals, so mi clients like Eclipse can restart their timeout? For
Example smartcards do so. If asked for a long running operation, the
smartcard first replies by asking the terminal (== card reader) to
extend the timeout before starting work. This can be repeated as often
as neccessary to complete the operation and the terminal gets regular
feedback. The card terminal may not deny the smartcard's wish.
- some possibly long running mi commands could be aborted over mi
(those that run a loop over many small operations, like
pretty-printers)?
best regards
Martin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Fwd: [patch] avoid the crash of gdb+pretty printer on initialized local variables
2011-12-05 10:13 ` Fwd: " Martin Runge
@ 2011-12-05 12:48 ` André Pönitz
2011-12-20 14:38 ` Tom Tromey
1 sibling, 0 replies; 9+ messages in thread
From: André Pönitz @ 2011-12-05 12:48 UTC (permalink / raw)
To: gdb-patches
On Monday 05 December 2011 11:13:25 ext Martin Runge wrote:
> Hello,
>
> I have seen gdb running into very long loops on Linux, too (Ubuntu
> 11.04, gdb 7.2 and 7.3). It looks like gdb is frozen, but it uses 100%
> CPU. When attaching to that gdb process, I observed gdb fetching a lot
> of values (address increasing, but the range was by far too large). I
> guess this comes from a pretty printer, asking gdb to fetch too many
> values. libstdc++ and Qt4 pretty printers were in use in my case.
>
> Although the error is probably somewhere in the pretty_printers, the
> user experience is very confusing. E.g. with Eclipse CDT on top, gdb
> does not respond to mi commands any more. As gdb does not give any
> "progress" of "still alive" messages via mi to Eclipse, it runs into a
> timeout and assumes gdb dead, debug session is broken and needs to be
> restarted.
>
> I think, only few people write their pretty printers themselves. Most
> get them "somewhere from the Internet", so its hard to guarantee
> quality or rely on it.
[Even "good" pretty printers have a hard time to work robustly on
uninitialized data without being too restrictive.]
> Would it be a good idea in your eyes, if
>
> - gdb would guarantee a response time to mi commands ( limit the time
> spent in a mi command -> stop fetching values when time is over)?
>
> - gdb gave some progress reports "still working, nn% done" in regular
> intervals, so mi clients like Eclipse can restart their timeout? For
> Example smartcards do so. If asked for a long running operation, the
> smartcard first replies by asking the terminal (== card reader) to
> extend the timeout before starting work. This can be repeated as often
> as neccessary to complete the operation and the terminal gets regular
> feedback. The card terminal may not deny the smartcard's wish.
>
> - some possibly long running mi commands could be aborted over mi
> (those that run a loop over many small operations, like
> pretty-printers)?
I think it would be sufficient if a frontend could interrupt a running python
script, see http://sourceware.org/bugzilla/show_bug.cgi?id=12615
Andre'
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] avoid the crash of gdb+pretty printer on initialized local variables
2011-12-04 1:41 ` asmwarrior
[not found] ` <CAF4KFGqyz0WMWWJt9x1HZpO+urMo9jJLyudcRrHxUTqJf8mvqA@mail.gmail.com>
@ 2011-12-05 21:51 ` Tom Tromey
2011-12-06 10:34 ` asmwarrior
1 sibling, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2011-12-05 21:51 UTC (permalink / raw)
To: asmwarrior; +Cc: gdb-patches
>>>>> ">" == ext asmwarrior <asmwarrior@gmail.com> writes:
Tom> I forget, something to do with not using the right gcc flag?
>> My app was build with -O0 and -g, no extra flag is used.
I mean a missing flag when building gdb. I vaguely recall a need for
-fno-omit-frame-pointer, and that without this, gdb exceptions cause
crashes.
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] avoid the crash of gdb+pretty printer on initialized local variables
2011-12-05 21:51 ` Tom Tromey
@ 2011-12-06 10:34 ` asmwarrior
2011-12-06 15:41 ` Tom Tromey
0 siblings, 1 reply; 9+ messages in thread
From: asmwarrior @ 2011-12-06 10:34 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On 2011-12-6 5:44, Tom Tromey wrote:
>>>>>> ">" == ext asmwarrior <asmwarrior@gmail.com> writes:
>
> Tom> I forget, something to do with not using the right gcc flag?
>
>>> My app was build with -O0 and -g, no extra flag is used.
>
> I mean a missing flag when building gdb. I vaguely recall a need for
> -fno-omit-frame-pointer, and that without this, gdb exceptions cause
> crashes.
>
> Tom
Hi, Tom, thanks.
Yes, gdb build under mingw should have -fno-omit-frame-pointer flag, otherwise, it will crash.
I forget to mention that My gdb was build with -O0 and -g, so I think no optimization was used in building gdb.
The problem is that gdb still crash when it try to pretty-print the uninitialized local variables.
asmwarrior
ollydbg from codeblocks' forum
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] avoid the crash of gdb+pretty printer on initialized local variables
2011-12-06 10:34 ` asmwarrior
@ 2011-12-06 15:41 ` Tom Tromey
0 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2011-12-06 15:41 UTC (permalink / raw)
To: asmwarrior; +Cc: gdb-patches
>>>>> ">" == ext asmwarrior <asmwarrior@gmail.com> writes:
>> I forget to mention that My gdb was build with -O0 and -g, so I think
>> no optimization was used in building gdb.
>> The problem is that gdb still crash when it try to pretty-print the
>> uninitialized local variables.
I think the best thing to do is find out why that happens, and fix the
root cause. gdb should not crash.
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Fwd: [patch] avoid the crash of gdb+pretty printer on initialized local variables
2011-12-05 10:13 ` Fwd: " Martin Runge
2011-12-05 12:48 ` André Pönitz
@ 2011-12-20 14:38 ` Tom Tromey
1 sibling, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2011-12-20 14:38 UTC (permalink / raw)
To: Martin Runge; +Cc: gdb-patches, asmwarrior
>>>>> "Martin" == Martin Runge <martin.runge@web.de> writes:
Martin> I have seen gdb running into very long loops on Linux, too (Ubuntu
Martin> 11.04, gdb 7.2 and 7.3). It looks like gdb is frozen, but it uses 100%
Martin> CPU. When attaching to that gdb process, I observed gdb fetching a lot
Martin> of values (address increasing, but the range was by far too large). I
Martin> guess this comes from a pretty printer, asking gdb to fetch too many
Martin> values. libstdc++ and Qt4 pretty printers were in use in my case.
Martin> Although the error is probably somewhere in the pretty_printers, the
Martin> user experience is very confusing. E.g. with Eclipse CDT on top, gdb
Martin> does not respond to mi commands any more. As gdb does not give any
Martin> "progress" of "still alive" messages via mi to Eclipse, it runs into a
Martin> timeout and assumes gdb dead, debug session is broken and needs to be
Martin> restarted.
Is Eclipse using the range limitation feature of dynamic varobjs?
That is intended to help prevent this sort of thing.
Martin> I think, only few people write their pretty printers themselves. Most
Martin> get them "somewhere from the Internet", so its hard to guarantee
Martin> quality or rely on it.
Yeah.
Martin> Would it be a good idea in your eyes, if
[...]
I am not sure what would be the best solution, but could you file a bug
report for the problem?
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-12-20 14:29 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <4ED379D8.4060808@gmail.com>
2011-12-02 4:32 ` [patch] avoid the crash of gdb+pretty printer on initialized local variables asmwarrior
2011-12-02 16:51 ` Tom Tromey
2011-12-04 1:41 ` asmwarrior
[not found] ` <CAF4KFGqyz0WMWWJt9x1HZpO+urMo9jJLyudcRrHxUTqJf8mvqA@mail.gmail.com>
[not found] ` <CAF4KFGp2cDOzKdV62MfX0vpHUAxj1D2W0W3cBZnZpYHPYxZEuA@mail.gmail.com>
2011-12-05 10:13 ` Fwd: " Martin Runge
2011-12-05 12:48 ` André Pönitz
2011-12-20 14:38 ` Tom Tromey
2011-12-05 21:51 ` Tom Tromey
2011-12-06 10:34 ` asmwarrior
2011-12-06 15:41 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox