Recent

Author Topic: External SIGSEGV when using System.move  (Read 6009 times)

safa

  • New Member
  • *
  • Posts: 17
External SIGSEGV when using System.move
« on: January 07, 2016, 10:07:33 pm »
Hi, I'm using System.Move function to copy data from a memoryStream to a pointer, this way:
Code: Pascal  [Select][+][-]
  1. data:=fpmmap(nil,filesize,prot_read or prot_write, map_shared, fp, 0);
  2. IDHTTP1.Get(url, stream);
  3. System.move(stream,data^,fileSize);
  4. fpMunmap(data,fileSize);  
data is declared as a pointer, stream is a TMemoryStream, when I execute the code, I get the exception External SIGSEGV, ans the windows of the assembler shows SYSTEM_MOVE, what's wrong with my code?
It's never too late, it's never too early, it's always the right moment.

GetMem

  • Hero Member
  • *****
  • Posts: 3753
Re: External SIGSEGV when using System.move
« Reply #1 on: January 07, 2016, 10:29:34 pm »
Did you know there is a Stream.Memory pointer? Why don't you use it?

Code: Pascal  [Select][+][-]
  1. IDHTTP1.Get(Url, Stream);
  2. if Stream.Size > 0
  3. begin
  4.   Stream.Postion := 0;
  5.   System.Move(Stream.Memory^, Data^, Stream.Size);
  6. end;
or
Code: Pascal  [Select][+][-]
  1. IDHTTP1.Get(Url, Stream);
  2. if Stream.Size > 0
  3. begin
  4.   Stream.Postion := 0;
  5.   Stream.ReadBuffer(Data^, Stream.Size);
  6. end;

safa

  • New Member
  • *
  • Posts: 17
Re: External SIGSEGV when using System.move
« Reply #2 on: January 07, 2016, 11:32:24 pm »
I'm getting the same error  :(
It's never too late, it's never too early, it's always the right moment.

Cyrax

  • Hero Member
  • *****
  • Posts: 830
Re: External SIGSEGV when using System.move
« Reply #3 on: January 07, 2016, 11:36:06 pm »
Try to change file mapping functions to instance of TFileStream class.

GetMem

  • Hero Member
  • *****
  • Posts: 3753
Re: External SIGSEGV when using System.move
« Reply #4 on: January 08, 2016, 06:46:27 am »
Perhaps we can help, if you describe what exactly are you trying to achieve. Did you see your other memory mapping related thread?
http://forum.lazarus.freepascal.org/index.php/topic,31000.msg197811.html#msg197811

safa

  • New Member
  • *
  • Posts: 17
Re: External SIGSEGV when using System.move
« Reply #5 on: January 08, 2016, 06:16:22 pm »
Perhaps we can help, if you describe what exactly are you trying to achieve. Did you see your other memory mapping related thread?
http://forum.lazarus.freepascal.org/index.php/topic,31000.msg197811.html#msg197811
In fact, I took a look at your suggestions (windows map file), and I'm about to try the code in my app.
I want to create a multi-plateforme application that requires using map file, so I need to know how to create a map file in windows and linux. Now the thing is: creating a map file in windows is not a problem unless when I use Lazarus, it's a bit different that's why I posted my question, creating a map file in Debian is a bit difficult because I couldn't find a useful tutorial online, except this one : http://www.freepascal.org/docs-html/rtl/baseunix/fpmmap.html , but it shows only how to create a map file, it doesnt show how a secondary thread opens a view and writes data in it, cause in my app: the map file is created by  a main thread, then this one sends the map file to secondary threads, these threads write data simultaneously using views.
Now, there are some tutos available in C, I'll try to translate them.
Well, i'm gonna start with creating the map file in windows (I'm gonna help myself with your suggestions), then I'll turn to Debian, that's the whole thing.
I whish I was clear in my explanation
It's never too late, it's never too early, it's always the right moment.

GetMem

  • Hero Member
  • *****
  • Posts: 3753
Re: External SIGSEGV when using System.move
« Reply #6 on: January 08, 2016, 06:35:08 pm »
Hi safa,

Quote

I whish I was clear in my explanation
Yes, it's clear now! I saw that you try to download something from the net, with indy, then map it to a memory file. To simulate your situation, I created a small php script, wich returns a json, nothing fancy here:
Code: PHP  [Select][+][-]
  1. <?php
  2.   class People {
  3.      public $FName = "";
  4.      public $LName = "";      
  5.      public $Age = "";
  6.   }
  7.        
  8.   $People = new People();
  9.   $People->FName = "John";
  10.   $People->LName  = "Smith";  
  11.   $People->Age = "29";
  12.  
  13.   echo json_encode($People);
  14. ?>
Save the script as "Lazarus.php", then copy to your local/remote htdocs folder. Make sure the server is running.
Now from lazarus(this is for linux, not windows):
Code: Pascal  [Select][+][-]
  1. uses BaseUnix, Unix;
  2.  
  3. function GetDataFromURL(const AURL: String; var AMs: TMemoryStream): Boolean;
  4. var
  5.   IdHTTP: TIdHTTP;
  6. begin
  7.   Result := False;
  8.   IdHTTP := TIdHTTP.Create(nil);
  9.   try
  10.     IdHTTP.Get(AURL, AMs);
  11.     Result := AMs.Size > 0;
  12.     if Result then
  13.       AMs.Position := 0;
  14.   finally
  15.     IdHTTP.Free;
  16.   end;
  17. end;
  18.  
  19. function WriteTextToFile(const AFileName, AText: String): Boolean;
  20. var
  21.   Len: LongInt;
  22.   hFile: CInt;
  23. begin
  24.   Result := False;
  25.   hFile := fpOpen(AFileName, O_WRONLY or O_CREAT);
  26.   if hFile <> -1 then
  27.   begin
  28.     Len := Length(AText);
  29.     Result := fpWrite(hfile, AText[1], Len) > -1;
  30.     FpClose(hFile);
  31.   end;
  32. end;
  33.  
  34. procedure TForm1.Button1Click(Sender: TObject);
  35. var
  36.   URL, FileName: String;
  37.   Ms: TMemoryStream;
  38.   Str: String;
  39.   hFile: CInt;
  40.   Len: LongInt;
  41.   mMap: Pointer;
  42. begin
  43.   URL := 'http://localhost/Lazarus.php';
  44.   FileName := ExtractFilePath(Application.ExeName) + 'test.txt';
  45.   Ms := TMemoryStream.Create;
  46.   try
  47.     if GetDataFromURL(URL, Ms) then
  48.     begin
  49.        Len := Ms.Size div SizeOf(Char);
  50.        SetLength(Str, Len);
  51.        Move(MS.Memory^, Pointer(Str)^, Len);
  52.        if WriteTextToFile(FileName, Str) then
  53.        begin
  54.          hFile := fpOpen(FileName, O_RDWR OR O_SYNC);
  55.          if hFile <> -1  then
  56.          begin
  57.            mMap := fpmmap(nil, Ms.Size, PROT_READ or PROT_WRITE, MAP_SHARED, hFile, 0);
  58.            if LongInt(mMap) <> -1 then
  59.            begin
  60.               ShowMessage('Memory mapped file succesfully created!');
  61.               //do whatever you have to do with the memory file
  62.               fpMUnMap(mMap, Len);
  63.             end;
  64.            fpClose(hFile);
  65.           end;
  66.        end;
  67.     end;
  68.   finally
  69.     Ms.Free;
  70.   end;
  71. end;

The map file is successfully created, you have to implement the parallel access from other thread/process.

Quote
Now, there are some tutos available in C, I'll try to translate them.
Yes, I agree. For linux, you will have to translate a few things from C

Hope this helps!
regards,
GetMem
« Last Edit: January 08, 2016, 08:28:30 pm by GetMem »

safa

  • New Member
  • *
  • Posts: 17
Re: External SIGSEGV when using System.move
« Reply #7 on: January 09, 2016, 11:39:04 am »
The map file is successfully created, you have to implement the parallel access from other thread/process.
Yes, it works fine, so what I understood is that:
Code: Pascal  [Select][+][-]
  1. hFile := fpOpen(FileName, O_RDWR OR O_SYNC);
:opens a local file.
Code: Pascal  [Select][+][-]
  1. mMap := fpmmap(nil, Ms.Size, PROT_READ or PROT_WRITE, MAP_SHARED, hFile, 0);
:creates the map file.
well, thats is what the principal thread is supposed to do, in windows it's something like:
Code: Pascal  [Select][+][-]
  1.  FHandle := CreateFile(PChar(FileName), FILE_READ_DATA or FILE_WRITE_DATA, 0, nil, CREATE_ALWAYS, 0, 0);
Code: Pascal  [Select][+][-]
  1. hMap := CreateFileMapping(FHandle, nil, PAGE_READWRITE, 0, 0, nil);
, where   FHandle type is: hFile, and hMap type is THandle.
So you showed me how to create a map file using a local file. And know I have to implement this in Linux:
Code: Pascal  [Select][+][-]
  1. Http.Request.Range := Format('%d-%d',[View.Offset, View.Offset +View.Size -1]);
  2. Data := MapViewOfFile(MapFile, FILE_MAP_WRITE, View.HiOffset, View.LoOffset, View.Size);
  3. Http.Get(URL, Stream);
  4. CopyMemory(Data, Stream.Memory, View.Size);
  5. UnmapViewOfFile(Data);
And it's all about:
Code: Pascal  [Select][+][-]
  1. Data := MapViewOfFile(MapFile, FILE_MAP_WRITE, View.HiOffset, View.LoOffset, View.Size);
Now, it's getting clearer, about SIGSEG exception, I guess I figured things out, this exception is raised when DATA is not assigned, and it wasn't because of the value of 'fp'.
And, now I'm getting the same error when trying the code above on Windows.Of course the exception is relevant to:
Code: Pascal  [Select][+][-]
  1. Data := MapViewOfFile(MapFile, FILE_MAP_WRITE, View.HiOffset, View.LoOffset, View.Size);
But I can't figure things out. If you'd like to help, I'll post the code.
« Last Edit: January 09, 2016, 01:54:54 pm by safa »
It's never too late, it's never too early, it's always the right moment.

matthius

  • Full Member
  • ***
  • Posts: 107
  • Creating VRAD...
    • LIBERLOG - Développement rapide
Re: External SIGSEGV when using System.move
« Reply #8 on: April 02, 2016, 08:44:17 pm »
External SIGSEGV when using System.move on www.extended.in on Linux i386.
« Last Edit: April 02, 2016, 09:34:19 pm by matthius »
M. GIROUX
13 rue Tanguy PRIGENT
35000 RENNES - France
(33)(0)2 23 46 06 54
http://liberlog.fr

ab1jx

  • New Member
  • *
  • Posts: 23
    • Just some photos on Nikonians
Re: External SIGSEGV when using System.move
« Reply #9 on: May 06, 2016, 06:11:15 am »
A SIGSEGV is because you tried to access memory that wasn't allocated to the process.  Usually due to a bad pointer, buffer overrun, too high a subscript in an array, etc.  If it dumped core you should be able to tell from that.

matthius

  • Full Member
  • ***
  • Posts: 107
  • Creating VRAD...
    • LIBERLOG - Développement rapide
Re: External SIGSEGV when using System.move
« Reply #10 on: August 30, 2016, 08:09:08 pm »
OK
M. GIROUX
13 rue Tanguy PRIGENT
35000 RENNES - France
(33)(0)2 23 46 06 54
http://liberlog.fr

 

TinyPortal © 2005-2018