@@ -3857,8 +3857,8 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
3857
3857
// case we should tell it to stop doing that. Normally, we don't NEED
3858
3858
// to do that because we will next close the communication to the stub
3859
3859
// 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.
3862
3862
Status error = HaltPrivate ();
3863
3863
BroadcastEvent (eBroadcastBitInterrupt, nullptr );
3864
3864
} else if (StateIsRunningState (m_last_broadcast_state)) {
@@ -6335,30 +6335,65 @@ static void AddRegion(const MemoryRegionInfo ®ion, bool try_dirty_pages,
6335
6335
ranges.push_back (CreateCoreFileMemoryRange (region));
6336
6336
}
6337
6337
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
+
6338
6370
// Save all memory regions that are not empty or have at least some permissions
6339
6371
// for a full core file style.
6340
6372
static void GetCoreFileSaveRangesFull (Process &process,
6341
6373
const MemoryRegionInfos ®ions,
6342
- Process::CoreFileMemoryRanges &ranges) {
6374
+ Process::CoreFileMemoryRanges &ranges,
6375
+ std::set<addr_t > &stack_ends) {
6343
6376
6344
6377
// Don't add only dirty pages, add full regions.
6345
6378
const bool try_dirty_pages = false ;
6346
6379
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);
6348
6382
}
6349
6383
6350
6384
// Save only the dirty pages to the core file. Make sure the process has at
6351
6385
// least some dirty pages, as some OS versions don't support reporting what
6352
6386
// pages are dirty within an memory region. If no memory regions have dirty
6353
6387
// 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
+
6358
6392
// Iterate over the regions and find all dirty pages.
6359
6393
bool have_dirty_page_info = false ;
6360
6394
for (const auto ®ion : regions) {
6361
- if (AddDirtyPages (region, ranges))
6395
+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0 &&
6396
+ AddDirtyPages (region, ranges))
6362
6397
have_dirty_page_info = true ;
6363
6398
}
6364
6399
@@ -6367,7 +6402,8 @@ GetCoreFileSaveRangesDirtyOnly(Process &process,
6367
6402
// plug-in so fall back to any region with write access permissions.
6368
6403
const bool try_dirty_pages = false ;
6369
6404
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)
6371
6407
AddRegion (region, try_dirty_pages, ranges);
6372
6408
}
6373
6409
}
@@ -6380,43 +6416,18 @@ GetCoreFileSaveRangesDirtyOnly(Process &process,
6380
6416
// dirty regions as this will make the core file smaller. If the process
6381
6417
// doesn't support dirty regions, then it will fall back to adding the full
6382
6418
// 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 ;
6387
6423
// Some platforms support annotating the region information that tell us that
6388
6424
// it comes from a thread stack. So look for those regions first.
6389
6425
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 ;
6394
6426
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)
6397
6430
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
- }
6420
6431
}
6421
6432
}
6422
6433
@@ -6428,23 +6439,27 @@ Status Process::CalculateCoreFileSaveRanges(lldb::SaveCoreStyle core_style,
6428
6439
return err;
6429
6440
if (regions.empty ())
6430
6441
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);
6431
6448
6432
6449
switch (core_style) {
6433
6450
case eSaveCoreUnspecified:
6434
- err = Status (" callers must set the core_style to something other than "
6435
- " eSaveCoreUnspecified" );
6436
6451
break ;
6437
6452
6438
6453
case eSaveCoreFull:
6439
- GetCoreFileSaveRangesFull (*this , regions, ranges);
6454
+ GetCoreFileSaveRangesFull (*this , regions, ranges, stack_ends );
6440
6455
break ;
6441
6456
6442
6457
case eSaveCoreDirtyOnly:
6443
- GetCoreFileSaveRangesDirtyOnly (*this , regions, ranges);
6458
+ GetCoreFileSaveRangesDirtyOnly (*this , regions, ranges, stack_ends );
6444
6459
break ;
6445
6460
6446
6461
case eSaveCoreStackOnly:
6447
- GetCoreFileSaveRangesStackOnly (*this , regions, ranges);
6462
+ GetCoreFileSaveRangesStackOnly (*this , regions, ranges, stack_ends );
6448
6463
break ;
6449
6464
}
6450
6465
0 commit comments