@@ -3857,8 +3857,8 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
38573857 // case we should tell it to stop doing that. Normally, we don't NEED
38583858 // to do that because we will next close the communication to the stub
38593859 // and that will get it to shut down. But there are remote debugging
3860- // cases where relying on that side-effect causes the shutdown to be
3861- // flakey, so we should send a positive signal to interrupt the wait.
3860+ // cases where relying on that side-effect causes the shutdown to be
3861+ // flakey, so we should send a positive signal to interrupt the wait.
38623862 Status error = HaltPrivate ();
38633863 BroadcastEvent (eBroadcastBitInterrupt, nullptr );
38643864 } else if (StateIsRunningState (m_last_broadcast_state)) {
@@ -6335,30 +6335,65 @@ static void AddRegion(const MemoryRegionInfo ®ion, bool try_dirty_pages,
63356335 ranges.push_back (CreateCoreFileMemoryRange (region));
63366336}
63376337
6338+ static void SaveOffRegionsWithStackPointers (
6339+ Process &process, const MemoryRegionInfos ®ions,
6340+ Process::CoreFileMemoryRanges &ranges, std::set<addr_t > &stack_ends) {
6341+ const bool try_dirty_pages = true ;
6342+
6343+ // Before we take any dump, we want to save off the used portions of the
6344+ // stacks and mark those memory regions as saved. This prevents us from saving
6345+ // the unused portion of the stack below the stack pointer. Saving space on
6346+ // the dump.
6347+ for (lldb::ThreadSP thread_sp : process.GetThreadList ().Threads ()) {
6348+ if (!thread_sp)
6349+ continue ;
6350+ StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex (0 );
6351+ if (!frame_sp)
6352+ continue ;
6353+ RegisterContextSP reg_ctx_sp = frame_sp->GetRegisterContext ();
6354+ if (!reg_ctx_sp)
6355+ continue ;
6356+ const addr_t sp = reg_ctx_sp->GetSP ();
6357+ const size_t red_zone = process.GetABI ()->GetRedZoneSize ();
6358+ lldb_private::MemoryRegionInfo sp_region;
6359+ if (process.GetMemoryRegionInfo (sp, sp_region).Success ()) {
6360+ const size_t stack_head = (sp - red_zone);
6361+ const size_t stack_size = sp_region.GetRange ().GetRangeEnd () - stack_head;
6362+ sp_region.GetRange ().SetRangeBase (stack_head);
6363+ sp_region.GetRange ().SetByteSize (stack_size);
6364+ stack_ends.insert (sp_region.GetRange ().GetRangeEnd ());
6365+ AddRegion (sp_region, try_dirty_pages, ranges);
6366+ }
6367+ }
6368+ }
6369+
63386370// Save all memory regions that are not empty or have at least some permissions
63396371// for a full core file style.
63406372static void GetCoreFileSaveRangesFull (Process &process,
63416373 const MemoryRegionInfos ®ions,
6342- Process::CoreFileMemoryRanges &ranges) {
6374+ Process::CoreFileMemoryRanges &ranges,
6375+ std::set<addr_t > &stack_ends) {
63436376
63446377 // Don't add only dirty pages, add full regions.
63456378const bool try_dirty_pages = false ;
63466379 for (const auto ®ion : regions)
6347- AddRegion (region, try_dirty_pages, ranges);
6380+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0 )
6381+ AddRegion (region, try_dirty_pages, ranges);
63486382}
63496383
63506384// Save only the dirty pages to the core file. Make sure the process has at
63516385// least some dirty pages, as some OS versions don't support reporting what
63526386// pages are dirty within an memory region. If no memory regions have dirty
63536387// page information fall back to saving out all ranges with write permissions.
6354- static void
6355- GetCoreFileSaveRangesDirtyOnly ( Process &process,
6356- const MemoryRegionInfos ®ions,
6357- Process::CoreFileMemoryRanges &ranges) {
6388+ static void GetCoreFileSaveRangesDirtyOnly (
6389+ Process &process, const MemoryRegionInfos ®ions ,
6390+ Process::CoreFileMemoryRanges &ranges, std::set< addr_t > &stack_ends) {
6391+
63586392 // Iterate over the regions and find all dirty pages.
63596393 bool have_dirty_page_info = false ;
63606394 for (const auto ®ion : regions) {
6361- if (AddDirtyPages (region, ranges))
6395+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0 &&
6396+ AddDirtyPages (region, ranges))
63626397 have_dirty_page_info = true ;
63636398 }
63646399
@@ -6367,7 +6402,8 @@ GetCoreFileSaveRangesDirtyOnly(Process &process,
63676402 // plug-in so fall back to any region with write access permissions.
63686403 const bool try_dirty_pages = false ;
63696404 for (const auto ®ion : regions)
6370- if (region.GetWritable () == MemoryRegionInfo::eYes)
6405+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0 &&
6406+ region.GetWritable () == MemoryRegionInfo::eYes)
63716407 AddRegion (region, try_dirty_pages, ranges);
63726408 }
63736409}
@@ -6380,43 +6416,18 @@ GetCoreFileSaveRangesDirtyOnly(Process &process,
63806416// dirty regions as this will make the core file smaller. If the process
63816417// doesn't support dirty regions, then it will fall back to adding the full
63826418// stack region.
6383- static void
6384- GetCoreFileSaveRangesStackOnly ( Process &process,
6385- const MemoryRegionInfos ®ions,
6386- Process::CoreFileMemoryRanges &ranges) {
6419+ static void GetCoreFileSaveRangesStackOnly (
6420+ Process &process, const MemoryRegionInfos ®ions ,
6421+ Process::CoreFileMemoryRanges &ranges, std::set< addr_t > &stack_ends) {
6422+ const bool try_dirty_pages = true ;
63876423 // Some platforms support annotating the region information that tell us that
63886424 // it comes from a thread stack. So look for those regions first.
63896425
6390- // Keep track of which stack regions we have added
6391- std::set<addr_t > stack_bases;
6392-
6393- const bool try_dirty_pages = true ;
63946426 for (const auto ®ion : regions) {
6395- if (region.IsStackMemory () == MemoryRegionInfo::eYes) {
6396- stack_bases.insert (region.GetRange ().GetRangeBase ());
6427+ // Save all the stack memory ranges not associated with a stack pointer.
6428+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0 &&
6429+ region.IsStackMemory () == MemoryRegionInfo::eYes)
63976430 AddRegion (region, try_dirty_pages, ranges);
6398- }
6399- }
6400-
6401- // Also check with our threads and get the regions for their stack pointers
6402- // and add those regions if not already added above.
6403- for (lldb::ThreadSP thread_sp : process.GetThreadList ().Threads ()) {
6404- if (!thread_sp)
6405- continue ;
6406- StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex (0 );
6407- if (!frame_sp)
6408- continue ;
6409- RegisterContextSP reg_ctx_sp = frame_sp->GetRegisterContext ();
6410- if (!reg_ctx_sp)
6411- continue ;
6412- const addr_t sp = reg_ctx_sp->GetSP ();
6413- lldb_private::MemoryRegionInfo sp_region;
6414- if (process.GetMemoryRegionInfo (sp, sp_region).Success ()) {
6415- // Only add this region if not already added above. If our stack pointer
6416- // is pointing off in the weeds, we will want this range.
6417- if (stack_bases.count (sp_region.GetRange ().GetRangeBase ()) == 0 )
6418- AddRegion (sp_region, try_dirty_pages, ranges);
6419- }
64206431 }
64216432}
64226433
@@ -6428,23 +6439,27 @@ Status Process::CalculateCoreFileSaveRanges(lldb::SaveCoreStyle core_style,
64286439 return err;
64296440 if (regions.empty ())
64306441 return Status (" failed to get any valid memory regions from the process" );
6442+ if (core_style == eSaveCoreUnspecified)
6443+ return Status (" callers must set the core_style to something other than "
6444+ " eSaveCoreUnspecified" );
6445+
6446+ std::set<addr_t > stack_ends;
6447+ SaveOffRegionsWithStackPointers (*this , regions, ranges, stack_ends);
64316448
64326449 switch (core_style) {
64336450 case eSaveCoreUnspecified:
6434- err = Status (" callers must set the core_style to something other than "
6435- " eSaveCoreUnspecified" );
64366451 break ;
64376452
64386453 case eSaveCoreFull:
6439- GetCoreFileSaveRangesFull (*this , regions, ranges);
6454+ GetCoreFileSaveRangesFull (*this , regions, ranges, stack_ends );
64406455 break ;
64416456
64426457 case eSaveCoreDirtyOnly:
6443- GetCoreFileSaveRangesDirtyOnly (*this , regions, ranges);
6458+ GetCoreFileSaveRangesDirtyOnly (*this , regions, ranges, stack_ends );
64446459 break ;
64456460
64466461 case eSaveCoreStackOnly:
6447- GetCoreFileSaveRangesStackOnly (*this , regions, ranges);
6462+ GetCoreFileSaveRangesStackOnly (*this , regions, ranges, stack_ends );
64486463 break ;
64496464 }
64506465
0 commit comments