This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 179759

Summary: Add breakpoint properties for grouping in Breakpoints Window
Product: debugger Reporter: Martin Entlicher <mentlicher>
Component: CodeAssignee: Martin Entlicher <mentlicher>
Status: RESOLVED FIXED    
Severity: normal CC: vv159170
Priority: P2 Keywords: API, API_REVIEW_FAST
Version: 6.x   
Hardware: PC   
OS: Linux   
Issue Type: ENHANCEMENT Exception Reporter:
Bug Depends on:    
Bug Blocks: 42266, 72560, 101195    
Attachments: The proposed API change.
Slightly modified API change that only adds getEngines() method.

Description Martin Entlicher 2010-01-21 10:05:23 UTC
In order to solve the dependent issues, we need to associate properties with Breakpoint class, which would tell us the necessary information for grouping of breakpoints into different categories.

According to the proposed UI spec at http://wiki.netbeans.org/DebuggerBreakpoints67, we need to know the breakpoint type, language, files and projects.

Therefore we propose to add Breakpoint.getGroupProperties() method, that would return GroupProperties object with the relevant info.
Comment 1 Martin Entlicher 2010-01-21 10:52:59 UTC
Created attachment 93458 [details]
The proposed API change.
Comment 2 Martin Entlicher 2010-01-21 10:54:35 UTC
Please review introduction of breakpoint properties.
Comment 3 ivan 2010-01-21 15:30:40 UTC
IS0: What does it mean for a breakpoint to belong to a project?
     AFAIK, there is no such thing as "current project". There is 
     the "selected" project and the "main" project and neither of
     these seems like the right candidate. For example one may be
     rebuilding a library but running/debugging it's wrapper/tester
     application. I even remember arguments made that "main" should
     be eliminated.

     Even if you create a breakpoint during a debug session using the
     project the debug session was started from (e.g. Server)
     it is not always the right choice because the breakpoint may
     be intended for a second session you're about to start from
     a different project (e.g. Client).

     Shall we deduce the project from the filename or function name?
     In many cases one cannot map files to projects, especially in 
     non-managed projects.

     In short as long as an IDE has "global" and "anytime" breakpoints 
     and uses a Start model (as opposed to the traditional debugger
     Load then Run model) for debugging no meaningful association can
     be made with projects.

IS1: Should getFiles() return an FO for, say a function bpt?
     It would return the file containing the definition of that
     function.
Comment 4 ivan 2010-01-21 15:51:01 UTC
IS2: This isn't directly related but I'm a bit wary of perpetuating
     the use of "human readable" breakpoint type names. When I
     deserialize breakpoints I need to create them and I use the
     "type name" and  DebuggerManager.getDebuggerManager().
     lookup(null, BreakpointType.class) to create a mapping.

     However, because it's human readable the name will pass through i18n.
     Then if the user changes their locale, or a better speaker of the language 
     corrects the spelling in the bundle file, restoring of persisted
     breakpoints will fall apart. 

     Also these type names are per debugger, I.e. categoryDisplayName,
     so as soon as you end up with multiple debuggers sorting by type becomes
     less useful. remember, we're not in a monoculture like Windows and it's
     IDE ... we'll be having diverse implementations of debuggers.
 
IS3: Can a breakpoint appear in more than one Group?
     Given that arrays of projects and files are returned the answer
     must be yes.
     But are groups designed such that different groups can contain the
     same breakpoint?
Comment 5 Martin Entlicher 2010-01-22 08:32:29 UTC
IS0: This is to be determined for every breakpoint type specifically.
     The API counts with the inability to map breakpoints to projects, that's
     why it allows you to return null.
     For some breakpoints it's clear. When you submit a line breakpoint to a
     file that is a part of a project (the most common situation), the mapping
     is clear. The breakpoint's project is the one in which the file resides.
     If the file is contained in multiple projects, then multiple projects are
     returned. In case of libraries or platform sources, no project binding can
     be made and therefore it's perfectly O.K. to return null.
     The "global" or "anytime" breakpoints, like Thread breakpoint or Exception
     breakpoint in Java, no file/project mapping is expected.

     The motivation behind this was to categorize breakpoints as much as
     possible in order to implement dependent issues and to help users to
     orientate in Breakpoints Window. If there are not similar requirements for
     CND debugger, implementing this is just voluntary.

IS1: Yes, this is expected. In Java debugger, for breakpoints on Java methods
     we find the method's source file(s) (there can be identical classes in
     several projects) and return these files. Therefore C/C++ debugger can do
     something similar. Whenever there is a reasonable mapping from breakpoints
     to appropriate files and projects, it's expected to be returned through
     this API.

IS2: Yes, unfortunately I did not find a way how to enforce a consistent naming
     e.g. for "Line" breakpoint type across all debuggers. Also equal Strings
     between Breakpoint.GroupProperties.getLanguage() and
     org.netbeans.spi.debugger.ui.BreakpointType.getCategoryDisplayName()
     can not be enforced. But, at least, grouping by Language and then by type
     should look reasonably. For serialization/deserialization you'll be better
     to use a different properties representing your implementation.
     In JPDA debugger, for instance, we use the implementation class name
     (which is also not perfect if you refactor the sources).

IS3: Yes, the implementation counts with this.
Comment 6 ivan 2010-01-22 15:37:53 UTC
IS0: The CND group may not have submitted requirements but this
     issue has been on the minds of SunStudio since day 1 (ten
     years +).

     One frequent complaint we've gotten is that breakpoints accumulate
     and that as users move from bug fix to bug fix or product to
     product they need to reset their bpt list.  Deleting everything is
     fine but sometimes we want persistence as well.  We also need to
     persist breakpoints because once a session is over we need to be
     abel to look at them and adjust them.

     If not glbally one can persist breakpoints per "context".  For
     example Microsoft VC persistes breakpoints per "solution".
     Lacking "solutions" a casual user will naturally latch on to
     Project as a "context" and as for per-project breakpoints.  I've
     evenhad debugger _designers_ (like from Microchip) use the term
     Project.  The problem is that in NB (as in other IDE's) a Project
     is not a working context but is a standing for an artifact it
     produces.

     Any but a trivial application is going to be made of several
     artifacts, let's say, a few libraries and a main application.
     Which of these projects is the "right project" to serve as a
     context?  If the user chooses to view only bpts in the main
     project then they will not see bpts they place in the libraries.

     You may say the users are not obligated to filter by project but
     then it seems to me we're not solving their real problem for any
     but the most trivial projects.

     You may say that NB is a non-trivial project and no-one
     seems to mind this. I'll answer that NB developers work
     on oly _only_ on application.
     There are customers that work on several application and
     it is precisely these that need a solution that helps them.


     Then, users may use many types of breakpoints while in a context.
     These may include watchpoints and exceptions. This proposal,
     by relegating these to "unknown project", seems like it will
     make things much harder and _discourage_ people form using
     useful breakpoints.

        BTW I consider _all_ types of breakpoints to be "global"
        and "anytime".

        global means: If I create a breakpoint while in two sessions
        both sessions will attempt to interpret that intent.

        anytime means: I can create a breakpoint anytime, before
        establishing any kind of conetxt.

        The term is use to distinguish between line/function and
        exception/watch breakpoints (square bpt glyph vs triangular
        bpt glyph) is "location based".


     A third choice for context is the session itself. The problem of
     course is what is the context when there are no sessions?


     IMO one cannot solve the users ultimate problem with the main IDE
     concepts we have on hand. A new concept needs to be introduced.
     Something like a "Run/Debug scenario" or as we call them in
     dbxtool "debug target".

     Such a concept solves another problem as well, that of multiple
     debuggers accepting the same breakpoint (example: gdb and dbx both
     accept C++ bpts and each creates it's own) (example: jpda and dbx
     both accept java breakpoits and each creates it's own).  A context
     will allow a user to specify which debugger they prefer to use for
     that context. Casual users again fall back on projects ...  "can I
     associate a debugger of choice with a project".

     Are we brave enough to duck the trend and investigate how we can
     introduce such a concept into an IDE?
Comment 7 Martin Entlicher 2010-01-25 07:01:55 UTC
IS0: It's true that Project is perhaps a too small entity for grouping things
     like breakpoints, because usually you work with more than one project with
     mutual dependencies at the same time. And the debugging session typically
     spreads over more Projects as well. But NetBeans really lacks something that
     would logically group projects together.
     This API proposal uses the current IDE concept, but since GroupProperties is
     an abstract class, any meaningful category that will appear in the future can
     be added there.

     If you consider all breakpoints to be "global", then no logical grouping to
     Projects, sessions, "solutions", or whatever can be made. Or am I missing
     something?

     For me, at least line breakpoints are bind to the particular file where they
     are submitted to, and if that file is a part of a project, they also belong
     to that project. And we can do the same binding with watchpoints (field
     breakpoints in Java) and method breakpoints. Some breakpoints should perhaps
     be restricted to particular projects by users... I've already heard
     a requirement to apply Exception breakpoints only to the one user project.
     Sometimes the user submits a breakpoint with the intent to work only in the
     current project and they do not expect to be hit when debugging a different
     project. This proposed categorization will help to implement this.

     Is there a specification somewhere for the "Run/Debug scenario" that you
     propose? I'm afraid that it's too big to be done in NB 6.9.
     Do you mean that the current proposal of breakpoints grouping does not have
     a sense for Sunstudio without some high-level "scenario" that will span
     across more Projects?

     The problem of multiple debuggers for the same language and accepting the
     same breakpoints is there for a long time already (from the very
     beginning). I agree that it deserves a solution. But I do not think there's
     enough time to come with one into NB 6.9. Something like
     "Run/Debug scenario" needs broader discussion. We already have
     Configurations which are just for program arguments and execution options,
     but they are project-specific. We need to assure that the new concept fits
     into the existing ones or that it can replace them. That is for a different
     and far more general issue than this.
Comment 8 ivan 2010-01-25 21:31:38 UTC
IS0:
> This API proposal uses the current IDE concept, but since GroupProperties
> is an abstract class, any meaningful category that will appear in the future
> can be added there.

This is a good point.

Vladimir also pointed out that one can get very creative with
GroupProperties.isHidden().


> If you consider all breakpoints to be "global", then no logical grouping
> to Projects, sessions, "solutions", or whatever can be made. Or am I missing
> something?

I view the globality of breakpoints as an inevitable and emergent characteristic
of breakpoints in IDE's not a fundamental requirement.
Also, to some extent, one can argue that the need for persistence of breakpoints
is also an emergent charateristic.

The fundamental requirement _in IDE_'s are "Start model" and "anytime breakpoints"
and the only way to implement them is via global breakpoints.

"anytime breakpoints" says:
	you can create a breakpoint anytime you wish without knowing or concerning
	yourself with what program you're going to run.

"start model" says:
	This is an IDE. The fact that there is a debugger in there should be
	hidden from view so if you happen to have anytime breakpoints you can
	dispense with a "loading a program into a debugger" action.

I think there is a logical grouping that makes sense and it is a "debugging scenario".
One declares what it is they are debugging, and then they will repeatedly run
and adjust their breakpoints.
Once a bug is fixed for a given scenario it's breakpoints are not needed and
that debugging scenario is likely not needed.

That is why people have successfully used cmdline debuggers, which don't
persist breakpoints, for ages. I've also found that with global 
breakpoints the easiest workaround for the accumulation problem is DeleteAll.

A debugging scenario is a bit abstract. A better concept might be "program".
A "program" is a tuple of <code, input, environment, ...> that describes 
how a process/processes is/are created. You can Run a program or
Debug a program or instrument a program.
It's a bit like current configurations but is orthogonal to projects.

	Configurations just repeat the same mistake again. 
 	It takes something which is supposed to classify how you build
	something and overloads it with how you run it.

> Sometimes the user submits a breakpoint with the intent to work only in
> the current project and they do not expect to be hit when debugging a
> different project. 

Here's a mention of "current project" again ... what exactly does
that mean? The currently selected project or the main project?

> 
> Is there a specification somewhere for the "Run/Debug scenario" that you
> propose?
> I'm afraid that it's too big to be done in NB 6.9.

I don't have a specification. What SunStudio does isn't particularly helpful
wrt global breakpoints.
I'm interested in more than just me appreciating
the problem and brainstorming as a group towards a more robust solution as opposed
to coming up with bandaids. Martin said it at the very beginning:

> But NetBeans really lacks something that would logically group projects together.

......................
I have one more concrete "question" ...

IS4: 
It's hard for me to judge how a mixture of SS hierarchical breakpoints
and recursive grouping will work.
We already have bugs where the existing user defined grouping doesn't work. My
reaction to that was to do away with groups, but they are now
back with a vengeance :-)

More concretely 
- SS nested breakpoints should not be groupable. I think this has more
  to do with what actions are allowed than what getGroupProperties() returns.
- How SS's per-session viewing will interoperate with any builtin 
  per-session viewing mechanism.
Comment 9 Martin Entlicher 2010-01-26 11:22:23 UTC
> Vladimir also pointed out that one can get very creative with
> GroupProperties.isHidden().

:-)
In Java debugger we use hidden breakpoints for actions like Go To Cursor or Run Into Method, where we need to move execution to some point, but do not want to disturb user with a visible breakpoint.

In Java debugger we try to avoid the globality of breakpoints if possible, to me it does not look inevitable, at least in most common cases - line breakpoints. In Java they are restricted to the particular file in the particular project and do not work anywhere else. From what I've heard this is also what users expect.

I've just tested how things work in Eclipse and I must say that I would not want such behavior in NetBeans.
1) I've created a C++ project named A with a Factorial class. I've put some line breakpoints to that class and call it's methods from main() in the same project.
2) Executed under debugger, breakpoints were hit as expected.
3) I've created a C++ project named B and copied the sources of project A into B. I did not submit any breakpoint into sources in B.
4) Executed B under debugger and debugger stops on lines where breakpoints were present in project A. But no breakpoints were visible in the gutter of B's sources.
5) When I closed project A and executed B again under debugger, it did not stop anywhere.
6) Opened A again and debugger was stopping in B again.

The reason of the above behavior was that breakpoints were persisted in project A where they belong to (we plan to do something similar in Java debugger - see issue #174774), but they were treated as global. Exactly the same behavior was observed in Eclipse in Java debugger.

You mention "anytime breakpoints" as one of the fundamental requirements, but when user submits a breakpoint on "Foo" do they really want to stop on any Foo function in any program?

I see a program as a collection of projects, right? Then when I submit a breakpoint on Foo in project A, I'd expect to be hit by programs that execute the project A, but not hit by programs that execute other projects. This should be possible to check from project dependencies, correct?

As a "current project" I mean either the main project (if set) or the currently selected project (if no main project is set). It's simply the project that gets executed in you hit Run or Debug in the toolbar.

When I said that "NetBeans really lacks something that would logically group projects together", I've forgot about "Project Groups". It was reminded to be by issue #123970. I suppose that the Project Group is something what should represent the Program. Since a Project Group can be also a master Project with all it's required sub-projects, in these (most common IMHO) cases the Master Project can serve as the representation of the Program. So perhaps there is a way how to reasonably manage breakpoints without "Solution" or "Debugging Scenario"...

I'm currently reading about how SS manages breakpoints...
I've realized that to solve issue #72560 we'll probably have to introduce a "Session" group that would contain all relevant breakpoints for the running debugger session. I'm not sure if this is compatible with how SS works, hopefully after detailed understanding of how SS manages breakpoints... 

IS4: Perhaps we can disable grouping if all breakpoints would return null GroupProperties. That would solve your concerns (well unless someone creates a JPDA breakpoint ;-)) But anyway - if you do not wish your breakpoints to be groupable, just do not do any changes and they will not be, even if other breakpoints will be inside some groups, your will stay in the root, ungrouped.

> How SS's per-session viewing will interoperate with any builtin 
  per-session viewing mechanism.

If SS's per-session viewing is implemented by viewmodel filters, it should work fine. SS's models have the final word on what is being shown, therefore if it removes breakpoints that do not belong to the current session it should be O.K. I guess.
Comment 10 Vladimir Voskresensky 2010-01-26 12:47:46 UTC
(In reply to comment #9)
> 
> I've just tested how things work in Eclipse and I must say that I would not
> want such behavior in NetBeans.
Just a comment: this is just a bug (not a concept) in Eclipse's integration of gdb support. We had the same issue and solved it when QA filed the bug.
Comment 11 Martin Entlicher 2010-01-27 03:59:22 UTC
Fine. So it it's a bug it means that breakpoints do not have to be global.
Comment 12 Martin Entlicher 2010-02-03 09:06:42 UTC
Created attachment 93808 [details]
Slightly modified API change that only adds getEngines() method.

In order to be able to bind breakpoints with debugger sessions / engines, GroupProperties have DebuggerEngine[] getEngines() method.
In changeset:   158915:4f9dc8c4b789 I've pushed implementation that adds "Debug Session" category, that will use this API.
Comment 13 Martin Entlicher 2010-02-03 09:08:53 UTC
Any more opinions on this?
I'd like to integrate this change by the end of this week.
Comment 14 ivan 2010-02-03 14:50:31 UTC
Yes :-)
But I'll voice them elsewhere since we're
getting further and further form a strict API review.
Comment 15 Martin Entlicher 2010-02-26 07:50:47 UTC
I've disabled the grouping UI until a groupable breakpoint is created:
http://hg.netbeans.org/main-silver?cmd=changeset;node=c284a4370dad

I'm going to proceed with this API change and GroupProperties will be implemented for Java, JSP and ANT debugger. It can be implemented by other debuggers later on.

I'm going to push this change during the weekend. Thanks for the review.
Comment 16 Martin Entlicher 2010-03-01 08:23:48 UTC
The API is pushed in changeset:   161830:81d3cab807b9
http://hg.netbeans.org/main/rev/81d3cab807b9

Implemented for Java, ANT and JSP in changeset:   161832:63fbcc30109f
http://hg.netbeans.org/main/rev/63fbcc30109f
Comment 17 Quality Engineering 2010-03-01 22:11:22 UTC
Integrated into 'main-golden', will be available in build *201003020200* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main/rev/81d3cab807b9
User: mentlicher@netbeans.org
Log: #179759 - Breakpoint grouping API introduced.