1*700637cbSDimitry Andric %feature("docstring", 2*700637cbSDimitry Andric "A Progress indicator helper class. 3*700637cbSDimitry Andric 4*700637cbSDimitry Andric Any potentially long running sections of code in LLDB should report 5*700637cbSDimitry Andric progress so that clients are aware of delays that might appear during 6*700637cbSDimitry Andric debugging. Delays commonly include indexing debug information, parsing 7*700637cbSDimitry Andric symbol tables for object files, downloading symbols from remote 8*700637cbSDimitry Andric repositories, and many more things. 9*700637cbSDimitry Andric 10*700637cbSDimitry Andric The Progress class helps make sure that progress is correctly reported 11*700637cbSDimitry Andric and will always send an initial progress update, updates when 12*700637cbSDimitry Andric Progress::Increment() is called, and also will make sure that a progress 13*700637cbSDimitry Andric completed update is reported even if the user doesn't explicitly cause one 14*700637cbSDimitry Andric to be sent. 15*700637cbSDimitry Andric 16*700637cbSDimitry Andric Progress can either be deterministic, incrementing up to a known total or non-deterministic 17*700637cbSDimitry Andric with an unbounded total. Deterministic is better if you know the items of work in advance, but non-deterministic 18*700637cbSDimitry Andric exposes a way to update a user during a long running process that work is taking place. 19*700637cbSDimitry Andric 20*700637cbSDimitry Andric For all progresses the details provided in the constructor will be sent until an increment detail 21*700637cbSDimitry Andric is provided. This detail will also continue to be broadcasted on any subsequent update that doesn't 22*700637cbSDimitry Andric specify a new detail. Some implementations differ on throttling updates and this behavior differs primarily 23*700637cbSDimitry Andric if the progress is deterministic or non-deterministic. For DAP, non-deterministic update messages have a higher 24*700637cbSDimitry Andric throttling rate than deterministic ones. 25*700637cbSDimitry Andric 26*700637cbSDimitry Andric Below are examples in Python for deterministic and non-deterministic progresses. :: 27*700637cbSDimitry Andric 28*700637cbSDimitry Andric deterministic_progress1 = lldb.SBProgress('Deterministic Progress', 'Detail', 3, lldb.SBDebugger) 29*700637cbSDimitry Andric for i in range(3): 30*700637cbSDimitry Andric deterministic_progress1.Increment(1, f'Update {i}') 31*700637cbSDimitry Andric # The call to Finalize() is a no-op as we already incremented the right amount of 32*700637cbSDimitry Andric # times and caused the end event to be sent. 33*700637cbSDimitry Andric deterministic_progress1.Finalize() 34*700637cbSDimitry Andric 35*700637cbSDimitry Andric deterministic_progress2 = lldb.SBProgress('Deterministic Progress', 'Detail', 10, lldb.SBDebugger) 36*700637cbSDimitry Andric for i in range(3): 37*700637cbSDimitry Andric deterministic_progress2.Increment(1, f'Update {i}') 38*700637cbSDimitry Andric # Cause the progress end event to be sent even if we didn't increment the right 39*700637cbSDimitry Andric # number of times. Real world examples would be in a try-finally block to ensure 40*700637cbSDimitry Andric # progress clean-up. 41*700637cbSDimitry Andric deterministic_progress2.Finalize() 42*700637cbSDimitry Andric 43*700637cbSDimitry Andric If you don't call Finalize() when the progress is not done, the progress object will eventually get 44*700637cbSDimitry Andric garbage collected by the Python runtime, the end event will eventually get sent, but it is best not to 45*700637cbSDimitry Andric rely on the garbage collection when using lldb.SBProgress. 46*700637cbSDimitry Andric 47*700637cbSDimitry Andric Non-deterministic progresses behave the same, but omit the total in the constructor. :: 48*700637cbSDimitry Andric 49*700637cbSDimitry Andric non_deterministic_progress = lldb.SBProgress('Non deterministic progress', 'Detail', lldb.SBDebugger) 50*700637cbSDimitry Andric for i in range(10): 51*700637cbSDimitry Andric non_deterministic_progress.Increment(1) 52*700637cbSDimitry Andric # Explicitly send a progressEnd, otherwise this will be sent 53*700637cbSDimitry Andric # when the python runtime cleans up this object. 54*700637cbSDimitry Andric non_deterministic_progress.Finalize() 55*700637cbSDimitry Andric 56*700637cbSDimitry Andric Additionally for Python, progress is supported in a with statement. :: 57*700637cbSDimitry Andric with lldb.SBProgress('Non deterministic progress', 'Detail', lldb.SBDebugger) as progress: 58*700637cbSDimitry Andric for i in range(10): 59*700637cbSDimitry Andric progress.Increment(1) 60*700637cbSDimitry Andric # The progress object is automatically finalized when the with statement 61*700637cbSDimitry Andric 62*700637cbSDimitry Andric ") lldb::SBProgress; 63*700637cbSDimitry Andric 64*700637cbSDimitry Andric %feature("docstring", 65*700637cbSDimitry Andric "Finalize the SBProgress, which will cause a progress end event to be emitted. This 66*700637cbSDimitry Andric happens automatically when the SBProcess object is destroyed, but can be done explicitly 67*700637cbSDimitry Andric with Finalize to avoid having to rely on the language semantics for destruction. 68*700637cbSDimitry Andric 69*700637cbSDimitry Andric Note once finalized, no further increments will be processed.") lldb::SBProgress::Finalize; 70*700637cbSDimitry Andric 71*700637cbSDimitry Andric %feature("docstring", 72*700637cbSDimitry Andric "Increment the progress by a given number of units, optionally with a message. Not all progress events are guaraunteed 73*700637cbSDimitry Andric to be sent, but incrementing to the total will always guarauntee a progress end event being sent.") lldb::SBProcess::Increment; 74