Recent

Author Topic: Exploring Memory Layout of Program  (Read 4971 times)

Aruna

  • Hero Member
  • *****
  • Posts: 597
Exploring Memory Layout of Program
« on: December 26, 2024, 03:43:32 am »
Hello everyone, Happy Christmas to y'all.  I wanted to explore how the program is laid out in memory so put this together. It works as expected but takes a considerable time before the data is loaded into the TMemo. It takes almost 10 seconds on my hardware. Is there a way to have an indication that data is still being collected/processed or a way to speed up this rather large delay? A screenshot is attached.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Process;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     ButtonRunObjdump: TButton;
  16.     MemoOutput: TMemo;
  17.     procedure ButtonRunObjdumpClick(Sender: TObject);
  18.   private
  19.     procedure RunObjdump(const FilePath: string);
  20.   public
  21.  
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. procedure TForm1.ButtonRunObjdumpClick(Sender: TObject);
  34. var
  35.   FilePath: string;
  36. begin
  37.   // Specify the binary file to analyze
  38.   FilePath := '/home/aruna/lazarus/memoryLayout/project1';
  39.   if FileExists(FilePath) then
  40.     RunObjdump(FilePath)
  41.   else
  42.     MemoOutput.Lines.Add('File not found: ' + FilePath);
  43. end;
  44.  
  45. procedure TForm1.RunObjdump(const FilePath: string);
  46. var
  47.   Output: string;
  48.   Command: string;
  49. begin
  50.   MemoOutput.Clear; // Clear previous output
  51.   Command := 'objdump -d --section=.text ' + FilePath;
  52.  
  53.   try
  54.     if RunCommand('/bin/bash', ['-c', Command], Output) then
  55.       MemoOutput.Lines.Text := Output // Display the output in TMemo
  56.     else
  57.       MemoOutput.Lines.Add('Error: Failed to run objdump.');
  58.   except
  59.     on E: Exception do
  60.       MemoOutput.Lines.Add('Exception: ' + E.Message);
  61.   end;
  62. end;
  63.  
  64. end.
« Last Edit: December 26, 2024, 03:45:48 am by Aruna »

Fibonacci

  • Hero Member
  • *****
  • Posts: 653
  • Internal Error Hunter
Re: Exploring Memory Layout of Program
« Reply #1 on: December 26, 2024, 03:58:13 am »
https://www.freepascal.org/docs-html/rtl/classes/tthread.executeinthread.html
https://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial

Basically, all you need to do is to execute your code via TThread.CreateAnonymousThread

Code: Pascal  [Select][+][-]
  1. procedure TForm1.RunObjdump(const FilePath: string);
  2. var
  3.   Output: string;
  4.   Command: string;
  5. begin
  6.   form1.Caption := 'working...';
  7.  
  8.   TThread.CreateAnonymousThread(procedure
  9.   begin
  10.     MemoOutput.Clear; // Clear previous output
  11.     Command := 'objdump -d --section=.text ' + FilePath;
  12.  
  13.     try
  14.       if RunCommand('/bin/bash', ['-c', Command], Output) then
  15.         MemoOutput.Lines.Text := Output // Display the output in TMemo
  16.       else
  17.         MemoOutput.Lines.Add('Error: Failed to run objdump.');
  18.     except
  19.       on E: Exception do
  20.         MemoOutput.Lines.Add('Exception: ' + E.Message);
  21.     end;
  22.  
  23.     form1.Caption := 'done';
  24.   end);
  25. end;

Add a modeswitch

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. {$modeswitch anonymousfunctions}  

Aruna

  • Hero Member
  • *****
  • Posts: 597
Re: Exploring Memory Layout of Program
« Reply #2 on: December 26, 2024, 04:41:46 am »
https://www.freepascal.org/docs-html/rtl/classes/tthread.executeinthread.html
https://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial

Basically, all you need to do is to execute your code via TThread.CreateAnonymousThread
Hi @Fibonacci, thank you very much. Your code was missing a closing bracket which I plugged in and when I tried it choked with errors.
The first screenshot shows the mode switch error. I commented it out and re-ran and the second screenshot shows the error.

Fibonacci

  • Hero Member
  • *****
  • Posts: 653
  • Internal Error Hunter
Re: Exploring Memory Layout of Program
« Reply #3 on: December 26, 2024, 05:00:22 am »
The latest version of FPC is required to use the anonymous functions feature. Otherwise just use regular way of multithreading, please refer to the second link I gave. A little more work to do.

I suggest installing FPC 3.3.1 using this awesome tool: https://github.com/LongDirtyAnimAlf/fpcupdeluxe/releases/tag/v2.4.0f

Your code was missing a closing bracket

Where?

Aruna

  • Hero Member
  • *****
  • Posts: 597
Re: Exploring Memory Layout of Program
« Reply #4 on: December 27, 2024, 04:48:20 am »
The latest version of FPC is required to use the anonymous functions feature. Otherwise just use regular way of multithreading, please refer to the second link I gave. A little more work to do.

I suggest installing FPC 3.3.1 using this awesome tool: https://github.com/LongDirtyAnimAlf/fpcupdeluxe/releases/tag/v2.4.0f

Your code was missing a closing bracket

Where?
My apologies I made a mistake there was no missing bracket. I am attaching a zip contaning full source and a screenshot that shows the time it takes to complete the process. I am running Free Pascal Compiler version 3.2.2 [2021/07/09] for x86_64 so it should work but chokes. I would be grateful if you would try to compile and run my zip and see where I may be going wrong. Thank you.

Fibonacci

  • Hero Member
  • *****
  • Posts: 653
  • Internal Error Hunter
Re: Exploring Memory Layout of Program
« Reply #5 on: December 27, 2024, 10:36:20 am »
It would be much easier for you if you updated your FPC. You are missing new features.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Process;
  9.  
  10. type
  11.   TForm1 = class(TForm)
  12.     ButtonRunObjdump: TButton;
  13.     MemoOutput: TMemo;
  14.     procedure ButtonRunObjdumpClick(Sender: TObject);
  15.   private
  16.     procedure RunObjdump(const FilePath: string);
  17.   public
  18.  
  19.   end;
  20.  
  21.   TThread1 = class(TThread)
  22.   private
  23.     q: QWord;
  24.   protected
  25.     procedure Execute; override;
  26.     procedure Done;
  27.   public
  28.     command: string;
  29.     memo: string;
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. procedure TThread1.Execute;
  40. var
  41.   Output: string;
  42. begin
  43.   q := GetTickCount64;
  44.  
  45.   try
  46.     {$ifdef MSWINDOWS}
  47.     if RunCommand('cmd', ['/c '+command], Output, [], swoHIDE) then
  48.     {$else MSWINDOWS}
  49.     if RunCommand('/bin/bash', ['-c', Command], Output) then
  50.     {$endif}
  51.       memo := Output
  52.     else
  53.       memo := 'Error: Failed to run objdump.';
  54.   except
  55.     on E: Exception do memo := 'Exception: ' + E.Message;
  56.   end;
  57.  
  58.   Synchronize(@Done);
  59. end;
  60.  
  61. procedure TThread1.Done;
  62. begin
  63.   Form1.MemoOutput.Lines.Text := memo;
  64.   Form1.Caption := 'Done in '+inttostr(GetTickCount64-q)+' ms.';
  65.   Form1.ButtonRunObjdump.Enabled := true;
  66. end;
  67.  
  68. procedure TForm1.ButtonRunObjdumpClick(Sender: TObject);
  69. var
  70.   FilePath: string;
  71. begin
  72.   // Specify the binary file to analyze
  73.   {$ifdef MSWINDOWS}
  74.   FilePath := 'C:\Windows\System32\notepad.exe';
  75.   {$else MSWINDOWS}
  76.   FilePath := '/home/aruna/lazarus/memoryLayout/project1';
  77.   {$endif}
  78.  
  79.   if FileExists(FilePath) then
  80.     RunObjdump(FilePath)
  81.   else
  82.     MemoOutput.Lines.Add('File not found: ' + FilePath);
  83. end;
  84.  
  85. procedure TForm1.RunObjdump(const FilePath: string);
  86. var
  87.   Command: string;
  88.   thr: TThread1;
  89. begin
  90.   MemoOutput.Clear; // Clear previous output
  91.  
  92.   //Command := 'objdump -T ' + FilePath; // Construct the objdump command
  93.   //Command := 'objdump -h ' + FilePath; // Construct the objdump command
  94.   //Command := 'file ' + FilePath; // Construct the objdump command
  95.   //Command := 'strings -d ' + FilePath; // Construct the objdump command
  96.   //Command := 'ldd ' + FilePath; // Construct the objdump command
  97.   //Command := 'readelf -d ' + FilePath; // Construct the objdump command
  98.   //Command := '' + FilePath; // Construct the objdump command
  99.   Command := 'objdump -d --section=.text "'+FilePath+'"';
  100.  
  101.   ButtonRunObjdump.Enabled := false;
  102.   MemoOutput.Lines.Add('working...');
  103.  
  104.   thr := TThread1.Create(true);    
  105.   thr.FreeOnTerminate := true;
  106.   thr.command := Command;
  107.   thr.Resume;
  108. end;
  109.  
  110. end.

cdbc

  • Hero Member
  • *****
  • Posts: 1951
    • http://www.cdbc.dk
Re: Exploring Memory Layout of Program
« Reply #6 on: December 27, 2024, 10:52:17 am »
Hey Aruna
Quote
I am running Free Pascal Compiler version 3.2.2 [2021/07/09] for x86_64 so it should work but chokes.
Well, that doesn't do you any good, when the features used in the program, require the *trunk* -compiler(3.3.1) to compile the anonymous stuff...
It is however, pretty easy to set up, with the help of 'FpcUpDeluxe'...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Aruna

  • Hero Member
  • *****
  • Posts: 597
Re: Exploring Memory Layout of Program
« Reply #7 on: December 27, 2024, 02:04:57 pm »
It would be much easier for you if you updated your FPC. You are missing new features.
Is there a way to do this without using FpcUpDeluxe? Some users report issues like incomplete installations, dependency problems, or difficulties when upgrading. If there is a way to upgrade without using FpcUpDeluxe please tell me how?

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Process;
  9.  
  10. type
  11.   TForm1 = class(TForm)
  12.     ButtonRunObjdump: TButton;
  13.     MemoOutput: TMemo;
  14.     procedure ButtonRunObjdumpClick(Sender: TObject);
  15.   private
  16.     procedure RunObjdump(const FilePath: string);
  17.   public
  18.  
  19.   end;
  20.  
  21.   TThread1 = class(TThread)
  22.   private
  23.     q: QWord;
  24.   protected
  25.     procedure Execute; override;
  26.     procedure Done;
  27.   public
  28.     command: string;
  29.     memo: string;
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. procedure TThread1.Execute;
  40. var
  41.   Output: string;
  42. begin
  43.   q := GetTickCount64;
  44.  
  45.   try
  46.     {$ifdef MSWINDOWS}
  47.     if RunCommand('cmd', ['/c '+command], Output, [], swoHIDE) then
  48.     {$else MSWINDOWS}
  49.     if RunCommand('/bin/bash', ['-c', Command], Output) then
  50.     {$endif}
  51.       memo := Output
  52.     else
  53.       memo := 'Error: Failed to run objdump.';
  54.   except
  55.     on E: Exception do memo := 'Exception: ' + E.Message;
  56.   end;
  57.  
  58.   Synchronize(@Done);
  59. end;
  60.  
  61. procedure TThread1.Done;
  62. begin
  63.   Form1.MemoOutput.Lines.Text := memo;
  64.   Form1.Caption := 'Done in '+inttostr(GetTickCount64-q)+' ms.';
  65.   Form1.ButtonRunObjdump.Enabled := true;
  66. end;
  67.  
  68. procedure TForm1.ButtonRunObjdumpClick(Sender: TObject);
  69. var
  70.   FilePath: string;
  71. begin
  72.   // Specify the binary file to analyze
  73.   {$ifdef MSWINDOWS}
  74.   FilePath := 'C:\Windows\System32\notepad.exe';
  75.   {$else MSWINDOWS}
  76.   FilePath := '/home/aruna/lazarus/memoryLayout/project1';
  77.   {$endif}
  78.  
  79.   if FileExists(FilePath) then
  80.     RunObjdump(FilePath)
  81.   else
  82.     MemoOutput.Lines.Add('File not found: ' + FilePath);
  83. end;
  84.  
  85. procedure TForm1.RunObjdump(const FilePath: string);
  86. var
  87.   Command: string;
  88.   thr: TThread1;
  89. begin
  90.   MemoOutput.Clear; // Clear previous output
  91.  
  92.   //Command := 'objdump -T ' + FilePath; // Construct the objdump command
  93.   //Command := 'objdump -h ' + FilePath; // Construct the objdump command
  94.   //Command := 'file ' + FilePath; // Construct the objdump command
  95.   //Command := 'strings -d ' + FilePath; // Construct the objdump command
  96.   //Command := 'ldd ' + FilePath; // Construct the objdump command
  97.   //Command := 'readelf -d ' + FilePath; // Construct the objdump command
  98.   //Command := '' + FilePath; // Construct the objdump command
  99.   Command := 'objdump -d --section=.text "'+FilePath+'"';
  100.  
  101.   ButtonRunObjdump.Enabled := false;
  102.   MemoOutput.Lines.Add('working...');
  103.  
  104.   thr := TThread1.Create(true);    
  105.   thr.FreeOnTerminate := true;
  106.   thr.command := Command;
  107.   thr.Resume;
  108. end;
  109.  
  110. end.
This is perfect and works on my hardware, thank you for taking the time. I also learned something new by studying your code about how to determine which OS am running on. Just out of curiosity if and when you have time would it be posible to have a screenshot of what notepad.exe shows, please? So once again many thanks for fixing one of my needs the form caption shows the total elapsed time and the TMemo now has a 'working...' which is a lot better than my empty one which can make a user think the program has frozen :)

Is there a way to make the time it takes to complete faster? The reason I ask is when I run time objdump -d --section=.text project1 the first screenshot shows you it takes 9.471seconds and when I run the code you sent second screenshot shows 'Done in 18295 ms'. So somewhere we have a bottleneck that maybe we can fix? Or then again maybe not... thank you very much for your code once again I learned many things.

Aruna

  • Hero Member
  • *****
  • Posts: 597
Re: Exploring Memory Layout of Program
« Reply #8 on: December 27, 2024, 02:13:25 pm »
Hey Aruna
Quote
I am running Free Pascal Compiler version 3.2.2 [2021/07/09] for x86_64 so it should work but chokes.
Well, that doesn't do you any good, when the features used in the program, require the *trunk* -compiler(3.3.1) to compile the anonymous stuff...
It is however, pretty easy to set up, with the help of 'FpcUpDeluxe'...
Regards Benny
Hey Benny how are you? Sorry, I missed you the second time on IRC. Please do drop by whenever time permits you to do so. I am usually always in there. I am afraid ( more like very scared ) of ever using git because I had a really bad experience a while ago when I ran 'git reset --hard' I lost all my projects. Code I had written from scratch which took some months. I think there is a post here on the forum about this experience. So if I can avoid git I will do so. That being said *trunk* is the main repo yes? What if I clone and download the main repo and build on my system? Can that work?

cdbc

  • Hero Member
  • *****
  • Posts: 1951
    • http://www.cdbc.dk
Re: Exploring Memory Layout of Program
« Reply #9 on: December 27, 2024, 03:20:41 pm »
Hi
...Yup, MeThinks, that should work, be advised - It will then install *trunk* as your main compiler - so pick a branch that works flawlessly  :D
Good luck

Yeah, I'm doing fine, enjoying the *lack* of frost & snow this christmas, as I say: "Let them have it in the Alps, where it's good for something"  ;D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

 

TinyPortal © 2005-2018