@@ -6335,16 +6335,51 @@ static void AddRegion(const MemoryRegionInfo ®ion, bool try_dirty_pages,
6335
6335
ranges.push_back (CreateCoreFileMemoryRange (region));
6336
6336
}
6337
6337
6338
+ static void
6339
+ SaveOffRegionsWithStackPointers (Process &process,
6340
+ const MemoryRegionInfos ®ions,
6341
+ Process::CoreFileMemoryRanges &ranges,
6342
+ std::set<addr_t > &stack_ends) {
6343
+ const bool try_dirty_pages = true ;
6344
+
6345
+ // Before we take any dump, we want to save off the used portions of the stacks
6346
+ // and mark those memory regions as saved. This prevents us from saving the unused portion
6347
+ // of the stack below the stack pointer. Saving space on the dump.
6348
+ for (lldb::ThreadSP thread_sp : process.GetThreadList ().Threads ()) {
6349
+ if (!thread_sp)
6350
+ continue ;
6351
+ StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex (0 );
6352
+ if (!frame_sp)
6353
+ continue ;
6354
+ RegisterContextSP reg_ctx_sp = frame_sp->GetRegisterContext ();
6355
+ if (!reg_ctx_sp)
6356
+ continue ;
6357
+ const addr_t sp = reg_ctx_sp->GetSP ();
6358
+ const size_t red_zone = process.GetABI ()->GetRedZoneSize ();
6359
+ lldb_private::MemoryRegionInfo sp_region;
6360
+ if (process.GetMemoryRegionInfo (sp, sp_region).Success ()) {
6361
+ const size_t stack_head = (sp - red_zone);
6362
+ const size_t stack_size = sp_region.GetRange ().GetRangeEnd () - stack_head;
6363
+ sp_region.GetRange ().SetRangeBase (stack_head);
6364
+ sp_region.GetRange ().SetByteSize (stack_size);
6365
+ stack_ends.insert (sp_region.GetRange ().GetRangeEnd ());
6366
+ AddRegion (sp_region, try_dirty_pages, ranges);
6367
+ }
6368
+ }
6369
+ }
6370
+
6338
6371
// Save all memory regions that are not empty or have at least some permissions
6339
6372
// for a full core file style.
6340
6373
static void GetCoreFileSaveRangesFull (Process &process,
6341
6374
const MemoryRegionInfos ®ions,
6342
- Process::CoreFileMemoryRanges &ranges) {
6375
+ Process::CoreFileMemoryRanges &ranges,
6376
+ std::set<addr_t > &stack_ends) {
6343
6377
6344
6378
// Don't add only dirty pages, add full regions.
6345
6379
const bool try_dirty_pages = false ;
6346
6380
for (const auto ®ion : regions)
6347
- AddRegion (region, try_dirty_pages, ranges);
6381
+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0 )
6382
+ AddRegion (region, try_dirty_pages, ranges);
6348
6383
}
6349
6384
6350
6385
// Save only the dirty pages to the core file. Make sure the process has at
@@ -6354,11 +6389,14 @@ const bool try_dirty_pages = false;
6354
6389
static void
6355
6390
GetCoreFileSaveRangesDirtyOnly (Process &process,
6356
6391
const MemoryRegionInfos ®ions,
6357
- Process::CoreFileMemoryRanges &ranges) {
6392
+ Process::CoreFileMemoryRanges &ranges,
6393
+ std::set<addr_t > &stack_ends) {
6394
+
6358
6395
// Iterate over the regions and find all dirty pages.
6359
6396
bool have_dirty_page_info = false ;
6360
6397
for (const auto ®ion : regions) {
6361
- if (AddDirtyPages (region, ranges))
6398
+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0
6399
+ && AddDirtyPages (region, ranges))
6362
6400
have_dirty_page_info = true ;
6363
6401
}
6364
6402
@@ -6367,7 +6405,8 @@ GetCoreFileSaveRangesDirtyOnly(Process &process,
6367
6405
// plug-in so fall back to any region with write access permissions.
6368
6406
const bool try_dirty_pages = false ;
6369
6407
for (const auto ®ion : regions)
6370
- if (region.GetWritable () == MemoryRegionInfo::eYes)
6408
+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0
6409
+ && region.GetWritable () == MemoryRegionInfo::eYes)
6371
6410
AddRegion (region, try_dirty_pages, ranges);
6372
6411
}
6373
6412
}
@@ -6383,48 +6422,17 @@ GetCoreFileSaveRangesDirtyOnly(Process &process,
6383
6422
static void
6384
6423
GetCoreFileSaveRangesStackOnly (Process &process,
6385
6424
const MemoryRegionInfos ®ions,
6386
- Process::CoreFileMemoryRanges &ranges) {
6425
+ Process::CoreFileMemoryRanges &ranges,
6426
+ std::set<addr_t > &stack_ends) {
6427
+ const bool try_dirty_pages = true ;
6387
6428
// Some platforms support annotating the region information that tell us that
6388
6429
// it comes from a thread stack. So look for those regions first.
6389
6430
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
6431
for (const auto ®ion : regions) {
6395
- if (region.IsStackMemory () == MemoryRegionInfo::eYes) {
6396
- stack_bases.insert (region.GetRange ().GetRangeBase ());
6397
- 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
- const size_t red_zone = process.GetABI ()->GetRedZoneSize ();
6414
- lldb_private::MemoryRegionInfo sp_region;
6415
- if (process.GetMemoryRegionInfo (sp, sp_region).Success ()) {
6416
- // Only add this region if not already added above. If our stack pointer
6417
- // is pointing off in the weeds, we will want this range.
6418
- if (stack_bases.count (sp_region.GetRange ().GetRangeBase ()) == 0 ) {
6419
- // Take only the start of the stack to the stack pointer and include the redzone.
6420
- // Because stacks grow 'down' to include the red_zone we have to subtract it from the sp.
6421
- const size_t stack_head = (sp - red_zone);
6422
- const size_t stack_size = sp_region.GetRange ().GetRangeEnd () - (stack_head);
6423
- sp_region.GetRange ().SetRangeBase (stack_head);
6424
- sp_region.GetRange ().SetByteSize (stack_size);
6425
- AddRegion (sp_region, try_dirty_pages, ranges);
6426
- }
6427
- }
6432
+ // Save all the stack memory ranges not associated with a stack pointer.
6433
+ if (stack_ends.count (region.GetRange ().GetRangeEnd ()) == 0
6434
+ && region.IsStackMemory () == MemoryRegionInfo::eYes)
6435
+ AddRegion (region, try_dirty_pages, ranges);
6428
6436
}
6429
6437
}
6430
6438
@@ -6436,23 +6444,27 @@ Status Process::CalculateCoreFileSaveRanges(lldb::SaveCoreStyle core_style,
6436
6444
return err;
6437
6445
if (regions.empty ())
6438
6446
return Status (" failed to get any valid memory regions from the process" );
6447
+ if (core_style == eSaveCoreUnspecified)
6448
+ return Status (" callers must set the core_style to something other than "
6449
+ " eSaveCoreUnspecified" );
6450
+
6451
+ std::set<addr_t > stack_ends;
6452
+ SaveOffRegionsWithStackPointers (*this , regions, ranges, stack_ends);
6439
6453
6440
6454
switch (core_style) {
6441
6455
case eSaveCoreUnspecified:
6442
- err = Status (" callers must set the core_style to something other than "
6443
- " eSaveCoreUnspecified" );
6444
6456
break ;
6445
6457
6446
6458
case eSaveCoreFull:
6447
- GetCoreFileSaveRangesFull (*this , regions, ranges);
6459
+ GetCoreFileSaveRangesFull (*this , regions, ranges, stack_ends );
6448
6460
break ;
6449
6461
6450
6462
case eSaveCoreDirtyOnly:
6451
- GetCoreFileSaveRangesDirtyOnly (*this , regions, ranges);
6463
+ GetCoreFileSaveRangesDirtyOnly (*this , regions, ranges, stack_ends );
6452
6464
break ;
6453
6465
6454
6466
case eSaveCoreStackOnly:
6455
- GetCoreFileSaveRangesStackOnly (*this , regions, ranges);
6467
+ GetCoreFileSaveRangesStackOnly (*this , regions, ranges, stack_ends );
6456
6468
break ;
6457
6469
}
6458
6470
0 commit comments