Портирование программ с windows на linux

This article describes some basic specific moments of porting application from Windows to Linux
  • Download BackupMBR_linux — 8.47 KB
  • Download BackupMBR_win — 8.03 KB
  • Download BackupMBR_port_win — 10.03 KB

1. Who is the target reader of this article?

Recently I faced one very interesting task. I had to port an application from one platform (Windows) to another (Linux). It is an interesting topic. First, knowledge of several platforms and writing the code for them is a good experience for every developer. Secondly, writing an application for different platforms makes it widespread and needed by many. So, I would like to share my impressions concerning this process. This article is intended for everybody who wants to write a cross-platform application.

2. Our task

Receiving the project specification, we usually see only one target platform in the “Platforms” section (e.g., Windows) and that is why we enjoy its advantages and disadvantages. Let’s imagine that you receive the task where it is proposed to run the application on the other platform (e.g., Linux). Or imagine that you have to use the code, which was written for one platform, on another platform. From this point you start to face difficulties. You start to plan the porting taking into account all the specifics of the program architecture. And if the architecture was wrong from the very beginning (I mean that it did not expect the porting between the platforms), it can turn out that you have to remake a lot. Let’s examine the example of the code (file attached to this article). This program opens the PhysicalDrive0, acquires MBR and writes it to the file, then defines the disk configuration and saves it to a separate file. The code was written only for Windows with all its consequences.

Please look at the code before reading the article (BackupMBR_win.zip attached to this article). This is the project of VisualStudio2008.

There must be no difficulties in such small example. But you can meet problems even here. The code is very simple and does not require many checks, deletion processing, etc. This code is not a standard but it lets to show what you should do during the porting of your application from Windows OS to Linux OS.

3. Compilers and IDE

When porting from Windows OS to Linux OS is performed, the porting from Microsoft Visual C++ to GCC(G++) is the most commonly used. Many of you may think that GCC and G++ are two different compilers. But it is not so. GCC («GNU C Compiler») was created in 1987 by Richard Stallman and it could compile only C code at that time. With time the compiler developed and supported not only C and C++ codes but also other programming languages. Now the GCC is interpreted as «GNU Compiler Collection». G++ is a part of GCC and is used to compile *.cpp files. GCC is used, in its turn, to compile *.с files. Though, you can compile the *.cpp file using GCC by indicating specific flags. GCC and G++ compile the C++ code in the same way.

Let’s return to the porting from Visual C++ to GCC (G++). It is worth paying attention to the difference between them. GCC is stricter to the standard than the Microsoft compiler. It means that in some situation the GCC compiler returns an error message and does not compile the source code while the Microsoft compiler just returns the warning message. Let’s examine some moments that are frequently met during the porting from Visual C++ to GCC. You can google it but I would like to repeat it myself.

  1. Use #ifndef/#define/#endif instead of #pragma once. GCC understands the #pragma once directive beginning from the version 3.4. That is why check the version of your compiler. If it is lower than 3.4, there is no need to correct the following code during the porting.
#ifndef SOME_HEADER_H
#define SOME_HEADER_H


#endif // SOME_HEADER_H
  1. Used types. During the porting, watch the types you use because GCC doesn’t understand all of them. It is better to create a separate file in the project (e.g., types.h file) and to put there all types that GCC does not understand.
HANDLE   
DWORD    
BYTE     
UINT     
  1. Assembler insertions. Be careful during the porting of ASM insertions to the project for GCC. They have another appearance and syntax. GCC uses AT&T ASM. It differs from Intel ASM, which is used in Visual C++. An example is provided below (the following example is taken from http://asm.sourceforge.net//articles/linasm.html; for more information about AT&T ASM also see this reference).

Intel Syntax

AT&T Syntax

mov al,bl
mov ax,bx
mov eax,ebx
mov eax, dword ptr [ebx]

movb %bl,%al
movw %bx,%ax
movl %ebx,%eax
movl (%ebx),%eax

P.S. For conversion, you can use the Intel2gas utility (see http://www.niksula.hut.fi/~mtiihone/intel2gas/). But to my opinion, it is more convenient only for the high volume of the ASM code. And anyway you should bring the code to the compilable state.

  1. Using the #pragma comment directive (lib, «libname.lib»). It is convenient to hook libraries in the project with the help of this directive in Visual C++. But GCC does not contain such one. That is why, for GCC, you should define the libraries you want to hook in the command line. For example:
g++ -o TestExe.exe *.o -Llib -lm -ldl -w  "lib_1.a" "lib_2.a" "lib_3.a"

As you can see, Linux libraries have *.a extension and not *.lib extension as in Windows OS. Dynamic libraries also have another extension (*.so instead of *.dll) and they link not in such way as in Windows OS. For more information about the types of libraries in Linux OS see http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html.

  1. Macros. Macros in GCC differ from the analogous ones in Visual C++. During the code porting to GСС, check the macros in the code. It’s possible that the implementation of such macro will not be performed. In such situation, it is better to find its implementation in Visual С++ and port it to GCC. The following table provides examples of frequently used macros.
  __DATE__                __DATE__
__FILE__                __FILE__
__LINE__                __LINE__
__STDC__                __STDC__
__TIME__                __TIME__
__TIMESTAMP__            __TIMESTAMP__

__FUNCTION__            __FUNCTION__
                    __PRETTY_FUNCTION__

MSC_VER                __GNUC__
                    __GNUC_MINOR__
                    __GNUC_PATCHLEVEL__

Let’s examine them. The first six macros are implemented in both compilers in the same way and are often used in logging. The differences begin from __FUNCTION__. In Windows OS, it writes not only the name of the function (as in Linux OS) but also the namespace and the class from where the call was performed. Its analog in Linux OS is not __FUNCTION__ but __PRETTY_FUNCTION__. MSC_VER and __GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ also have different types of returned data. For example, MSC_VER = 1500 for Visual C++, for GNU 3.2.2 it is __GNUC__ = 3, __GNUC_MINOR__ = 2, __GNUC_PATCHLEVEL__ = 2.

If the target platform does not include the needed macro, find its implementation and port it. Macro can be also written in ASM (for the code optimization). Do not hurry and rewrite it from Intel to AT&T and vice versa. It is better to check once more if there is its implementation in С++. Also take into account that Linux OS can run on devices with ARM processor. In this case the macro, which was written under AT&T, will not work and you will have to implement it under another type of the processor.

Let’s move to IDE. There are lots of them and you have the possibility to choose. Let’s examine some of them (taking into account that the project was initially written in Visual Studio, our task is to choose IDE for working in Linux OS):

— Code::Blocks (see http://www.codeblocks.org/)

win-linux-porting/code_blocks.screenshot.png

Pic.1 Code::Blocks. Start Page.

It is often proposed as the substitution of Visual Studio for those who port their project to Linux OS. IDE can open Visual Studio projects under Windows OS and Linux OS. I built a project with its help and I can say that it is very convenient.

— Eclipse/CDT (see http://www.eclipse.org/cdt/downloads.php).

win-linux-porting/eclipse.screenshot.png

Pic.2 Eclipse/CDT.

It is another free IDE. If you write in C++, download it together with the CDT plug-in. After installation IDE supports only Java by default and if you install CDT plug-in after, the auto-add-on probably will not work.

— Qt Creator (see http://qt.nokia.com/products/developer-tools).

win-linux-porting/qt_cretor.screenshot.png

Pic.3 QT Creator. Start Page

When I first worked with Linux I used this IDE. Its interface is simple (developers must have followed the example of XCode interface during the development of Qt Creator). And you do not have to use Qt while working in Qt Creator. Just configure the project using the *.pro file (in it, libraries that are statically linked, *.h and *.cpp files, the type of the application are defined).

— Emacs/Vim (see http://www.gnu.org/software/emacs/)

win-linux-porting/emacs.screenshot.png

Pic.4 Emacs. Start Page

This IDE is for experienced developers under Linux OS. The problem of this IDE is that it can take long to learn how to work with Emacs. And the skills are quickly lost, as people say. You will be able to perform the majority of commands by using hot keys or the Emacs command line. Even while opening the file you will be asked to define the file path in the command line. But on the other hand, this tool is very powerful and flexible.

I introduced four IDEs that are the most popular among the developers under Linux OS. For example, I work with QtCreator but there must be no problems while working with other IDEs (do not forget about problems with Emacs). So, it is your time to choose.

I want to add a few words about the debuggers. Sometimes I did not manage to debug the code using the native IDE debugger. That is why I had to search for the alternative. I used two debuggers: Insight and kdbg. I also tried to use ddd debugger but I did not like it. So use the one you like more. With time you will find the one that will meet the maximum of your demands.

4. Porting of the application

Let’s return to the code we examined in the second part. As we can see in the API code, functions are used directly without the wrappers above the API level. You may say that it is not bad: errors are handled, the code works, so why not to leave it as it is? There is a reason not to leave as it is. When you port the application to another platform, there will be one more problem of searching API functions in the code and their replacement. For example, the CreateFileW function (disk opening and creation of the file from the MBR disk) is represented twice in the examined code. And the program is simple in itself. If the project is big and you do not use wrappers above the API level, the code will repeat itself a lot. And it means that you will have to change a lot during the porting to another platform.

That is why the first step is to write the library that contains all used APIs and that implements the methods of working with them. It must also contain all functions specific for the definite platform. Such library will have the necessary interface, and during the porting, you will have to make some corrections only in it.

Let’s examine the schemes that illustrate the thoughts mentioned above. The majority of developers extract the core of their application into the separate libraries (Business Logic) that implement the definite interface. Such library also implements the separate GUI that will use this very library. This is correct, convenient and also it works. But there is one nuance that we just mentioned.

win-linux-porting/platforms_compability_layer.png

There must be the Platform Compatibility Layer for the cross-platform applications. This is the component that will stand between the API level and the core of your application. It is necessary to include the following components in it:

  • working with files;
  • working with sockets;
  • working with ports;
  • ASCII/Unicode
  • Threading API

Let’s start from the very beginning. Let’s try to port our application. We must define the code that will be included in the «Platform Compatibility Layer». The following table displays the comparison between Windows and Linux API.

Table 1. Comparing Linux and Windows API.

Windows API

Linux API

HANDLE WINAPI CreateFileA(
     __in      LPCTSTR lpFileName,
     __in      DWORD dwDesiredAccess,
     __in      DWORD dwShareMode,
     __in_opt LPSECURITY_ATTRIBUTES  lpSecurityAttributes,
     __in      DWORD dwCreationDisposition,
     __in      DWORD dwFlagsAndAttributes,
     __in_opt  HANDLE hTemplateFile)
   int  open(
          const char* name,
          int flags)

int  open(
          const char* name,
          int flags,
          mode_t mode)
BOOL WINAPI ReadFile(
     __in         HANDLE hFile,
     __out        LPVOID lpBuffer,
     __in         DWORD nNumberOfBytesToRead,
     __out_opt    LPDWORD lpNumberOfBytesRead,
     __inout_opt  LPOVERLAPPED lpOverlapped)
ssize_t read(
       int fd,
       void buf*,
       size_t len)
BOOL WINAPI WriteFile(
     __in         HANDLE hFile,
     __in         LPCVOID lpBuffer,
     __in         DWORD nNumberOfBytesToWrite,
     __out_opt    LPDWORD lpNumberOfBytesWritten,
     __inout_opt  LPOVERLAPPED lpOverlapped)
ssize_t write(
       int fd,
       void buf*,
       size_t count)
DWORD SetFilePointer(
     __in         HANDLE hFile,
     __in         LONG lDistanceToMove,
     __inout_opt  PLONG lpDistanceToMoveHigh,
     __in         DWORD dwMoveMethod)
off_t lseek(
       int fd,
       off_t pos,
       int origin)
BOOL CloseHandle(
     __in  HANDLE hObject)
int  close(
           int fd)

The first function that we use is the CreateFileA function. We need it to open the device (in this case, it is PhysycalDrive0). We call it with the following parameters:


HANDLE handle_r = ::CreateFileA("\\.\PhysicalDrive0"
                        , GENERIC_READ 
                        , FILE_SHARE_READ | FILE_SHARE_WRITE
                        , 0
                        , OPEN_EXISTING
                        , FILE_ATTRIBUTE_NORMAL
                    , 0);

With the help of the first parameter we define the path of the device we are opening \\.PhysicalDrive0. In Linux OS, all devices have the format of simple files and are located in the /dev directory. There you can find the required device (it is /dev/sda device in my system). You can define the path to the device on your computer by entering the mount command in Linux terminal. This command is used for device mounting. But such command without any parameters will display all mounted devices in the system. The following example is the example of mount command for my system:

root@ubuntu:/usr/share/man$ mount
    /dev/sda1 on / type ext3 (rw)
    tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
    proc on /proc type proc (rw,noexec,nosuid,nodev)
    ..........................................................................
    securityfs on /sys/kernel/security type securityfs (rw)

Let’s examine the first line, where:

/dev/sda1 — the path to the device file
/ — the path of the mounted filesystem
type ext3 — the filesystem type
rw — read and write permissions.

Hard drives are usually indicated as /dev/sd* and /dev/hd* in Linux OS. If the computer has three hard drives, they will be indicated as /dev/sda, /dev/sdb, /dev/sdc. The number that follows after the name of the hard drive defines the partition number on this drive. To open the disk, use the open() function.

According to the manual, this function juxtaposes the full file path with the descriptor of the file, which it returns. Descriptor is the analog of HANDLE in Windows OS. It can be used for read/write/lseek functions. If you did not manage to open/create a file, the function returns -1. Permission of file access is defined in the flags parameter. For /dev/sda, set the O_RDONLY flag (it is an analog of GENERIC_READ for CreateFileA). For more information about flags see the manual. So, for Linux OS, the open() function will look like the following:


It is more compact than in Windows OS. Now it is necessary to write the function that will be common for Windows and Linux OS. First, let’s define how this function will look like. CreateFileA can be assumed as a basis. There are three parameters out of 7 that do not change in the program:

- DWORD dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
- LPSECURITY_ATTRIBUTES  lpSecurityAttributes = 0
- HANDLE hTemplateFile = 0

As these parameters have the same value, we exclude them from the target function. You may say that we limit the functionality defining one and the same value to some parameters. But we did not change them in the program, those values, which are defined, are enough for us. It means that the function performs the program minimum and can cover the functionality that we need. It is worth defining here how we use one or another API function. The minimum functionality is usually enough. But on the other hand, if we want to set the FILE_SHARE_READ value to the dwSharedMode parameter, we will hit a problem. It is not enough that we must add changes to the function, but also we will have to change the number of parameters in all its calls. That is why it is necessary to define what exactly you want, for example, from CreateFileA and how you will use it. Then it will be clear how the wrapper over this function will look like.

So, we came to conclusion that the function will have 4 parameters. Now we have to confirm them on both platforms. I will port the minimum of them: GENERIC_READ (to open the file for reading) and GENERIC_WRITE (to open the file for writing). These parameters are similar to O_RDONLY and O_WRONLY parameters for the open() function. dwCreationDisposition defines the way of opening the file. I used two values: OPEN_EXISTING (the file opens; if there is no file, the error is returned) and CREATE_ALWAYS (a new file is created; if such file already exists, it is rewritten). There are no such parameters for the open() function. The closest will be the O_CREAT parameter. This flag is used for file creation and corresponds to CREATE_ALWAYS parameter. You don’t need to use the OPEN_EXISTING value for the open() function. You may say that the FILE_ATTRIBUTE_NORMAL value of the dwFlagsAndAttributes also did not change and that we have to exclude it from the parameters. But as it was mentioned earlier, the open() function has one more mode parameter. It defines the file permission, as you remember. Let’s define the FILE_ATTRIBUTE_NORMAL = 0644 parameter (the owner of the file has read and write permissions, others only read permission). It is not right as we cannot define other file permissions but it is enough for porting our application. It is a certain support point. But it is easy to correct: we just find the value correspondence for the necessary parameters for both platforms.

We compared all parameters that are interesting for us and now can start writing the function itself. What is the process of writing? We use the #ifndef/#define/#elif/#endif preprocessor directives. We use the following construction:

#ifdef WIN32
    
#elif __linux__
    
#else 
    #error: unknown OS
#endif

By using this construction, we can single out parts of the code that are specific for a definite platform. With the help of this method you can single out not only the parts of functions but also the whole functions.

int do_something()
{
#ifdef WIN32
    
#elif __linux__
    
#else 
    #error: unknown OS
#endif
}    
#ifdef WIN32
int do_something()
{
    
}
#elif __linux__
int do_something()
{
    
}
#else 
    #error: unknown OS
#endif

As we can see, both methods prove its value. The first one is less readable; the second one contains more code but it is easier to make changes in it. I would advise you to use the second one but it is your right to choose. As an alternative, you can separate off all to the header files.

Let’s look how the function will look like after making all changes in it:


#include "file_io.h"


#ifdef WIN32
    
#elif __linux__
 #include <sys/types.h>

    #include <sys/stat.h>

    #include "unistd.h"

    #include <fcntl.h>


    #define GENERIC_READ                O_RDONLY    //read only mode
    #define GENERIC_WRITE               O_WRONLY    //write only mode
    #define CREATE_ALWAYS               O_CREAT        //create new file
    #define OPEN_EXISTING               0           //fake parameter's value
 #define FILE_ATTRIBUTE_NORMAL     0644          // file attributes
#else
    #error: unknown OS
#endif

#ifdef WIN32 // create_io_file for windows
HANDLE create_io_file(const char* file_name,
           DWORD desired_access,
           DWORD creation_despositions,
           DWORD flags_attributes)
{
        return ::CreateFileA(file_name,
                             desired_access,
                             FILE_SHARE_READ | FILE_SHARE_WRITE,
                             0,
                                creation_despositions,
                                flags_attributes,
                                0);
}
#elif __linux__ // create_io_file for Linux
HANDLE create_io_file(const char* file_name,
                      DWORD desired_access,
                      DWORD creation_despositions,
                      DWORD flags_attributes)
{
    return ::open(file_name,
                  desired_access | creation_despositions,
                  flags_attributes);

}
#else
    #error: unknown OS
#endif

As it can be seen from the code, we took into account everything mentioned above. The received create_io_file wrapper does not implement all the features of CreateFileA and open but it is an example of how you can implement the cross-platform wrapper above the API level. You can port the rest of functions in the same way (see file_io.h/file_io.cpp file).

Besides API, we used DeviceIOControl to receive the disk geometry. The get_drive_info() function is represented below:


bool get_drive_info(HANDLE _handle, drive_info &mp;drive_info_)
{
    DWORD size_ = 0;
    BOOL is_accessible_ =
        ::DeviceIoControl(_handle
        , IOCTL_STORAGE_CHECK_VERIFY
        , 0
        , 0
        , 0
        , 0
        , &size_
        , 0);

    if (!is_accessible_)
    {
        return false;
    }

    DISK_GEOMETRY disk_geometry_;
    ::memset(&disk_geometry_, 0, sizeof disk_geometry_);

    BOOL is_geometry_ =
        ::DeviceIoControl(_handle
        , IOCTL_DISK_GET_DRIVE_GEOMETRY
        , 0
        , 0
        , &disk_geometry_
        , sizeof disk_geometry_
        , &size_
        , 0);

    if (!is_geometry_)
    {
        return false;
    }

    drive_info_._cylinder = disk_geometry_.Cylinders.QuadPart;
    drive_info_._type = fixed;
    drive_info_._tracks_per_cylinder = disk_geometry_.TracksPerCylinder;
    drive_info_._sectors_per_track = disk_geometry_.SectorsPerTrack;
    drive_info_._bytes_per_sector = disk_geometry_.BytesPerSector;

        drive_info_._lba_size = drive_info_._cylinder
           * drive_info_._bytes_per_sector
           * drive_info_._sectors_per_track
           * drive_info_._tracks_per_cylinder;

       return true;
}

There is an analog of DeviceIOControl in Linux. It is the ioctl function, which receives the device descriptor and can return the requested information about it. By calling DeviceIOControl with the IOCTL_DISK_GET_DRIVE_GEOMETRY parameter we receive the DISK_GEOMETRY structure as a result. It looks like the following:

typedef struct _DISK_GEOMETRY {
    LARGE_INTEGER Cylinders;
    MEDIA_TYPE MediaType;
    DWORD TracksPerCylinder;
    DWORD SectorsPerTrack;
    DWORD BytesPerSector;
} DISK_GEOMETRY, *PDISK_GEOMETRY;

To receive the similar structure with the disk geometry in Linux, call the ioctl function with the HDIO_GETGEO parameter and reference the following structure:

struct hd_geometry {
      unsigned char heads;
      unsigned char sectors;
      unsigned short cylinders;
      unsigned long start;
};

Having compared the structures, we notice the absence of one of the fields. The hd_geometry structure does not contain the BytesPerSector value. This can be corrected by calling the ioctl function with the BLKSSZGET parameter, which according to Linux sources returns the block device sector size. These are the specifics of porting this function. The final variant looks like the following:


#ifdef WIN32
bool get_drive_info(HANDLE _handle, drive_info &drive_info_)
{
    DWORD size_ = 0;
    BOOL is_accessible_ =
        ::DeviceIoControl(_handle
        , IOCTL_STORAGE_CHECK_VERIFY
        , 0
        , 0
        , 0
        , 0
        , &size_
        , 0);

    if (!is_accessible_)
    {
        return false;
    }

    DISK_GEOMETRY disk_geometry_;
    ::memset(&disk_geometry_, 0, sizeof disk_geometry_);

    BOOL is_geometry_ =
        ::DeviceIoControl(_handle
        , IOCTL_DISK_GET_DRIVE_GEOMETRY
        , 0
        , 0
        , &disk_geometry_
        , sizeof disk_geometry_
        , &size_
        , 0);

    if (!is_geometry_)
    {
        return false;
    }

    drive_info_._cylinder = disk_geometry_.Cylinders.QuadPart;
    drive_info_._type = fixed;
    drive_info_._tracks_per_cylinder = disk_geometry_.TracksPerCylinder;
    drive_info_._sectors_per_track = disk_geometry_.SectorsPerTrack;
    drive_info_._bytes_per_sector = disk_geometry_.BytesPerSector;

    drive_info_._lba_size = drive_info_._cylinder
        * drive_info_._bytes_per_sector
        * drive_info_._sectors_per_track
        * drive_info_._tracks_per_cylinder;

    return true;
}

#elif __linux__
bool get_drive_info(HANDLE _handle, drive_info &drive_info_)
{
    struct hd_geometry geometry;
    ::memset(&geometry, 0, sizeof geometry);

    int result = ioctl(_handle, HDIO_GETGEO, &geometry);

    if (result < 0)
    {
        std::cout<<"ioctl error";
        return false;
    }


    drive_info_._cylinder = geometry.cylinders;
    drive_info_._type = fixed;
    drive_info_._tracks_per_cylinder = geometry.heads;
    drive_info_._sectors_per_track = geometry.sectors;


    long sector_size = 0;
    result = ioctl(_handle, BLKSSZGET, &sector_size); 

    if (result < 0)
    {
        std::cout<<"ioctl error";
        return false;
    }

    drive_info_._bytes_per_sector = sector_size;

    drive_info_._lba_size = drive_info_._cylinder
        * drive_info_._bytes_per_sector
        * drive_info_._sectors_per_track
        * drive_info_._tracks_per_cylinder;

    return true;
}

#else
    #error: unknown OS
#endif

There is one more function left. It is the store_drive_geometry function but it does not require the change of the code. It can be easily ported. Such effect can be achieved by using STL (see http://cplusplus.com), boost (see http://boost.org) or Qt libraries. All these libraries are cross-platform and allow writing the easily ported code. For example, in STL, the wrapper above the API level is already implemented for the work with files and the library is already cross-platform. So pay attention to using such libraries. It can make your work easier.

5. Windows->Linux. A few words

We examined only one of many components from the list that change during the porting. I would like to say a few words about the rest of them.

ASCII/Unicode. Here we can meet problems because the size of the wchar_t type in Windows is twice smaller than in Linux (2 bytes in Windows and 4 bytes in Linux). The reason is that Linux uses UTF-32 character encoding and Windows — UCS-2. The difference in character encodings can be solved by setting the GCC flag during the compilation:

-fshort-wchar

Attention should be paid to all char <-> wchar_t conversions and to the use of Unicode during the transfer between systems.

Threading API. It is better to implement it using boost or Qt libraries. It means that the work with threads has many pitfalls and it will be difficult to implement everything by yourself and it will also take you too long. That is why, as I have already said, it is better to use ready solutions.

6. The End

I tried to represent in brief some key moments that you can face during the porting of the application from Windows OS to Linux OS. I rather managed to show how to implement cross-platform wrappers for API by giving an example. You can come to one more conclusion from the information mentioned above. During the porting of applications it is worth paying attention to the ready implementations of cross-platform libraries (such as STL, boost and QT).

7. Additional materials

Look through all files attached to the article.

BackupMBR_win.zip – a project (Visual Studio 2008). An application that is to be ported to Linux OS.
BackupMBR_port_win.zip – a project (Visual Studio 2008). The cross-platform alternative of BackupMBR.
BackupMBR_linux.zip – a project (Qt Creator). The cross-platform alternative of BackupMBR that was built into the project for Linux OS.

This member has not yet provided a Biography. Assume it’s interesting and varied, and probably something to do with programming.

  • Download BackupMBR_linux — 8.47 KB
  • Download BackupMBR_win — 8.03 KB
  • Download BackupMBR_port_win — 10.03 KB

1. Who is the target reader of this article?

Recently I faced one very interesting task. I had to port an application from one platform (Windows) to another (Linux). It is an interesting topic. First, knowledge of several platforms and writing the code for them is a good experience for every developer. Secondly, writing an application for different platforms makes it widespread and needed by many. So, I would like to share my impressions concerning this process. This article is intended for everybody who wants to write a cross-platform application.

2. Our task

Receiving the project specification, we usually see only one target platform in the “Platforms” section (e.g., Windows) and that is why we enjoy its advantages and disadvantages. Let’s imagine that you receive the task where it is proposed to run the application on the other platform (e.g., Linux). Or imagine that you have to use the code, which was written for one platform, on another platform. From this point you start to face difficulties. You start to plan the porting taking into account all the specifics of the program architecture. And if the architecture was wrong from the very beginning (I mean that it did not expect the porting between the platforms), it can turn out that you have to remake a lot. Let’s examine the example of the code (file attached to this article). This program opens the PhysicalDrive0, acquires MBR and writes it to the file, then defines the disk configuration and saves it to a separate file. The code was written only for Windows with all its consequences.

Please look at the code before reading the article (BackupMBR_win.zip attached to this article). This is the project of VisualStudio2008.

There must be no difficulties in such small example. But you can meet problems even here. The code is very simple and does not require many checks, deletion processing, etc. This code is not a standard but it lets to show what you should do during the porting of your application from Windows OS to Linux OS.

3. Compilers and IDE

When porting from Windows OS to Linux OS is performed, the porting from Microsoft Visual C++ to GCC(G++) is the most commonly used. Many of you may think that GCC and G++ are two different compilers. But it is not so. GCC («GNU C Compiler») was created in 1987 by Richard Stallman and it could compile only C code at that time. With time the compiler developed and supported not only C and C++ codes but also other programming languages. Now the GCC is interpreted as «GNU Compiler Collection». G++ is a part of GCC and is used to compile *.cpp files. GCC is used, in its turn, to compile *.с files. Though, you can compile the *.cpp file using GCC by indicating specific flags. GCC and G++ compile the C++ code in the same way.

Let’s return to the porting from Visual C++ to GCC (G++). It is worth paying attention to the difference between them. GCC is stricter to the standard than the Microsoft compiler. It means that in some situation the GCC compiler returns an error message and does not compile the source code while the Microsoft compiler just returns the warning message. Let’s examine some moments that are frequently met during the porting from Visual C++ to GCC. You can google it but I would like to repeat it myself.

  1. Use #ifndef/#define/#endif instead of #pragma once. GCC understands the #pragma once directive beginning from the version 3.4. That is why check the version of your compiler. If it is lower than 3.4, there is no need to correct the following code during the porting.
#ifndef SOME_HEADER_H
#define SOME_HEADER_H


#endif // SOME_HEADER_H
  1. Used types. During the porting, watch the types you use because GCC doesn’t understand all of them. It is better to create a separate file in the project (e.g., types.h file) and to put there all types that GCC does not understand.
HANDLE   
DWORD    
BYTE     
UINT     
  1. Assembler insertions. Be careful during the porting of ASM insertions to the project for GCC. They have another appearance and syntax. GCC uses AT&T ASM. It differs from Intel ASM, which is used in Visual C++. An example is provided below (the following example is taken from http://asm.sourceforge.net//articles/linasm.html; for more information about AT&T ASM also see this reference).

Intel Syntax

AT&T Syntax

mov al,bl
mov ax,bx
mov eax,ebx
mov eax, dword ptr [ebx]

movb %bl,%al
movw %bx,%ax
movl %ebx,%eax
movl (%ebx),%eax

P.S. For conversion, you can use the Intel2gas utility (see http://www.niksula.hut.fi/~mtiihone/intel2gas/). But to my opinion, it is more convenient only for the high volume of the ASM code. And anyway you should bring the code to the compilable state.

  1. Using the #pragma comment directive (lib, «libname.lib»). It is convenient to hook libraries in the project with the help of this directive in Visual C++. But GCC does not contain such one. That is why, for GCC, you should define the libraries you want to hook in the command line. For example:
g++ -o TestExe.exe *.o -Llib -lm -ldl -w  "lib_1.a" "lib_2.a" "lib_3.a"

As you can see, Linux libraries have *.a extension and not *.lib extension as in Windows OS. Dynamic libraries also have another extension (*.so instead of *.dll) and they link not in such way as in Windows OS. For more information about the types of libraries in Linux OS see http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html.

  1. Macros. Macros in GCC differ from the analogous ones in Visual C++. During the code porting to GСС, check the macros in the code. It’s possible that the implementation of such macro will not be performed. In such situation, it is better to find its implementation in Visual С++ and port it to GCC. The following table provides examples of frequently used macros.
  __DATE__                __DATE__
__FILE__                __FILE__
__LINE__                __LINE__
__STDC__                __STDC__
__TIME__                __TIME__
__TIMESTAMP__            __TIMESTAMP__

__FUNCTION__            __FUNCTION__
                    __PRETTY_FUNCTION__

MSC_VER                __GNUC__
                    __GNUC_MINOR__
                    __GNUC_PATCHLEVEL__

Let’s examine them. The first six macros are implemented in both compilers in the same way and are often used in logging. The differences begin from __FUNCTION__. In Windows OS, it writes not only the name of the function (as in Linux OS) but also the namespace and the class from where the call was performed. Its analog in Linux OS is not __FUNCTION__ but __PRETTY_FUNCTION__. MSC_VER and __GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ also have different types of returned data. For example, MSC_VER = 1500 for Visual C++, for GNU 3.2.2 it is __GNUC__ = 3, __GNUC_MINOR__ = 2, __GNUC_PATCHLEVEL__ = 2.

If the target platform does not include the needed macro, find its implementation and port it. Macro can be also written in ASM (for the code optimization). Do not hurry and rewrite it from Intel to AT&T and vice versa. It is better to check once more if there is its implementation in С++. Also take into account that Linux OS can run on devices with ARM processor. In this case the macro, which was written under AT&T, will not work and you will have to implement it under another type of the processor.

Let’s move to IDE. There are lots of them and you have the possibility to choose. Let’s examine some of them (taking into account that the project was initially written in Visual Studio, our task is to choose IDE for working in Linux OS):

— Code::Blocks (see http://www.codeblocks.org/)

win-linux-porting/code_blocks.screenshot.png

Pic.1 Code::Blocks. Start Page.

It is often proposed as the substitution of Visual Studio for those who port their project to Linux OS. IDE can open Visual Studio projects under Windows OS and Linux OS. I built a project with its help and I can say that it is very convenient.

— Eclipse/CDT (see http://www.eclipse.org/cdt/downloads.php).

win-linux-porting/eclipse.screenshot.png

Pic.2 Eclipse/CDT.

It is another free IDE. If you write in C++, download it together with the CDT plug-in. After installation IDE supports only Java by default and if you install CDT plug-in after, the auto-add-on probably will not work.

— Qt Creator (see http://qt.nokia.com/products/developer-tools).

win-linux-porting/qt_cretor.screenshot.png

Pic.3 QT Creator. Start Page

When I first worked with Linux I used this IDE. Its interface is simple (developers must have followed the example of XCode interface during the development of Qt Creator). And you do not have to use Qt while working in Qt Creator. Just configure the project using the *.pro file (in it, libraries that are statically linked, *.h and *.cpp files, the type of the application are defined).

— Emacs/Vim (see http://www.gnu.org/software/emacs/)

win-linux-porting/emacs.screenshot.png

Pic.4 Emacs. Start Page

This IDE is for experienced developers under Linux OS. The problem of this IDE is that it can take long to learn how to work with Emacs. And the skills are quickly lost, as people say. You will be able to perform the majority of commands by using hot keys or the Emacs command line. Even while opening the file you will be asked to define the file path in the command line. But on the other hand, this tool is very powerful and flexible.

I introduced four IDEs that are the most popular among the developers under Linux OS. For example, I work with QtCreator but there must be no problems while working with other IDEs (do not forget about problems with Emacs). So, it is your time to choose.

I want to add a few words about the debuggers. Sometimes I did not manage to debug the code using the native IDE debugger. That is why I had to search for the alternative. I used two debuggers: Insight and kdbg. I also tried to use ddd debugger but I did not like it. So use the one you like more. With time you will find the one that will meet the maximum of your demands.

4. Porting of the application

Let’s return to the code we examined in the second part. As we can see in the API code, functions are used directly without the wrappers above the API level. You may say that it is not bad: errors are handled, the code works, so why not to leave it as it is? There is a reason not to leave as it is. When you port the application to another platform, there will be one more problem of searching API functions in the code and their replacement. For example, the CreateFileW function (disk opening and creation of the file from the MBR disk) is represented twice in the examined code. And the program is simple in itself. If the project is big and you do not use wrappers above the API level, the code will repeat itself a lot. And it means that you will have to change a lot during the porting to another platform.

That is why the first step is to write the library that contains all used APIs and that implements the methods of working with them. It must also contain all functions specific for the definite platform. Such library will have the necessary interface, and during the porting, you will have to make some corrections only in it.

Let’s examine the schemes that illustrate the thoughts mentioned above. The majority of developers extract the core of their application into the separate libraries (Business Logic) that implement the definite interface. Such library also implements the separate GUI that will use this very library. This is correct, convenient and also it works. But there is one nuance that we just mentioned.

win-linux-porting/platforms_compability_layer.png

There must be the Platform Compatibility Layer for the cross-platform applications. This is the component that will stand between the API level and the core of your application. It is necessary to include the following components in it:

  • working with files;
  • working with sockets;
  • working with ports;
  • ASCII/Unicode
  • Threading API

Let’s start from the very beginning. Let’s try to port our application. We must define the code that will be included in the «Platform Compatibility Layer». The following table displays the comparison between Windows and Linux API.

Table 1. Comparing Linux and Windows API.

Windows API

Linux API

HANDLE WINAPI CreateFileA(
     __in      LPCTSTR lpFileName,
     __in      DWORD dwDesiredAccess,
     __in      DWORD dwShareMode,
     __in_opt LPSECURITY_ATTRIBUTES  lpSecurityAttributes,
     __in      DWORD dwCreationDisposition,
     __in      DWORD dwFlagsAndAttributes,
     __in_opt  HANDLE hTemplateFile)
   int  open(
          const char* name,
          int flags)

int  open(
          const char* name,
          int flags,
          mode_t mode)
BOOL WINAPI ReadFile(
     __in         HANDLE hFile,
     __out        LPVOID lpBuffer,
     __in         DWORD nNumberOfBytesToRead,
     __out_opt    LPDWORD lpNumberOfBytesRead,
     __inout_opt  LPOVERLAPPED lpOverlapped)
ssize_t read(
       int fd,
       void buf*,
       size_t len)
BOOL WINAPI WriteFile(
     __in         HANDLE hFile,
     __in         LPCVOID lpBuffer,
     __in         DWORD nNumberOfBytesToWrite,
     __out_opt    LPDWORD lpNumberOfBytesWritten,
     __inout_opt  LPOVERLAPPED lpOverlapped)
ssize_t write(
       int fd,
       void buf*,
       size_t count)
DWORD SetFilePointer(
     __in         HANDLE hFile,
     __in         LONG lDistanceToMove,
     __inout_opt  PLONG lpDistanceToMoveHigh,
     __in         DWORD dwMoveMethod)
off_t lseek(
       int fd,
       off_t pos,
       int origin)
BOOL CloseHandle(
     __in  HANDLE hObject)
int  close(
           int fd)

The first function that we use is the CreateFileA function. We need it to open the device (in this case, it is PhysycalDrive0). We call it with the following parameters:


HANDLE handle_r = ::CreateFileA("\\.\PhysicalDrive0"
                        , GENERIC_READ 
                        , FILE_SHARE_READ | FILE_SHARE_WRITE
                        , 0
                        , OPEN_EXISTING
                        , FILE_ATTRIBUTE_NORMAL
                    , 0);

With the help of the first parameter we define the path of the device we are opening \\.PhysicalDrive0. In Linux OS, all devices have the format of simple files and are located in the /dev directory. There you can find the required device (it is /dev/sda device in my system). You can define the path to the device on your computer by entering the mount command in Linux terminal. This command is used for device mounting. But such command without any parameters will display all mounted devices in the system. The following example is the example of mount command for my system:

root@ubuntu:/usr/share/man$ mount
    /dev/sda1 on / type ext3 (rw)
    tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
    proc on /proc type proc (rw,noexec,nosuid,nodev)
    ..........................................................................
    securityfs on /sys/kernel/security type securityfs (rw)

Let’s examine the first line, where:

/dev/sda1 — the path to the device file
/ — the path of the mounted filesystem
type ext3 — the filesystem type
rw — read and write permissions.

Hard drives are usually indicated as /dev/sd* and /dev/hd* in Linux OS. If the computer has three hard drives, they will be indicated as /dev/sda, /dev/sdb, /dev/sdc. The number that follows after the name of the hard drive defines the partition number on this drive. To open the disk, use the open() function.

According to the manual, this function juxtaposes the full file path with the descriptor of the file, which it returns. Descriptor is the analog of HANDLE in Windows OS. It can be used for read/write/lseek functions. If you did not manage to open/create a file, the function returns -1. Permission of file access is defined in the flags parameter. For /dev/sda, set the O_RDONLY flag (it is an analog of GENERIC_READ for CreateFileA). For more information about flags see the manual. So, for Linux OS, the open() function will look like the following:


It is more compact than in Windows OS. Now it is necessary to write the function that will be common for Windows and Linux OS. First, let’s define how this function will look like. CreateFileA can be assumed as a basis. There are three parameters out of 7 that do not change in the program:

- DWORD dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
- LPSECURITY_ATTRIBUTES  lpSecurityAttributes = 0
- HANDLE hTemplateFile = 0

As these parameters have the same value, we exclude them from the target function. You may say that we limit the functionality defining one and the same value to some parameters. But we did not change them in the program, those values, which are defined, are enough for us. It means that the function performs the program minimum and can cover the functionality that we need. It is worth defining here how we use one or another API function. The minimum functionality is usually enough. But on the other hand, if we want to set the FILE_SHARE_READ value to the dwSharedMode parameter, we will hit a problem. It is not enough that we must add changes to the function, but also we will have to change the number of parameters in all its calls. That is why it is necessary to define what exactly you want, for example, from CreateFileA and how you will use it. Then it will be clear how the wrapper over this function will look like.

So, we came to conclusion that the function will have 4 parameters. Now we have to confirm them on both platforms. I will port the minimum of them: GENERIC_READ (to open the file for reading) and GENERIC_WRITE (to open the file for writing). These parameters are similar to O_RDONLY and O_WRONLY parameters for the open() function. dwCreationDisposition defines the way of opening the file. I used two values: OPEN_EXISTING (the file opens; if there is no file, the error is returned) and CREATE_ALWAYS (a new file is created; if such file already exists, it is rewritten). There are no such parameters for the open() function. The closest will be the O_CREAT parameter. This flag is used for file creation and corresponds to CREATE_ALWAYS parameter. You don’t need to use the OPEN_EXISTING value for the open() function. You may say that the FILE_ATTRIBUTE_NORMAL value of the dwFlagsAndAttributes also did not change and that we have to exclude it from the parameters. But as it was mentioned earlier, the open() function has one more mode parameter. It defines the file permission, as you remember. Let’s define the FILE_ATTRIBUTE_NORMAL = 0644 parameter (the owner of the file has read and write permissions, others only read permission). It is not right as we cannot define other file permissions but it is enough for porting our application. It is a certain support point. But it is easy to correct: we just find the value correspondence for the necessary parameters for both platforms.

We compared all parameters that are interesting for us and now can start writing the function itself. What is the process of writing? We use the #ifndef/#define/#elif/#endif preprocessor directives. We use the following construction:

#ifdef WIN32
    
#elif __linux__
    
#else 
    #error: unknown OS
#endif

By using this construction, we can single out parts of the code that are specific for a definite platform. With the help of this method you can single out not only the parts of functions but also the whole functions.

int do_something()
{
#ifdef WIN32
    
#elif __linux__
    
#else 
    #error: unknown OS
#endif
}    
#ifdef WIN32
int do_something()
{
    
}
#elif __linux__
int do_something()
{
    
}
#else 
    #error: unknown OS
#endif

As we can see, both methods prove its value. The first one is less readable; the second one contains more code but it is easier to make changes in it. I would advise you to use the second one but it is your right to choose. As an alternative, you can separate off all to the header files.

Let’s look how the function will look like after making all changes in it:


#include "file_io.h"


#ifdef WIN32
    
#elif __linux__
 #include <sys/types.h>

    #include <sys/stat.h>

    #include "unistd.h"

    #include <fcntl.h>


    #define GENERIC_READ                O_RDONLY    //read only mode
    #define GENERIC_WRITE               O_WRONLY    //write only mode
    #define CREATE_ALWAYS               O_CREAT        //create new file
    #define OPEN_EXISTING               0           //fake parameter's value
 #define FILE_ATTRIBUTE_NORMAL     0644          // file attributes
#else
    #error: unknown OS
#endif

#ifdef WIN32 // create_io_file for windows
HANDLE create_io_file(const char* file_name,
           DWORD desired_access,
           DWORD creation_despositions,
           DWORD flags_attributes)
{
        return ::CreateFileA(file_name,
                             desired_access,
                             FILE_SHARE_READ | FILE_SHARE_WRITE,
                             0,
                                creation_despositions,
                                flags_attributes,
                                0);
}
#elif __linux__ // create_io_file for Linux
HANDLE create_io_file(const char* file_name,
                      DWORD desired_access,
                      DWORD creation_despositions,
                      DWORD flags_attributes)
{
    return ::open(file_name,
                  desired_access | creation_despositions,
                  flags_attributes);

}
#else
    #error: unknown OS
#endif

As it can be seen from the code, we took into account everything mentioned above. The received create_io_file wrapper does not implement all the features of CreateFileA and open but it is an example of how you can implement the cross-platform wrapper above the API level. You can port the rest of functions in the same way (see file_io.h/file_io.cpp file).

Besides API, we used DeviceIOControl to receive the disk geometry. The get_drive_info() function is represented below:


bool get_drive_info(HANDLE _handle, drive_info &mp;drive_info_)
{
    DWORD size_ = 0;
    BOOL is_accessible_ =
        ::DeviceIoControl(_handle
        , IOCTL_STORAGE_CHECK_VERIFY
        , 0
        , 0
        , 0
        , 0
        , &size_
        , 0);

    if (!is_accessible_)
    {
        return false;
    }

    DISK_GEOMETRY disk_geometry_;
    ::memset(&disk_geometry_, 0, sizeof disk_geometry_);

    BOOL is_geometry_ =
        ::DeviceIoControl(_handle
        , IOCTL_DISK_GET_DRIVE_GEOMETRY
        , 0
        , 0
        , &disk_geometry_
        , sizeof disk_geometry_
        , &size_
        , 0);

    if (!is_geometry_)
    {
        return false;
    }

    drive_info_._cylinder = disk_geometry_.Cylinders.QuadPart;
    drive_info_._type = fixed;
    drive_info_._tracks_per_cylinder = disk_geometry_.TracksPerCylinder;
    drive_info_._sectors_per_track = disk_geometry_.SectorsPerTrack;
    drive_info_._bytes_per_sector = disk_geometry_.BytesPerSector;

        drive_info_._lba_size = drive_info_._cylinder
           * drive_info_._bytes_per_sector
           * drive_info_._sectors_per_track
           * drive_info_._tracks_per_cylinder;

       return true;
}

There is an analog of DeviceIOControl in Linux. It is the ioctl function, which receives the device descriptor and can return the requested information about it. By calling DeviceIOControl with the IOCTL_DISK_GET_DRIVE_GEOMETRY parameter we receive the DISK_GEOMETRY structure as a result. It looks like the following:

typedef struct _DISK_GEOMETRY {
    LARGE_INTEGER Cylinders;
    MEDIA_TYPE MediaType;
    DWORD TracksPerCylinder;
    DWORD SectorsPerTrack;
    DWORD BytesPerSector;
} DISK_GEOMETRY, *PDISK_GEOMETRY;

To receive the similar structure with the disk geometry in Linux, call the ioctl function with the HDIO_GETGEO parameter and reference the following structure:

struct hd_geometry {
      unsigned char heads;
      unsigned char sectors;
      unsigned short cylinders;
      unsigned long start;
};

Having compared the structures, we notice the absence of one of the fields. The hd_geometry structure does not contain the BytesPerSector value. This can be corrected by calling the ioctl function with the BLKSSZGET parameter, which according to Linux sources returns the block device sector size. These are the specifics of porting this function. The final variant looks like the following:


#ifdef WIN32
bool get_drive_info(HANDLE _handle, drive_info &drive_info_)
{
    DWORD size_ = 0;
    BOOL is_accessible_ =
        ::DeviceIoControl(_handle
        , IOCTL_STORAGE_CHECK_VERIFY
        , 0
        , 0
        , 0
        , 0
        , &size_
        , 0);

    if (!is_accessible_)
    {
        return false;
    }

    DISK_GEOMETRY disk_geometry_;
    ::memset(&disk_geometry_, 0, sizeof disk_geometry_);

    BOOL is_geometry_ =
        ::DeviceIoControl(_handle
        , IOCTL_DISK_GET_DRIVE_GEOMETRY
        , 0
        , 0
        , &disk_geometry_
        , sizeof disk_geometry_
        , &size_
        , 0);

    if (!is_geometry_)
    {
        return false;
    }

    drive_info_._cylinder = disk_geometry_.Cylinders.QuadPart;
    drive_info_._type = fixed;
    drive_info_._tracks_per_cylinder = disk_geometry_.TracksPerCylinder;
    drive_info_._sectors_per_track = disk_geometry_.SectorsPerTrack;
    drive_info_._bytes_per_sector = disk_geometry_.BytesPerSector;

    drive_info_._lba_size = drive_info_._cylinder
        * drive_info_._bytes_per_sector
        * drive_info_._sectors_per_track
        * drive_info_._tracks_per_cylinder;

    return true;
}

#elif __linux__
bool get_drive_info(HANDLE _handle, drive_info &drive_info_)
{
    struct hd_geometry geometry;
    ::memset(&geometry, 0, sizeof geometry);

    int result = ioctl(_handle, HDIO_GETGEO, &geometry);

    if (result < 0)
    {
        std::cout<<"ioctl error";
        return false;
    }


    drive_info_._cylinder = geometry.cylinders;
    drive_info_._type = fixed;
    drive_info_._tracks_per_cylinder = geometry.heads;
    drive_info_._sectors_per_track = geometry.sectors;


    long sector_size = 0;
    result = ioctl(_handle, BLKSSZGET, &sector_size); 

    if (result < 0)
    {
        std::cout<<"ioctl error";
        return false;
    }

    drive_info_._bytes_per_sector = sector_size;

    drive_info_._lba_size = drive_info_._cylinder
        * drive_info_._bytes_per_sector
        * drive_info_._sectors_per_track
        * drive_info_._tracks_per_cylinder;

    return true;
}

#else
    #error: unknown OS
#endif

There is one more function left. It is the store_drive_geometry function but it does not require the change of the code. It can be easily ported. Such effect can be achieved by using STL (see http://cplusplus.com), boost (see http://boost.org) or Qt libraries. All these libraries are cross-platform and allow writing the easily ported code. For example, in STL, the wrapper above the API level is already implemented for the work with files and the library is already cross-platform. So pay attention to using such libraries. It can make your work easier.

5. Windows->Linux. A few words

We examined only one of many components from the list that change during the porting. I would like to say a few words about the rest of them.

ASCII/Unicode. Here we can meet problems because the size of the wchar_t type in Windows is twice smaller than in Linux (2 bytes in Windows and 4 bytes in Linux). The reason is that Linux uses UTF-32 character encoding and Windows — UCS-2. The difference in character encodings can be solved by setting the GCC flag during the compilation:

-fshort-wchar

Attention should be paid to all char <-> wchar_t conversions and to the use of Unicode during the transfer between systems.

Threading API. It is better to implement it using boost or Qt libraries. It means that the work with threads has many pitfalls and it will be difficult to implement everything by yourself and it will also take you too long. That is why, as I have already said, it is better to use ready solutions.

6. The End

I tried to represent in brief some key moments that you can face during the porting of the application from Windows OS to Linux OS. I rather managed to show how to implement cross-platform wrappers for API by giving an example. You can come to one more conclusion from the information mentioned above. During the porting of applications it is worth paying attention to the ready implementations of cross-platform libraries (such as STL, boost and QT).

7. Additional materials

Look through all files attached to the article.

BackupMBR_win.zip – a project (Visual Studio 2008). An application that is to be ported to Linux OS.
BackupMBR_port_win.zip – a project (Visual Studio 2008). The cross-platform alternative of BackupMBR.
BackupMBR_linux.zip – a project (Qt Creator). The cross-platform alternative of BackupMBR that was built into the project for Linux OS.

This member has not yet provided a Biography. Assume it’s interesting and varied, and probably something to do with programming.

Содержание

  1. Как перенести проект с Windows на Linux или с чего начать? Есть cpp проект под винду, рабочий. Необходимо перенести на Linux
  2. Как запустить Windows-приложение в Linux?
  3. Можно ли запустить Windows-приложение в Linux?
  4. Обзор инструментов Wine, Winetricks и PlayOnLinux
  5. Установка и запуск Windows-приложения в Linux
  6. Шаг 1 – Установка Wine
  7. Шаг 2 – Скачивание установочного файла программы
  8. Шаг 3 – Установка программы
  9. Шаг 4 – Запуск программы
  10. Видео-инструкция
  11. Выбор редакции
  12. Топ-20 фильмов про быстрое.
  13. Genshin Impact обновление.
  14. Топ-20 лучших сериалов про.
  15. Запуск Windows программ под Linux
  16. Установка Wine
  17. Настройка Wine
  18. Будьте внимательны, при этом удалятся также все приложения Windows, которые установлены в этот каталог!
  19. PlayOnLinux
  20. Прочие программы на базе Wine
  21. VirtualBox

Как перенести проект с Windows на Linux или с чего начать? Есть cpp проект под винду, рабочий. Необходимо перенести на Linux

Проект написан Microsoft Visual Studio 2010

Что вендо-специфичного используется в проекте?

40709:1576041504

Если там гуйня и сисвызовы, проще написать заново!

Интересует какой дистрибутив ставить, и какие пакеты для программирования, а так же где нарыть стандартных библиотек?

p

Если приложение серьёзно виндовое (winapi), то есть такой алгоритм:

1. На винде научиться собирать его с помощью mingw — visual c++ в linux всё равно нет, так что всё равно придётся сделать код совместимым с gcc.

2. Научившись, перенести исходники на linux, поставить wine, заменить все вызовы gcc на winegcc, windres на wrc и т.д. (см. man winegcc), и опять же добиться чтобы компилировалось и запускалось).

3. Дальше действовать сообразно предложениям выше по треду по выкидыванию зависимости от winelib.

p

Интересует какой дистрибутив ставить

тот, работу приложения под которым вы собираетесь обеспечивать.

стандартный набор для разработки в дистрибутиве (debian/ubuntu: build-essential, archlinux: base-devel)

на то они и стандартные, чтобы входить в комплект поставки, верно?

Сеть вроде надо переписывать, там api несколько другой, если гуйни нет, то скорее всего немного дорабатывать (мне так кажется из-за моего монитора ).

p

В целом обычно в таком случае переписывают с winapi на Qt. (т.е. даже виндовая версия будет на Qt, а winapi просто выкидывают).

40709:1576041504

Генту или слаку. Первая хороша еще тем, что т.к. ты все собираешь, то недостатка в библиотеках и заголовочных файлах не будет (привет, бубунта!). Можешь и дебьян поставить, если поцтеринга не боишься, но придется почти вручную все нужное ставить.

Это тебе не мастдайка, ничего «рыть» не надо. Ставишь из репы все, что нужно, и не паришься.

108401: 1333525771

Возможно легче не перенести, а переписать заново.

p

Я такое сначала перевожу на что-либо кросплатформенное под той же Виндой и Вижуалом (скажем, используя boost и Qt), отлаживаю а уж потом переношу на другую платформу.

Поясните мне, как человеку далекому от ЛОРовских телепатов, что вы хотите перенести на Линукс. То ли разработку на линуксе, но в результате получать теже ЕХЕ под виндовс, то ли портировать проект на линукс, т.е. получить ELF файл для запуска на линуксе?

— Ubuntu подойдет, установить debian/ubuntu: build-essential, archlinux: base-devel

— wine не нужен, обертка не важна

именно портировать проект на линукс

121714:922829503

Вангую сотни боли и «говно этот ваш линукс» в итоге. Надо было думать прежде, чем юзать winapi.

79910:1487889964

Если Win-специфичного кода не много(не используются большие фреймворки/тулкитьі), то: Собираешь проект которьій есть под линуксом. Весь код, генерирующий еррорьі комментируешь. Как будет собираться без ерроров анализируешь закомментированньій код. Подбираешь библиотеки/тулкитьі/фреймворки которьіе вернут проекту функциональность закомментированного кода.

Источник

Как запустить Windows-приложение в Linux?

Всем привет! Практически у всех начинающих пользователей Linux, которые только перешли с Windows, возникает один и тот же вопрос – а как в Linux запустить программу (игру), которая была в Windows? Иными словами, как запустить программу или игру, которая была разработана для Windows, в Linux, т.е. в другой операционной системе. В этом материале я расскажу Вам, можно ли это сделать, и если можно, то как.

Можно ли запустить Windows-приложение в Linux?

Для начала обязательно отмечу, что Linux – это совсем другая платформа, не Windows и не совместимая с ней, поэтому абсолютно любая программа или игра, разработанная для Windows, запускается только на Windows.

На заметку! Новичкам рекомендую почитать мою книгу «Linux для обычных пользователей» – в ней я подробно рассказываю про основы операционной системы Linux, и как пользоваться этой системой без командной строки.

Однако, так как эти вопросы задаются, и возник спрос, существует возможность запускать Windows-приложения в Linux, но это не стандартная возможность, которая не гарантирует нормального функционирования программы, да и не все программы так можно запустить, а еще к тому же, за счет того, что запускаются именно Windows-приложения, значительно снижается безопасность системы. Поэтому лучше не использовать возможность, которую я опишу чуть ниже, а пользоваться стабильными приложениями, разработанными именно для Linux.

Обзор инструментов Wine, Winetricks и PlayOnLinux

Итак, если у Вас все-таки остро стоит задача запустить Windows-кую программу в Linux, то существует специальная программа под названием Wine.

Wine – это альтернативная реализация Windows API.

Иными словами, Wine создает условия для запуска Windows-программ в Linux. При этом Wine – это не эмулятор, т.е. это не виртуальная машина, она не эмулирует оборудование, не эмулирует операционную систему, как я уже отметил, она является альтернативной реализацией Windows API, что и позволяет запускать Windows-программы в Linux.

Но как я уже отметил, совместимость программ не полная, не все программы поддерживаются, а те, которые поддерживаются, могут работать некорректно. В то же время большинство популярных программ работают в Wine очень даже неплохо, например, есть возможность запустить даже Microsoft Office.

Для упрощения установки и запуска Windows-программ в Linux разработчики также придумали специальные вспомогательные инструменты, которые упрощают всю эту работы.

К таким инструментам относится скрипт Winetricks.

Winetricks – скрипт для загрузки и установки различных распространённых библиотек, необходимых для запуска некоторых программ в Wine. Winetricks автоматически создаёт для программ правильные настройки и скачивает требуемые для их работы компоненты.

Winetricks – скрипт для упрощения работы с Wine.

Еще одним инструментом для упрощения установки Windows-приложений в Wine является программа – PlayOnLinux. Она создана для автоматизации установки программ и игр, созданных для Windows в Linux, т.е. она может автоматически скачать и установить некоторые программы (игры). Также PlayOnLinux в случае необходимости может скачать специальную версию Wine вместе с настройками для конкретной программы, и даже применять к программе некоторые исправления для того, чтобы добиться более стабильной работы.

PlayOnLinux – графическая программа, надстройка над Wine, которая упрощает установку и использование программ и игр в Linux, которые были разработаны для Windows.

По факту PlayOnLinux – это что-то вроде менеджера программ с графическим интерфейсом, в котором уже по умолчанию отображаются программы, которые можно установить, т.е. Вы просто выбираете программу и запускаете установку. И тем самым по сути, если программа есть в списке PlayOnLinux, то Вы сможете установить ее и запустить в Linux, для этого выполнив всего несколько простых шагов мастера.

Однако работа с PlayOnLinux и, в частности, с Wine непредсказуемая, иными словами, стандартного сценария установки программ нет, в процессе установки любой программы могут (и, наверное, будут) появляться различные ошибки, например, отсутствие какого-нибудь пакета или еще что-нибудь.

Поэтому установка Windows-приложений в Linux — это дело индивидуальное, и рассчитывать на стандартный способ установки не приходится. А лучше вообще использовать приложения на той платформе, для которой они были разработаны, т.е. Windows-приложения на Windows, а Linux-программы на Linux.

Но, как говорится, если Вы не ищете легких путей, то можете установить Wine или PlayOnLinux, и пробовать устанавливать различные Windows-приложения.

Установка и запуск Windows-приложения в Linux

Теперь давайте я покажу, как установить и запустить Windows-приложение в операционной системе Linux, в качестве примера я возьму программу Notepad++, которая была разработана для Windows, т.е. версии для Linux на текущий момент у этой программы нет.

Шаг 1 – Установка Wine

Сначала необходимо установить программу Wine. Пример установки Wine можете посмотреть в материале – Установка Wine в Linux Mint, в этой статье я подробно рассказывал и показывал, как установить Wine в дистрибутиве Linux Mint.

После того, как Wine Вы установили, повторно, для установки другой программы, Wine устанавливать не нужно.

Шаг 2 – Скачивание установочного файла программы

Следующее, что нужно сделать, это, конечно же, скачать установочный дистрибутив программы, в нашем случае Notepad++, т.е. так же, как и в Windows, Вам необходимо скачать ровно тот же самый установочный файл, который Вы бы использовали, если устанавливали программу на Windows.

Шаг 3 – Установка программы

После того как Вы установили Wine, Вы можете запускать exe файлы точно так же, как и в Windows.

Таким образом, для запуска установки программы мы просто щелкаем двойным кликом по скаченному файлу.

Потом программа Wine попросит загрузить и установить необходимые для корректной работы пакеты (в случае их отсутствия в системе). Нажимаем «Установить» и ждем окончания процесса установки этих пакетов.

После чего запустится установка программы, в нашем случае установка Notepad++, и этот процесс ничем не будет отличаться от установки в Windows, ведь это тот же самый установщик.

Более подробно посмотреть на процесс установки Notepad++ Вы можете в материале – Установка Notepad++ в Linux Mint

Шаг 4 – Запуск программы

После окончания установки ярлык программы появится в меню, а также на рабочем столе, если Вы поставили соответствующую галочку в процессе установки программы.

Для того чтобы запустить программу, просто щелкаете по ярлыку.

Как видите, в нашем случае проблем с установкой программы в Linux не возникло, но так бывает далеко не всегда, ведь установка Windows-приложений в Linux, как я уже говорил, это дело индивидуальное и непредсказуемое, и в большинстве случаев будут появляться различные ошибки.

Да и тогда, когда установка пройдет успешно, никто не дает гарантии, что приложение будет работать корректно, т.е. так же как в Windows.

Видео-инструкция

На сегодня это все, надеюсь, материал был Вам полезен, пока!

Источник

Выбор редакции

Топ-20 фильмов про быстрое.

Genshin Impact обновление.

Топ-20 лучших сериалов про.

Запуск Windows программ под Linux

cover

Для операционных систем на базе Linux написано огромное количество программ. Несмотря на это, иногда возникает необходимость производить запуск Windows программ под Linux. В основном, это касается игр и некоторых специализированных программ, аналоги которых в Linux отсутствуют. Кроме того, некоторые пользователи, переходя с Windows на Linux, уже привыкли к определенному набору программного обеспечения и желают его использовать в дальнейшем. В этом случае предпочтительнее все же найти аналогичные программы для Linux и освоить их, поскольку в родной операционной системе программы работают обычно лучше и стабильнее. Поэтому рекомендуем запускать Windows программы под Linux только после того, как вы убедитесь, что аналогов нужных программ под Linux нет, или они вам не подходят.

Запустить программу, написанную для Windows в Linux, можно несколькими способами: с использованием Wine и продуктов на его основе, с помощью виртуальных машин и эмуляторов: VirtualBox, VMware, Parallels Workstation, QEMU. Теоретически еще есть возможность портирования программ с Windows на Linux при наличии исходного кода и навыков программирования, но этот вариант мы здесь рассматривать не будем.

Программы под Wine обычно работают быстрее, чем в виртуальных машинах. Это особенно актуально для современных 3D игр. Wine не требует установки операционной системы и позволяет быстро менять версию системы, библиотек и другие параметры. Запускать программы можно непосредственно в среде Linux. С другой стороны, для настройки Wine все равно придется потратить некоторое время и возможно неоднократно при запуске отдельных программ и игр. В виртуальных машинах запускаются оригинальные версии Windows и прочие операционные системы, которые нужно предварительно установить и настроить. Системе выделяются определенные ресурсы компьютера, эмулируется стандартное оборудование. Перед выполнением программы нужно предварительно запустить эмулятор и загрузить операционную систему, на что требуется дополнительное время. Следует отметить, что некоторые программы имеют защиту от запуска под виртуальными машинами.

Установка Wine

Мы рассмотрим установку Wine на Ubuntu и систем на ее базе (Linux Mint, Kubuntu и т.п.).Пользователи других операционных систем могут скачать Wine и прочитать инструкции по установке здесь: http://www.winehq.org/download/

Открываем терминал комбинацией клавиш Ctrl+Alt+T. Добавляем репозиторий с Wine командой:

sudo add-apt-repository ppa:ubuntu-wine/ppa

Вводим пароль администратора. В процессе установки нужно будет нажать клавишу «Enter».

Если вы будете производить апгрейд системы, например, обновлять Ubuntu 13.10 до Ubuntu 14.04, то придется повторить вышеуказанную операцию после апгрейда, поскольку в процессе обновления нестандартные репозитории удаляются.

После добавления репозитория обновляем информацию о пакетах:

sudo apt-get update

Теперь можно установить Wine командой:

sudo apt-get install wine1.7

Установится последняя, на момент написания статьи, тестовая версия программы. Для установки старой, но более стабильной версии нужно выполнить команду:

sudo apt-get install wine1.6

Возможно, когда вы будете читать эту статью, уже появятся более новые версии, тогда вместо wine1.6 или wine1.7, надо будет устанавливать wine1.8 или wine1.9. Номер текущей версии указан на официальном сайте Wine: http://www.winehq.org

Хотя можно и не указывать версию при установке, версия Wine в этом случае будет зависеть от версии операционной системы:

sudo apt-get install wine

Проверить, какая версия установилась, можно с помощью команды:

Настройка Wine

После установки необходимо настроить программу командой:

winecfg

w1

Рис. 1. Окно настроек winecfg

А редактировать реестр можно с помощью привычной команды:

regedit

w2

Рис. 2. Окно regedit под Wine

После такой первоначальной настройки, уже можно будет устанавливать и запускать программы с помощью Wine. Но многие программы работать не смогут, поскольку требуют определенных библиотек, шрифтов и т.д., которые придется установить отдельно. Для этого воспользуемся программой winetricks, которая входит в стандартный пакет программ Wine. Winetricks кроме шрифтов и библиотек позволяет также устанавливать популярные программы и игры и производить настройки Wine.

Попробуем установить Internet Explorer 7 с помощью winetricks, для этого наберем в терминале:

winetricks ie7

Подождем некоторое время, пока скачаются необходимые файлы и запустится программа-установщик, нажмем кнопку «Next» и подождем окончания установки. Для последующего запуска Internet Explorer нужно будет выполнить команду:

wine ‘C:Program FilesInternet Exploreriexplore’

Но лучше запускать программы из родного каталога. Переходим в каталог (если в имени файла есть пробел, то перед ним нужно ставить обратный слеш «»):

/.wine/drive_c/Program Files/Internet Explorer/

И запускаем программу:

wine iexplore.exe

Чтобы не набирать эти команды каждый раз, можно создать простейший скрипт. Переходим в домашний каталог:

Создаем файл ie.sh с помощью редактора nano:

nano ie.sh

Вставляем в файл строчки:

/.wine/drive_c/Program Files/Internet Explorer/ wine iexplore.exe

Сохраняем файл — Ctrl+O и выходим из редактора — Ctrl+X. Делаем файл исполняемым:

chmod +x ie.sh

Теперь для запуска ie достаточно набрать:

А можно скопировать файл на рабочий стол и запускать его с помощью мышки:

Установка программы с CD или DVD может быть выполнена с помощью такой команды:

wine start ‘D:setup.exe’

Аналогичным образом можно установить другие программы и библиотеки. Также можно воспользоваться графическим интерфейсом программы, набрав winetricks без параметров. Потом выбрать «Select the default wineprefix».

w3

Рис. 3. Основное окно winetricks

Далее выбираем действие, которое будем производить, например, установку библиотеки (Install a Windows DLL or component):

w4

Рис. 4. Выбор действия winetricks

И отмечаем галочками библиотеки, которые необходимо установить. Можно сделать то же самое и посредством командой строки, например:

winetricks d3dx9 dotnet20

Таким образом, мы установим сразу два компонента: d3dx9 и dotnet20. Чтобы в программах корректно отображались популярные шрифты, установим их:

winetricks allfonts

С библиотеками немного сложнее. Разные программы могут потребовать отдельных настроек, определенных версий Windows и библиотек. Для этого можно создать несколько конфигураций Wine, указывая каталог с настройками с помощью переменной окружения WINEPREFIX. По умолчанию WINEPREFIX=

/.wine Для создания новых настроек в каталоге

Таким образом, можно создать любое количество конфигураций. Для настройки и установки шрифтов и библиотек наберем:

Для запуска установленной программы:

Завершить выполнение программы можно с помощью команды:

А чтобы завершить работу всех программ, запущенных под Wine, нужно набрать:

Для удаления настроек и всех программ в префиксе

/.wine2 нужно просто удалить каталог:

Точно также можно удалить и основной каталог Wine:

Будьте внимательны, при этом удалятся также все приложения Windows, которые установлены в этот каталог!

winefile — запуск файлового менеджера, с помощью которого можно запускать Windows-приложения, копировать и удалять файлы и т.д. Узнать, какие приложения и игры запускаются под Wine и как производить настройки под конкретные приложения можно на сайте: http://appdb.winehq.org/ Сайт англоязычный. Для поиска приложений нужно выбрать в меню «Browse Apps» и ввести в поле «Name» название программы. Версии программ, которые запускаются и работают без ошибок или с несущественными проблемами, имеют рейтинг «Platinum» или «Gold». Если программа вообще не работает, то ей присваивается рейтинг «Garbage».

PlayOnLinux

PlayOnLinux — это программа, которая значительно упрощает установку и настройку Windows-приложений для запуска под Wine. Она автоматически скачивает из интернета и устанавливает все необходимые компоненты для запуска конкретных программ, а также и сами программы, если они распространяются бесплатно через интернет. В противном случае, понадобится установочный диск с программой. Устанавливаем программу любым способом, например в Ubuntu командой:

sudo apt-get install playonlinux

playonlinux

Пользоваться программой предельно просто. Нажимаем кнопку «Установка».

w5

Рис. 5. Основное окно PlayOnLinux

Выбираем программу, которую необходимо установить. Если не нашли нужную программу в окне выбора, можно попробовать нажать «Установить программу, отсутствующий в списке» внизу окна.

w6

Рис. 6. Окно выбора программы PlayOnLinux

Останется несколько раз нажать кнопку «Далее», а в некоторых случаях выбрать конфигурацию программы. После установки ярлыки программ появятся в основном окне PlayOnLinux, откуда их можно будет запустить двойным кликом, либо нажатием на кнопку «Запуск». Также можно будет создать ярлыки программ Windows на рабочем столе с помощью кнопки «Ярлык».

w7

Рис. 7. Основное окно PlayOnLinux с установленной Windows-программой FireFox

Прочие программы на базе Wine

Существуют также платные программные продукты на базе Wine. CrossOver позволяет запускать под Linux различные версии Microsoft Office, Adobe Photoshop и множество других программ и игр. [email protected] нацелен в основном на поддержку популярных программ для бизнеса: 1С:Предприятие, КонсультантПлюс, ГАРАНТ и прочих. Ознакомиться с этими программами можно на официальных сайтах: http://www.codeweavers.com/products/ http://etersoft.ru/products/wine

VirtualBox

VirtualBox — одна из самых популярных программ для виртуализации, которая позволяет запускать различные операционные системы одновременно на одном компьютере. Установку VirtualBox в Ubuntu можно выполнить стандартным способом, набрав в терминале:

sudo apt-get update

sudo apt-get install dkms

sudo apt-get install virtualbox

dkms осуществляет поддержку динамических модулей ядра (vboxdrv, vboxnetflt, vboxnetadp), которые необходимы для работы VirtualBox. В других версиях Linux для установки используются соответствующие команды (yum, urpmi и т. д.), также можно использовать установочный файл или собрать программу из исходного кода. Подробнее смотрите в статье «Как устанавливать программы в Linux».

Скачать VirtualBox для различных операционных систем можно здесь: https://www.virtualbox.org/wiki/Downloads. После окончания установки добавим пользователя в группу vboxusers, вместо username необходимо указать корректное имя пользователя, под которым будет работать VirtualBox:

Теперь можно запустить программу через меню, либо набрав в терминале:

virtualbox

vb1

Рис. 8. Менеджер VirtualBox с уже установленными операционными системами

Теперь поставим операционную систему, для этого нужно иметь установочный диск или его образ. Нажмем кнопку «Создать», запустится мастер создания новой виртуальной машины:

vb2

Рис. 9. Мастер создания новой виртуальной машины

Нажмем кнопку «Вперед», введем имя виртуальной машины, например «Windows XP», а ниже выберем соответствующие тип и версию операционной системы:

vb3

Рис. 10. Выбор версии операционной системы

Мы выбрали Windows XP, поскольку она менее требовательна к ресурсам компьютера, занимает меньше места, быстрее загружается. Но поддержка этой системы уже официально прекращена. Естественно, можно установить и другие версии Windows, которые поддерживает VirtualBox: Windows Server 2003, Windows Vista, Windows Server 2008, Windows 7, Windows 8, Windows Server 2012. Далее выбираем объем ОЗУ, которое будет выделено виртуальной машине:

vb4

Рис. 11. Выбор объема памяти

Выбор зависит от версии ОС, объема физической памяти, планируемых задач, количества запускаемых одновременно гостевых систем. В зависимости от версии операционной системы, VirtualBox будет предлагать различные параметры по умолчанию, но они, как правило, минимальные, желательно их увеличить. В любом случае, для нормальной работы современных операционных систем необходимо не менее 1-2 Гигабайт ОЗУ (для Windows XP достаточно 512 Мбайт) и еще необходимо оставить память основной хост-системе. Далее создаем новый виртуальный жесткий диск или выбираем уже созданные ранее.

vb5

Рис. 12. Виртуальный жесткий диск

На следующем экране выбираем тип диска, по умолчанию стандартный VDI.

vb6

Рис. 13. Выбор типа диска

Далее указываем, что наш диск будет динамический, это позволяет сэкономить дисковое пространство физического носителя.

vb7

Рис. 14. Выбор атрибутов виртуального диска

Указываем размер диска, расположение оставляем по умолчанию (диск будет располагаться в папке

/VirtualBox VMs/Имя системы.

vb8

Рис. 15. Выбор расположения и размера виртуального диска

Осталось нажать кнопку «Создать».

vb9

Рис. 16. Последний этап создания новой виртуальной машины

Виртуальная машины создана. Выбираем ее в менеджере VirtualBox и нажимаем кнопку «Свойства».

vb10

Рис. 17. Выбор системы

Тут можно подробно настроить созданную виртуальною машину. В первую очередь, необходимо указать диск, с которого будем ставить систему. Для этого нажимаем слева «Носители», выбираем пустой диск, справа кликаем на иконку диска и указываем образ дистрибутива, либо ставим галочку «Живой CD/DVD» и вставляем физический диск.

vb11

Рис. 18. Выбор установочного диска

Далее переходим на вкладку «Система → Материнская плата», проверяем порядок загрузки, CD/DVD-ROM должен быть выше жесткого диска. Если это не так, изменяем порядок загрузки стрелками.

vb12

Рис. 19. Настройки системы

Если важна скорость работы с графикой, переходим на вкладку «Дисплей», увеличиваем объем видеопамяти и включаем ускорение.

vb13

Рис. 20. Настройка параметров дисплея

Переходим обратно в VirtualBox Менеджер и нажимаем кнопку «Старт». Далее производим установку системы, как обычно. После установки гостевой системы, загружаем ее и в меню «Устройства» выбираем «Установить дополнения гостевой ОС». Вместо этого можно нажать комбинацию клавиш правый Ctrl+D. После установки дополнений система будет готова к работе.

vb14

Рис. 21. Установленная и готовая к работе система Windows XP в VirtualBox

Загрузка гостевой операционной системы после запуска VirtualBox осуществляется кнопкой «Старт». Переключение указателя мышки между основной и гостевой системой осуществляется автоматически, но можно переключить принудительно с помощью кнопки правый Ctrl (Host key — можно изменить в настройках) и правый Ctrl+I. Эта же кнопка в сочетании с различными клавишами служит для выполнения ряда функций:

Host key+F — переключение в полноэкранный режим и обратно.

Host key+Del — заменяет комбинацию Ctrl+Alt+Del.

Host key+I — отключить интеграцию мышки.

Host key+С — переключение в режим масштабирования, в котором можно задать произвольный размер окна, возврат в стандартный режим происходит с помощью той же комбинации клавиш.

Host key+D — установка дополнений гостевой операционной системы.

Host key+T — сделать снимок, сохранить состояние ОС. Восстановить систему из сохраненного состояния можно будет в основном окне менеджера VirtualBox, нажав на кнопку «Снимки». Очень удобная функция для борьбы с вирусами, тестирования и отладки программ, которые могут повредить систему. Всегда можно сделать откат системы в стабильное состояние.

Host key+S — открыть окно настроек.

Host key+R — перезагрузить систему.

Host key+Q — закрыть виртуальную машину (выйти из системы).

Источник

Wine — набор библиотек и утилит для запуска Windows программ и игр внутри Linux.

История Wine

Первая версия Wine появилась в 1993 году и изначально была разработана для запуска 16-битных приложений Windows 3.1 внутри Linux.

Основателем проекта является Боб Амштадт (Bob Amstadt). С 1994 г проект перешел под управление программиста Александра Джуллиарда (Alexandre Julliard).

Название

Название Wine (W.I.N.E) является рекурсивным акронимом фразы «Wine Is Not an Emulator» — «Вайн это не эмулятор.»

Слово wine в переводе с английского означает вино. По этой причине в терминологии программы используется понятие бутылок (см. ниже). Бутылка (или префикс) — это директория (среда) внутри которой выполняется Windows программа.

Wine это не эмулятор

Wine работает не как эмулятор и не как виртуальная машина, он не эмулирует систему Windows, не создает имитацию Windows и не пытается реализовать ее логику. Вместо этого он на лету выполняет преобразование API-вызовов Windows в POSIX-совместимые вызовы.

То есть это что-то вроде прослойки между приложениями для Windows и системой Linux, которая позволяет Windows программам выполняться так, как если бы они были изначально написаны для Linux.

Wine не создает эмуляцию Windows, вместо этого приложения Windows запускаются прямо внутри текущей операционной системы.

Wine работает не только под Linux, но и под другие POSIX-совместимые операционные системы — macOS и *BSD.

Wine также работает под Windows. В Windows его обычно используют для того, чтобы запускать старые программы в современных версиях Windows.

Среда Wine

Для текущего пользователя Wine создает в его домашней директории каталог .wine, в котором создается структура директорий аналогичная Windows.

Внутри каталога drive_c содержатся директории Program Files, ProgramData, windows, users. Там же хранится реестр.

Внутри директории windows размещаются DLL файлы (библиотеки). Это не библиотеки из Windows. Они были написаны с нуля на основе документации к Windows API и фактически реализуют функции оригинальных библиотек, но для Linux.

При работе Windows приложениям могут потребоваться дополнительные DLL библиотеки, которые не предоставлены Wine. В таком случае могут использоваться оригинальные Windows-версии таких библиотек.

Директория .wine называется «префиксом» или «бутылкой». Для некоторых программ может потребоваться создание отдельного префикса, то есть для ее работы нужны будут какие-то специфические настройки и она будет работать в среде другой директории отличной от ~/.wine. Можно создавать сколько угодно префиксов (бутылок).

Как запускать программы Windows через Wine

Чтобы запустить программу, написанную для Windows, в простейшем случае достаточно выполнить команду:

wine program.exe

Через Wine также можно запускать установщики Windows приложений и устанавливать их прямо в Linux.

wine setup.exe

Список программ и игр, работающих через Wine

На официальном сайте Wine ведется база данных программ и игр, которые можно запустить через Wine: Wine Application Database (AppDB) — https://appdb.winehq.org.

Для каждого приложения можно получить информацию об особенностях установки, запуска и настройки данного приложения через Wine, о проблемах и багах, с которыми можно столкнуться.

База данных постоянно пополняется. В ней насчитывается более 26000 приложений. Введутся списки самых популярных приложений, они делятся на Платиновые, Золотые и Серебряные. Вот некоторые из самых популярных программ и игр, работающих через Wine (конкретную версию уточняйте в базе данных AppDB):

  • Adobe Animate
  • Adobe Photoshop
  • Microsoft Office
  • Total Commander
  • Lingvo
  • 1C:Предприятие
  • Гарант
  • КонсультантПлюс
  • Final Fantasy XI Online
  • StarCraft
  • Warcraft III
  • World of Warcraft
  • Counter-Strike: Source
  • EVE Online
  • Half-Life 2
  • Magic: The Gathering Online
  • The Sims 3
  • И многие многие другие…

Использование отдельных префиксов (бутылок)

Как было сказано выше, некоторые программы должны запускаться внутри своей среды, то есть должны быть изолированы от других приложений. Для этого им нужен отдельный префикс (отдельная директория среды, в которой они будут работать).

Префикс задается переменной WINEPREFIX.

Сначала создадим новый префикс. Выполняем команду:

WINEPREFIX="/home/pingvinus/.wine2/" winecfg

Теперь выполняем саму программу и указываем для нее новый префикс:

WINEPREFIX="/home/pingvinus/.wine2/" wine /путь/до/файла/setup.exe

Установка недостающих библиотек (утилита Winetricks)

Очень часто для работы программ требуются дополнительные компоненты (библиотеки, шрифты), которых нет в Wine. Их можно установить самостоятельно, но это может стать очень трудоемким процессом, так как придётся искать и устанавливать каждый компонент вручную.

Для автоматического поиска и установки библиотек была создана специальная вспомогательная утилита Winetricks.

Утилита Winetricks

Winetricks — это графическая утилита, которая умеет автоматически скачивать и устанавливать необходимые компоненты. Также, Winetricks поддерживает автоматическую загрузку и установку некоторых игр и программ (для некоторых требуется наличие оригинального диска).

Winetricks поддерживает установку более сотни различных компонентов. Среди них — .Net Framework, Mono, DirectX, DivX и XviD кодеки, шрифты Windows и многие другие.

Winetricks список библиотек для Wine

Нужно понимать, что Winetricks не является таблеткой от всех проблем и всегда могут потребоваться компоненты, которые Winetricks не поддерживает.

При первом запуске Winetricks предложит установить некоторые из часто используемых компонентов.

Заключение

На нашем сайте вы также можете ознакомиться со следующими материалами:

  • Аналоги программ Windows в Linux
  • Игровые клиенты и сервисы (эмуляторы) для Linux
  • Виртуальные машины и эмуляторы для Linux

Установка

Установка Wine в Ubuntu Linux и Linux Mint через PPA репозиторий

Wine есть в штатных репозиториях Ubuntu, но там может содержаться не самая свежая версия, поэтому рекомендуется устанавливать программу из PPA-репозитория, предлагаемого разработчиками.

Во время установки Wine дополнительно устанавливается довольно много других зависимостей (это может быть более 100 дополнительных компонентов).

Установка Wine из штатных репозиториев Ubuntu (не самая свежая версия)

Для установки Wine из штатных репозиториев Ubuntu, выполните команду:

sudo apt install wine-stable

Для установки Winetricks выполните команду:

sudo apt install winetricks

Установка Wine из PPA репозитория (рекомендуется)

Процесс установки Wine в Ubuntu Linux описан в официальном руководстве. Рассмотрим, как установить Wine в Ubuntu Linux, используя PPA репозиторий.

Если у вас 64-х битная версия системы, то нужно разрешить использование 32-х битной архитектуры. Выполняем команду:

sudo dpkg --add-architecture i386

Устанавливаем ключ для репозитория — выполняем команды:

wget -nc https://dl.winehq.org/wine-builds/winehq.key
sudo apt-key add winehq.key

Добавляем сам репозиторий. Выберите команду для вашего дистрибутива:

# Ubuntu 21.04
sudo add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ hirsute main'

# Ubuntu 20.10
sudo add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ groovy main'

# Ubuntu 20.04 Linux Mint 20.x
sudo add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main'

# Ubuntu 18.10:
sudo apt-add-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ cosmic main'

# Ubuntu 18.04 и Linux Mint 19.x:
sudo apt-add-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ bionic main'

Далее обновляем информацию о пакетах:

sudo apt update

Устанавливаем Wine. Для установки стабильной версии выполняем команду:

sudo apt install --install-recommends winehq-stable

Для установки самой свежей, но возможно не очень стабильной версии используется команда:

sudo apt install --install-recommends winehq-devel

Также можно установить Winetricks:

sudo apt install winetricks

Установка в Ubuntu (LinuxMint)

sudo apt install wine-stable

Установка в ArchLinux (Manjaro)

sudo pacman -S wine

Установка в Fedora

sudo dnf install wine

Установка в openSuse

sudo zypper install wine

Установка в Gentoo

sudo emerge -a virtual/wine

Разработка

Исходный код:
  • Open Source (открыт)

Языки программирования:
  • C

Программа кроссплатформенная
Работает в:

  • BSD
  • Linux
  • MacOS
  • Windows

0 / 0 / 1

Регистрация: 19.04.2018

Сообщений: 7

1

21.08.2018, 13:58. Показов 2465. Ответов 9


Доброго времени суток всем!
Прошу помочь/подсказать куда копать в моей проблемке)
Итак что имеется:
1) Был портирован рабочий проект из под Windows/Delphi7 на Windows/Lazarus, тут вопросов не было…. при правке синтаксиса и вызовов, проект запустился.
2) Далее портирование проходило из под Windows/Lazarus на Linux(Mint)/Lazarus, тут и появилась проблема. Проект компилируется, собирается, при попытке старта происходит непонятная вещь, сразу выдаётся окно «Execution stopped»при этом никаких ошибок не выдаёт.
Может кто сталкивался с подобной проблемой, буду признателен за помощь!
Проект приложения — оконный.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



155 / 107 / 36

Регистрация: 27.06.2018

Сообщений: 249

21.08.2018, 14:12

2

Да, обычно ошибка в 37 строке.

Без кода конкретно сказать нечего. Вдруг там что-то типа CreateXXX('c:файл... или подобные Win-приблуды

Что отладчик говорит?



0



0 / 0 / 1

Регистрация: 19.04.2018

Сообщений: 7

21.08.2018, 14:35

 [ТС]

3

Прикладываю «логи отладчика»



0



0 / 0 / 1

Регистрация: 19.04.2018

Сообщений: 7

21.08.2018, 14:47

 [ТС]

4

Кликните здесь для просмотра всего текста

<unset env DISPLAY>
&»unset env DISPLAYn»
^done
(gdb)
<-gdb-set env DISPLAY=:0>
^done
(gdb)
<-file-exec-and-symbols «/home/user/Desktop/sobranniy_project/ready/ServiceARM»>
^done
(gdb)
<-gdb-set language pascal>
^done
(gdb)
<-environment-cd .>
^done
(gdb)
<-environment-cd «/home/user/Desktop/sobranniy_project/ready/»>
^done
(gdb)
<-data-evaluate-expression FPC_THREADVAR_RELOCATE_PROC>
^error,msg=»No symbol «FPC_THREADVAR_RELOCATE_PROC» in current context.»
(gdb)
<info functions FPC_CPUINIT>
&»info functions FPC_CPUINITn»
~»All functions matching regular expression «FPC_CPUINIT»:n»
~»nNon-debugging symbols:n»
~»0x08060080 SYSTEM_$$_FPC_CPUINITn»
^done
(gdb)
<-exec-arguments >
^done
(gdb)
<set inferior-tty /dev/pts/0>
&»set inferior-tty /dev/pts/0n»
^done
(gdb)
<-gdb-set language pascal>
^done
(gdb)
<ptype TObject>
&»ptype TObjectn»
~»type = ^TOBJECT = class n»
~» publicn»
~» function CREATE () : TOBJECT;n»
~» procedure DESTROY (); virtual;n»
~» function NEWINSTANCE () : TOBJECT; virtual;n»
~» procedure FREEINSTANCE (); virtual;n»
~» function SAFECALLEXCEPTION () : HRESULT; virtual;n»
~» procedure DEFAULTHANDLER (); virtual;n»
~» procedure FREE ();n»
~» function INITINSTANCE () : TOBJECT;n»
~» procedure CLEANUPINSTANCE ();n»
~» function CLASSTYPE () : TCLASS;n»
~» function CLASSINFO () : POINTER;n»
~» function CLASSNAME () : SHORTSTRING;n»
~» function CLASSNAMEIS () : BOOLEAN;n»
~» function CLASSPARENT () : TCLASS;n»
~» function INSTANCESIZE () : LONGINT;n»
~» function INHERITSFROM () : BOOLEAN;n»
~» function STRINGMESSAGETABLE () : PSTRINGMESSAGETABLE;n»
~» function METHODADDRESS () : POINTER;n»
~» function METHODNAME () : SHORTSTRING;n»
~» function FIELDADDRESS () : POINTER;n»
~» procedure AFTERCONSTRUCTION (); virtual;n»
~» procedure BEFOREDESTRUCTION (); virtual;n»
~» procedure DEFAULTHANDLERSTR (); virtual;n»
~» procedure DISPATCH (); virtual;n»
~» procedure DISPATCHSTR (); virtual;n»
~» function GETINTERFACE () : BOOLEAN;n»
~» function GETINTERFACE () : BOOLEAN;n»
~» function GETINTERFACEBYSTR () : BOOLEAN;n»
~» function GETINTERFACEWEAK () : BOOLEAN;n»
~» function GETINTERFACEENTRY () : PINTERFACEENTRY;n»
~» function GETINTERFACEENTRYBYSTR () : PINTERFACEENTRY;n»
~» function GETINTERFACETABLE () : PINTERFACETABLE;n»
~» function UNITNAME () : ANSISTRING;n»
~» function EQUALS () : BOOLEAN; virtual;n»
~» function GETHASHCODE () : LONGINT; virtual;n»
~» function TOSTRING () : ANSISTRING; virtual;n»
~»endn»
^done
(gdb)
<ptype Exception>
&»ptype Exceptionn»
~»type = ^EXCEPTION = class : public TOBJECT n»
~» privaten»
~» FMESSAGE : ANSISTRING;n»
~» FHELPCONTEXT : LONGINT;n»
~» HELPCONTEXT : LONGINT;n»
~» MESSAGE : ANSISTRING;n»
~»n»
~» publicn»
~» function CREATE () : EXCEPTION;n»
~» function CREATEFMT () : EXCEPTION;n»
~» function CREATERES () : EXCEPTION;n»
~» function CREATERESFMT () : EXCEPTION;n»
~» function CREATEHELP () : EXCEPTION;n»
~» function CREATEFMTHELP () : EXCEPTION;n»
~» function CREATERESHELP () : EXCEPTION;n»
~» function CREATERESFMTHELP () : EXCEPTION;n»
~» function TOSTRING () : ANSISTRING; virtual;n»
~»endn»
^done
(gdb)
<ptype Shortstring>
&»ptype Shortstringn»
~»type = ShortString = record n»
~» length : BYTE;n»
~» st : array [1..255] of CHAR;n»
~»endn»
^done
(gdb)
<ptype pointer>
&»ptype pointern»
~»type = ^pointern»
^done
(gdb)
<ptype byte>
&»ptype byten»
~»type = BYTEn»
^done
(gdb)
<set print elements 2500>
&»set print elements 2500n»
^done
(gdb)
<info file>
&»info filen»
~»Symbols from «/home/user/Desktop/sobranniy_project/ready/ServiceARM».n»
~»Local exec file:n»
~»t`/home/user/Desktop/sobranniy_project/ready/ServiceARM’, file type elf32-i386.n»
~»tEntry point: 0x85ba080n»
~»t0x080480f4 — 0x08048107 is .interpn»
~»t0x08048108 — 0x0804a534 is .hashn»
~»t0x0804a534 — 0x0804f554 is .dynsymn»
~»t0x0804f554 — 0x08056b6f is .dynstrn»
~»t0x08056b70 — 0x08057574 is .gnu.versionn»
~»t0x08057574 — 0x080575f4 is .gnu.version_rn»
~»t0x080575f4 — 0x080576b4 is .rel.dynn»
~»t0x080576b4 — 0x08059dbc is .rel.pltn»
~»t0x08059dbc — 0x08059ddf is .initn»
~»t0x08059de0 — 0x0805ec00 is .pltn»
~»t0x0805ec00 — 0x085ba100 is .textn»
~»t0x085ba100 — 0x085ba114 is .finin»
~»t0x085ba120 — 0x086293d0 is .rodatan»
~»t0x086293d0 — 0x086293d4 is .eh_framen»
~»t0x0862a3d4 — 0x0862a3d8 is .init_arrayn»
~»t0x0862a3d8 — 0x0862a3dc is .fini_arrayn»
~»t0x0862a3dc — 0x0862a3e0 is .jcrn»
~»t0x0862a3e0 — 0x0862a530 is .dynamicn»
~»t0x0862a530 — 0x0862a534 is .gotn»
~»t0x0862a534 — 0x0862b8c4 is .got.pltn»
~»t0x0862b8d0 — 0x087e04d8 is .datan»
~»t0x087e04d8 — 0x0880de1c is fpc.resourcesn»
~»t0x0880de20 — 0x0882add4 is .bssn»
~»t0x0882add4 — 0x0882b0ac is fpc.reshandlesn»
^done
(gdb)
<-data-evaluate-expression sizeof(POINTER)>
^done,value=»4″
(gdb)
<-break-insert main>
^done,bkpt={number=»54″,type=»breakpoint»,disp=»ke ep»,enabled=»y»,addr=»0x0805ecdb»,func=»main»,file =»ServiceARM.lpr»,fullname=»/home/user/Desktop/sobranniy_project/ServiceARM.lpr»,line=»47″,thread-groups=[«i1″],times=»0″,original-location=»main»}
(gdb)
<-break-insert *140222592>
^done,bkpt={number=»55″,type=»breakpoint»,disp=»ke ep»,enabled=»y»,addr=»0x085ba080″,at=»<SI_C21_$$__ FPC_LIBC21_START>»,thread-groups=[«i1″],times=»0″,original-location=»*140222592»}
(gdb)
<-break-insert +0>
^done,bkpt={number=»56″,type=»breakpoint»,disp=»ke ep»,enabled=»y»,addr=»0x0805ecdb»,func=»main»,file =»ServiceARM.lpr»,fullname=»/home/user/Desktop/sobranniy_project/ServiceARM.lpr»,line=»43″,thread-groups=[«i1″],times=»0″,original-location=»/home/user/Desktop/sobranniy_project/ServiceARM.lpr:+0»}
(gdb)
<-exec-run>
=thread-group-started,id=»i1″,pid=»2581″
=thread-created,id=»1″,group-id=»i1″
^running
*running,thread-id=»all»
(gdb)
=library-loaded,id=»/lib/ld-linux.so.2″,target-name=»/lib/ld-linux.so.2″,host-name=»/lib/ld-linux.so.2″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libdl.so.2″,target-name=»/lib/i386-linux-gnu/libdl.so.2″,host-name=»/lib/i386-linux-gnu/libdl.so.2″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libpthread.so.0″,target-name=»/lib/i386-linux-gnu/libpthread.so.0″,host-name=»/lib/i386-linux-gnu/libpthread.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libX11.so.6″,target-name=»/usr/lib/i386-linux-gnu/libX11.so.6″,host-name=»/usr/lib/i386-linux-gnu/libX11.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgdk_pixbuf-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgdk_pixbuf-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgdk_pixbuf-2.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgobject-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgobject-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgobject-2.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libglib-2.0.so.0″,target-name=»/lib/i386-linux-gnu/libglib-2.0.so.0″,host-name=»/lib/i386-linux-gnu/libglib-2.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgthread-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgthread-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgthread-2.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgmodule-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgmodule-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgmodule-2.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libpango-1.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libpango-1.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libpango-1.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libcairo.so.2″,target-name=»/usr/lib/i386-linux-gnu/libcairo.so.2″,host-name=»/usr/lib/i386-linux-gnu/libcairo.so.2″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libatk-1.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libatk-1.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libatk-1.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libc.so.6″,target-name=»/lib/i386-linux-gnu/libc.so.6″,host-name=»/lib/i386-linux-gnu/libc.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libpangocairo-1.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libpangocairo-1.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libpangocairo-1.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgio-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgio-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgio-2.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libfontconfig.so.1″,target-name=»/usr/lib/i386-linux-gnu/libfontconfig.so.1″,host-name=»/usr/lib/i386-linux-gnu/libfontconfig.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXrender.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXrender.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXrender.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXinerama.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXinerama.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXinerama.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXi.so.6″,target-name=»/usr/lib/i386-linux-gnu/libXi.so.6″,host-name=»/usr/lib/i386-linux-gnu/libXi.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXrandr.so.2″,target-name=»/usr/lib/i386-linux-gnu/libXrandr.so.2″,host-name=»/usr/lib/i386-linux-gnu/libXrandr.so.2″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXcursor.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXcursor.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXcursor.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXcomposite.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXcomposite.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXcomposite.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXdamage.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXdamage.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXdamage.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXfixes.so.3″,target-name=»/usr/lib/i386-linux-gnu/libXfixes.so.3″,host-name=»/usr/lib/i386-linux-gnu/libXfixes.so.3″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXext.so.6″,target-name=»/usr/lib/i386-linux-gnu/libXext.so.6″,host-name=»/usr/lib/i386-linux-gnu/libXext.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libm.so.6″,target-name=»/lib/i386-linux-gnu/libm.so.6″,host-name=»/lib/i386-linux-gnu/libm.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libxcb.so.1″,target-name=»/usr/lib/i386-linux-gnu/libxcb.so.1″,host-name=»/usr/lib/i386-linux-gnu/libxcb.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libpangoft2-1.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libpangoft2-1.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libpangoft2-1.0.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libffi.so.6″,target-name=»/usr/lib/i386-linux-gnu/libffi.so.6″,host-name=»/usr/lib/i386-linux-gnu/libffi.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libpcre.so.3″,target-name=»/lib/i386-linux-gnu/libpcre.so.3″,host-name=»/lib/i386-linux-gnu/libpcre.so.3″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libthai.so.0″,target-name=»/usr/lib/i386-linux-gnu/libthai.so.0″,host-name=»/usr/lib/i386-linux-gnu/libthai.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libpixman-1.so.0″,target-name=»/usr/lib/i386-linux-gnu/libpixman-1.so.0″,host-name=»/usr/lib/i386-linux-gnu/libpixman-1.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libfreetype.so.6″,target-name=»/usr/lib/i386-linux-gnu/libfreetype.so.6″,host-name=»/usr/lib/i386-linux-gnu/libfreetype.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libpng12.so.0″,target-name=»/lib/i386-linux-gnu/libpng12.so.0″,host-name=»/lib/i386-linux-gnu/libpng12.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libxcb-shm.so.0″,target-name=»/usr/lib/i386-linux-gnu/libxcb-shm.so.0″,host-name=»/usr/lib/i386-linux-gnu/libxcb-shm.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libxcb-render.so.0″,target-name=»/usr/lib/i386-linux-gnu/libxcb-render.so.0″,host-name=»/usr/lib/i386-linux-gnu/libxcb-render.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libz.so.1″,target-name=»/lib/i386-linux-gnu/libz.so.1″,host-name=»/lib/i386-linux-gnu/libz.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/librt.so.1″,target-name=»/lib/i386-linux-gnu/librt.so.1″,host-name=»/lib/i386-linux-gnu/librt.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libselinux.so.1″,target-name=»/lib/i386-linux-gnu/libselinux.so.1″,host-name=»/lib/i386-linux-gnu/libselinux.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libresolv.so.2″,target-name=»/lib/i386-linux-gnu/libresolv.so.2″,host-name=»/lib/i386-linux-gnu/libresolv.so.2″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libexpat.so.1″,target-name=»/lib/i386-linux-gnu/libexpat.so.1″,host-name=»/lib/i386-linux-gnu/libexpat.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXau.so.6″,target-name=»/usr/lib/i386-linux-gnu/libXau.so.6″,host-name=»/usr/lib/i386-linux-gnu/libXau.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libXdmcp.so.6″,target-name=»/usr/lib/i386-linux-gnu/libXdmcp.so.6″,host-name=»/usr/lib/i386-linux-gnu/libXdmcp.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libharfbuzz.so.0″,target-name=»/usr/lib/i386-linux-gnu/libharfbuzz.so.0″,host-name=»/usr/lib/i386-linux-gnu/libharfbuzz.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libdatrie.so.1″,target-name=»/usr/lib/i386-linux-gnu/libdatrie.so.1″,host-name=»/usr/lib/i386-linux-gnu/libdatrie.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgraphite2.so.3″,target-name=»/usr/lib/i386-linux-gnu/libgraphite2.so.3″,host-name=»/usr/lib/i386-linux-gnu/libgraphite2.so.3″,symbols-loaded=»0″,thread-group=»i1″
~»[Thread debugging using libthread_db enabled]n»
~»Using host libthread_db library «/lib/i386-linux-gnu/libthread_db.so.1″.n»
=breakpoint-modified,bkpt={number=»55″,type=»breakpoint»,disp= «keep»,enabled=»y»,addr=»0x085ba080″,at=»<SI_C21_$ $__FPC_LIBC21_START>»,thread-groups=[«i1″],times=»1″,original-location=»*140222592»}
*stopped,reason=»breakpoint-hit»,disp=»keep»,bkptno=»55″,frame={addr=»0x085ba0 80″,func=»SI_C21_$$__FPC_LIBC21_START»,args=[]},thread-id=»1″,stopped-threads=»all»,core=»0″
(gdb)
<-break-delete 54>
^done
(gdb)
<-break-delete 55>
^done
(gdb)
<-break-delete 56>
^done
(gdb)
<info address FPC_RAISEEXCEPTION>
&»info address FPC_RAISEEXCEPTIONn»
~»Symbol «FPC_RAISEEXCEPTION» is at 0x8070c40 in a file compiled without debugging.n»
^done
(gdb)
<-break-insert *134679616>
^done,bkpt={number=»57″,type=»breakpoint»,disp=»ke ep»,enabled=»y»,addr=»0x08070c40″,at=»<fpc_raiseex ception>»,thread-groups=[«i1″],times=»0″,original-location=»*134679616»}
(gdb)
<info address FPC_BREAK_ERROR>
&»info address FPC_BREAK_ERRORn»
~»Symbol «FPC_BREAK_ERROR» is at 0x8073570 in a file compiled without debugging.n»
^done
(gdb)
<-break-insert *134690160>
^done,bkpt={number=»58″,type=»breakpoint»,disp=»ke ep»,enabled=»y»,addr=»0x08073570″,at=»<SYSTEM_$$_H ANDLEERRORADDRFRAME$LONGINT$POINTER$POINTER>»,thre ad-groups=[«i1″],times=»0″,original-location=»*134690160»}
(gdb)
<info address FPC_RUNERROR>
&»info address FPC_RUNERRORn»
~»Symbol «FPC_RUNERROR» is at 0x8073660 in a file compiled without debugging.n»
^done
(gdb)
<-break-insert *134690400>
^done,bkpt={number=»59″,type=»breakpoint»,disp=»ke ep»,enabled=»y»,addr=»0x08073660″,at=»<SYSTEM_$$_R UNERROR$WORD>»,thread-groups=[«i1″],times=»0″,original-location=»*134690400»}
(gdb)
<-symbol-list-lines «/home/user/Desktop/sobranniy_project/Start.pas»>
^done,lines=[{pc=»0x0809a6e0″,line=»58″},{pc=»0x0809a6fa»,line= «85»},{pc=»0x0809a700″,line=»115″},{pc=»0x0809a71a «,line=»115″},{pc=»0x0809a768″,line=»117″},{pc=»0x 0809a790″,line=»120″},{pc=»0x0809a7ce»,line=»121″} ,{pc=»0x0809a7e7″,line=»123″},{pc=»0x0809a81c»,lin e=»124″},{pc=»0x0809a851″,line=»127″},{pc=»0x0809a 861″,line=»128″},{pc=»0x0809a869″,line=»130″},{pc= «0x0809a8c8″,line=»131″},{pc=»0x0809a95d»,line=»13 4″},{pc=»0x0809a99c»,line=»134″},{pc=»0x0809a9b0″, line=»97″},{pc=»0x0809a9e1″,line=»97″},{pc=»0x0809 aa0d»,line=»99″},{pc=»0x0809aa2b»,line=»100″},{pc= «0x0809aa2f»,line=»101″},{pc=»0x0809aa65″,line=»10 2″},{pc=»0x0809aad3″,line=»104″},{pc=»0x0809aad7″, line=»105″},{pc=»0x0809ab36″,line=»107″},{pc=»0x08 09ab65″,line=»109″},{pc=»0x0809ab82″,line=»113″},{ pc=»0x0809aba4″,line=»113″},{pc=»0x0809abb0″,line= «140»},{pc=»0x0809abca»,line=»141″},{pc=»0x0809abd 7″,line=»142″},{pc=»0x0809abe4″,line=»143″},{pc=»0 x0809abee»,line=»158″},{pc=»0x0809ac02″,line=»159″ },{pc=»0x0809ac16″,line=»160″},{pc=»0x0809ac1e»,li ne=»161″},{pc=»0x0809ac58″,line=»162″},{pc=»0x0809 ac60″,line=»165″},{pc=»0x0809ac7a»,line=»165″},{pc =»0x0809ac9f»,line=»166″},{pc=»0x0809acbc»,line=»1 67″},{pc=»0x0809acc5″,line=»168″},{pc=»0x0809accc» ,line=»170″},{pc=»0x0809ad4c»,line=»173″},{pc=»0x0 809ad5e»,line=»173″},{pc=»0x0809ad70″,line=»178″}, {pc=»0x0809ad8d»,line=»179″},{pc=»0x0809adc7″,line =»180″},{pc=»0x0809ae01″,line=»181″},{pc=»0x0809ae 0b»,line=»182″},{pc=»0x0809ae15″,line=»183″},{pc=» 0x0809ae20″,line=»186″},{pc=»0x0809ae37″,line=»188 «},{pc=»0x0809ae40″,line=»191″},{pc=»0x0809ae57″,l ine=»193″},{pc=»0x0809ae60″,line=»196″},{pc=»0x080 9ae7a»,line=»197″},{pc=»0x0809ae90″,line=»199″},{p c=»0x0809aee2″,line=»200″},{pc=»0x0809af36″,line=» 201″},{pc=»0x0809af73″,line=»204″},{pc=»0x0809af89 «,line=»206″},{pc=»0x0809afc6″,line=»207″},{pc=»0x 0809b000″,line=»209″},{pc=»0x0809b010″,line=»215″} ,{pc=»0x0809b02a»,line=»215″},{pc=»0x0809b05d»,lin e=»216″},{pc=»0x0809b06f»,line=»217″},{pc=»0x0809b 082″,line=»220″},{pc=»0x0809b095″,line=»222″},{pc= «0x0809b0ea»,line=»224″},{pc=»0x0809b124″,line=»22 5″},{pc=»0x0809b163″,line=»229″},{pc=»0x0809b19d», line=»230″},{pc=»0x0809b1da»,line=»231″},{pc=»0x08 09b214″,line=»234″},{pc=»0x0809b271″,line=»235″},{ pc=»0x0809b2ad»,line=»237″},{pc=»0x0809b2ec»,line= «238»},{pc=»0x0809b30e»,line=»238″}]
(gdb)
<-exec-continue>
^running
*running,thread-id=»all»
(gdb)



0



0 / 0 / 1

Регистрация: 19.04.2018

Сообщений: 7

21.08.2018, 14:53

 [ТС]

5

Кликните здесь для просмотра всего текста

=library-loaded,id=»/usr/lib/i386-linux-gnu/gconv/UTF-16.so»,target-name=»/usr/lib/i386-linux-gnu/gconv/UTF-16.so»,host-name=»/usr/lib/i386-linux-gnu/gconv/UTF-16.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/liboverlay-scrollbar.so»,target-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/liboverlay-scrollbar.so»,host-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/liboverlay-scrollbar.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libunity-gtk-module.so»,target-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libunity-gtk-module.so»,host-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libunity-gtk-module.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libunity-gtk2-parser.so.0″,target-name=»/usr/lib/i386-linux-gnu/libunity-gtk2-parser.so.0″,host-name=»/usr/lib/i386-linux-gnu/libunity-gtk2-parser.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/engines/libmurrine.so»,target-name=»/usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/engines/libmurrine.so»,host-name=»/usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/engines/libmurrine.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libcanberra-gtk-module.so»,target-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libcanberra-gtk-module.so»,host-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libcanberra-gtk-module.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libcanberra-gtk.so.0″,target-name=»/usr/lib/i386-linux-gnu/libcanberra-gtk.so.0″,host-name=»/usr/lib/i386-linux-gnu/libcanberra-gtk.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libcanberra.so.0″,target-name=»/usr/lib/i386-linux-gnu/libcanberra.so.0″,host-name=»/usr/lib/i386-linux-gnu/libcanberra.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libvorbisfile.so.3″,target-name=»/usr/lib/i386-linux-gnu/libvorbisfile.so.3″,host-name=»/usr/lib/i386-linux-gnu/libvorbisfile.so.3″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libtdb.so.1″,target-name=»/usr/lib/i386-linux-gnu/libtdb.so.1″,host-name=»/usr/lib/i386-linux-gnu/libtdb.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libltdl.so.7″,target-name=»/usr/lib/i386-linux-gnu/libltdl.so.7″,host-name=»/usr/lib/i386-linux-gnu/libltdl.so.7″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libvorbis.so.0″,target-name=»/usr/lib/i386-linux-gnu/libvorbis.so.0″,host-name=»/usr/lib/i386-linux-gnu/libvorbis.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libogg.so.0″,target-name=»/usr/lib/i386-linux-gnu/libogg.so.0″,host-name=»/usr/lib/i386-linux-gnu/libogg.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgiognutls.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiognutls.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiognutls.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libp11-kit.so.0″,target-name=»/usr/lib/i386-linux-gnu/libp11-kit.so.0″,host-name=»/usr/lib/i386-linux-gnu/libp11-kit.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libgnutls.so.26″,target-name=»/usr/lib/i386-linux-gnu/libgnutls.so.26″,host-name=»/usr/lib/i386-linux-gnu/libgnutls.so.26″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libgcrypt.so.11″,target-name=»/lib/i386-linux-gnu/libgcrypt.so.11″,host-name=»/lib/i386-linux-gnu/libgcrypt.so.11″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libtasn1.so.6″,target-name=»/usr/lib/i386-linux-gnu/libtasn1.so.6″,host-name=»/usr/lib/i386-linux-gnu/libtasn1.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libgpg-error.so.0″,target-name=»/lib/i386-linux-gnu/libgpg-error.so.0″,host-name=»/lib/i386-linux-gnu/libgpg-error.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgiognutls.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiognutls.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiognutls.so»,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libp11-kit.so.0″,target-name=»/usr/lib/i386-linux-gnu/libp11-kit.so.0″,host-name=»/usr/lib/i386-linux-gnu/libp11-kit.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgnutls.so.26″,target-name=»/usr/lib/i386-linux-gnu/libgnutls.so.26″,host-name=»/usr/lib/i386-linux-gnu/libgnutls.so.26″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libgcrypt.so.11″,target-name=»/lib/i386-linux-gnu/libgcrypt.so.11″,host-name=»/lib/i386-linux-gnu/libgcrypt.so.11″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libtasn1.so.6″,target-name=»/usr/lib/i386-linux-gnu/libtasn1.so.6″,host-name=»/usr/lib/i386-linux-gnu/libtasn1.so.6″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libgpg-error.so.0″,target-name=»/lib/i386-linux-gnu/libgpg-error.so.0″,host-name=»/lib/i386-linux-gnu/libgpg-error.so.0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgiolibproxy.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiolibproxy.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiolibproxy.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libproxy.so.1″,target-name=»/usr/lib/i386-linux-gnu/libproxy.so.1″,host-name=»/usr/lib/i386-linux-gnu/libproxy.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/libstdc++.so.6″,target-name=»/usr/lib/i386-linux-gnu/libstdc++.so.6″,host-name=»/usr/lib/i386-linux-gnu/libstdc++.so.6″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libgcc_s.so.1″,target-name=»/lib/i386-linux-gnu/libgcc_s.so.1″,host-name=»/lib/i386-linux-gnu/libgcc_s.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgiolibproxy.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiolibproxy.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiolibproxy.so»,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgvfsdbus.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgvfsdbus.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgvfsdbus.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gvfs/libgvfscommon.so»,target-name=»/usr/lib/i386-linux-gnu/gvfs/libgvfscommon.so»,host-name=»/usr/lib/i386-linux-gnu/gvfs/libgvfscommon.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libudev.so.1″,target-name=»/lib/i386-linux-gnu/libudev.so.1″,host-name=»/lib/i386-linux-gnu/libudev.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libcgmanager.so.0″,target-name=»/lib/i386-linux-gnu/libcgmanager.so.0″,host-name=»/lib/i386-linux-gnu/libcgmanager.so.0″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libnih.so.1″,target-name=»/lib/i386-linux-gnu/libnih.so.1″,host-name=»/lib/i386-linux-gnu/libnih.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libnih-dbus.so.1″,target-name=»/lib/i386-linux-gnu/libnih-dbus.so.1″,host-name=»/lib/i386-linux-gnu/libnih-dbus.so.1″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/lib/i386-linux-gnu/libdbus-1.so.3″,target-name=»/lib/i386-linux-gnu/libdbus-1.so.3″,host-name=»/lib/i386-linux-gnu/libdbus-1.so.3″,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgioremote-volume-monitor.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgioremote-volume-monitor.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgioremote-volume-monitor.so»,symbols-loaded=»0″,thread-group=»i1″
=library-loaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgiognomeproxy.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiognomeproxy.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiognomeproxy.so»,symbols-loaded=»0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgiognomeproxy.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiognomeproxy.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgiognomeproxy.so»,thread-group=»i1″
=thread-created,id=»2″,group-id=»i1″
~»[New Thread 0xb68cdb40 (LWP 2582)]n»
*running,thread-id=»all»
=thread-created,id=»3″,group-id=»i1″
~»[New Thread 0xb5effb40 (LWP 2583)]n»
*running,thread-id=»all»
=breakpoint-modified,bkpt={number=»59″,type=»breakpoint»,disp= «keep»,enabled=»y»,addr=»0x08073660″,at=»<SYSTEM_$ $_RUNERROR$WORD>»,thread-groups=[«i1″],times=»1″,original-location=»*134690400»}
*stopped,reason=»breakpoint-hit»,disp=»keep»,bkptno=»59″,frame={addr=»0x080736 60″,func=»SYSTEM_$$_RUNERROR$WORD»,args=[]},thread-id=»1″,stopped-threads=»all»,core=»0″
(gdb)
<-data-evaluate-expression $eax>
^done,value=»142606547″
(gdb)
<-data-evaluate-expression $edx>
^done,value=»0″
(gdb)
<-data-evaluate-expression $ecx>
^done,value=»142665028″
(gdb)
<-stack-info-depth 33>
^done,depth=»5″
(gdb)
<-data-evaluate-expression $fp>
^done,value=»0xbffff5f0″
(gdb)
<-stack-select-frame 1>
^done
(gdb)
<-data-evaluate-expression $fp>
^done,value=»0xbffff5f8″
(gdb)
<-stack-select-frame 0>
^done
(gdb)
<info line *0>
&»info line *0n»
~»No line number information available.n»
^done
(gdb)
<-exec-continue>
^running
*running,thread-id=»1″
(gdb)
*running,thread-id=»all»
~»[Thread 0xb68cdb40 (LWP 2582) exited]n»
=thread-exited,id=»2″,group-id=»i1″
~»[Thread 0xb5effb40 (LWP 2583) exited]n»
=thread-exited,id=»3″,group-id=»i1″
=thread-exited,id=»1″,group-id=»i1″
=thread-group-exited,id=»i1″,exit-code=»0323″
*stopped,reason=»exited»,exit-code=»0323″
(gdb)
<-break-delete 57>
^done
(gdb)
<-break-delete 58>
^done
(gdb)
<-break-delete 59>
^done
(gdb)
<-file-exec-and-symbols >
=library-unloaded,id=»/lib/ld-linux.so.2″,target-name=»/lib/ld-linux.so.2″,host-name=»/lib/ld-linux.so.2″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libdl.so.2″,target-name=»/lib/i386-linux-gnu/libdl.so.2″,host-name=»/lib/i386-linux-gnu/libdl.so.2″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libpthread.so.0″,target-name=»/lib/i386-linux-gnu/libpthread.so.0″,host-name=»/lib/i386-linux-gnu/libpthread.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libX11.so.6″,target-name=»/usr/lib/i386-linux-gnu/libX11.so.6″,host-name=»/usr/lib/i386-linux-gnu/libX11.so.6″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgdk_pixbuf-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgdk_pixbuf-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgdk_pixbuf-2.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgobject-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgobject-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgobject-2.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libglib-2.0.so.0″,target-name=»/lib/i386-linux-gnu/libglib-2.0.so.0″,host-name=»/lib/i386-linux-gnu/libglib-2.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgthread-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgthread-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgthread-2.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgmodule-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgmodule-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgmodule-2.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libpango-1.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libpango-1.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libpango-1.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libcairo.so.2″,target-name=»/usr/lib/i386-linux-gnu/libcairo.so.2″,host-name=»/usr/lib/i386-linux-gnu/libcairo.so.2″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libatk-1.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libatk-1.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libatk-1.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libc.so.6″,target-name=»/lib/i386-linux-gnu/libc.so.6″,host-name=»/lib/i386-linux-gnu/libc.so.6″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libpangocairo-1.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libpangocairo-1.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libpangocairo-1.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgio-2.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libgio-2.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libgio-2.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libfontconfig.so.1″,target-name=»/usr/lib/i386-linux-gnu/libfontconfig.so.1″,host-name=»/usr/lib/i386-linux-gnu/libfontconfig.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXrender.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXrender.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXrender.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXinerama.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXinerama.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXinerama.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXi.so.6″,target-name=»/usr/lib/i386-linux-gnu/libXi.so.6″,host-name=»/usr/lib/i386-linux-gnu/libXi.so.6″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXrandr.so.2″,target-name=»/usr/lib/i386-linux-gnu/libXrandr.so.2″,host-name=»/usr/lib/i386-linux-gnu/libXrandr.so.2″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXcursor.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXcursor.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXcursor.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXcomposite.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXcomposite.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXcomposite.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXdamage.so.1″,target-name=»/usr/lib/i386-linux-gnu/libXdamage.so.1″,host-name=»/usr/lib/i386-linux-gnu/libXdamage.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXfixes.so.3″,target-name=»/usr/lib/i386-linux-gnu/libXfixes.so.3″,host-name=»/usr/lib/i386-linux-gnu/libXfixes.so.3″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXext.so.6″,target-name=»/usr/lib/i386-linux-gnu/libXext.so.6″,host-name=»/usr/lib/i386-linux-gnu/libXext.so.6″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libm.so.6″,target-name=»/lib/i386-linux-gnu/libm.so.6″,host-name=»/lib/i386-linux-gnu/libm.so.6″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libxcb.so.1″,target-name=»/usr/lib/i386-linux-gnu/libxcb.so.1″,host-name=»/usr/lib/i386-linux-gnu/libxcb.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libpangoft2-1.0.so.0″,target-name=»/usr/lib/i386-linux-gnu/libpangoft2-1.0.so.0″,host-name=»/usr/lib/i386-linux-gnu/libpangoft2-1.0.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libffi.so.6″,target-name=»/usr/lib/i386-linux-gnu/libffi.so.6″,host-name=»/usr/lib/i386-linux-gnu/libffi.so.6″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libpcre.so.3″,target-name=»/lib/i386-linux-gnu/libpcre.so.3″,host-name=»/lib/i386-linux-gnu/libpcre.so.3″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libthai.so.0″,target-name=»/usr/lib/i386-linux-gnu/libthai.so.0″,host-name=»/usr/lib/i386-linux-gnu/libthai.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libpixman-1.so.0″,target-name=»/usr/lib/i386-linux-gnu/libpixman-1.so.0″,host-name=»/usr/lib/i386-linux-gnu/libpixman-1.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libfreetype.so.6″,target-name=»/usr/lib/i386-linux-gnu/libfreetype.so.6″,host-name=»/usr/lib/i386-linux-gnu/libfreetype.so.6″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libpng12.so.0″,target-name=»/lib/i386-linux-gnu/libpng12.so.0″,host-name=»/lib/i386-linux-gnu/libpng12.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libxcb-shm.so.0″,target-name=»/usr/lib/i386-linux-gnu/libxcb-shm.so.0″,host-name=»/usr/lib/i386-linux-gnu/libxcb-shm.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libxcb-render.so.0″,target-name=»/usr/lib/i386-linux-gnu/libxcb-render.so.0″,host-name=»/usr/lib/i386-linux-gnu/libxcb-render.so.0″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libz.so.1″,target-name=»/lib/i386-linux-gnu/libz.so.1″,host-name=»/lib/i386-linux-gnu/libz.so.1″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/librt.so.1″,target-name=»/lib/i386-linux-gnu/librt.so.1″,host-name=»/lib/i386-linux-gnu/librt.so.1″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libselinux.so.1″,target-name=»/lib/i386-linux-gnu/libselinux.so.1″,host-name=»/lib/i386-linux-gnu/libselinux.so.1″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libresolv.so.2″,target-name=»/lib/i386-linux-gnu/libresolv.so.2″,host-name=»/lib/i386-linux-gnu/libresolv.so.2″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libexpat.so.1″,target-name=»/lib/i386-linux-gnu/libexpat.so.1″,host-name=»/lib/i386-linux-gnu/libexpat.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXau.so.6″,target-name=»/usr/lib/i386-linux-gnu/libXau.so.6″,host-name=»/usr/lib/i386-linux-gnu/libXau.so.6″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libXdmcp.so.6″,target-name=»/usr/lib/i386-linux-gnu/libXdmcp.so.6″,host-name=»/usr/lib/i386-linux-gnu/libXdmcp.so.6″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libharfbuzz.so.0″,target-name=»/usr/lib/i386-linux-gnu/libharfbuzz.so.0″,host-name=»/usr/lib/i386-linux-gnu/libharfbuzz.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libdatrie.so.1″,target-name=»/usr/lib/i386-linux-gnu/libdatrie.so.1″,host-name=»/usr/lib/i386-linux-gnu/libdatrie.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libgraphite2.so.3″,target-name=»/usr/lib/i386-linux-gnu/libgraphite2.so.3″,host-name=»/usr/lib/i386-linux-gnu/libgraphite2.so.3″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gconv/UTF-16.so»,target-name=»/usr/lib/i386-linux-gnu/gconv/UTF-16.so»,host-name=»/usr/lib/i386-linux-gnu/gconv/UTF-16.so»,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/liboverlay-scrollbar.so»,target-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/liboverlay-scrollbar.so»,host-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/liboverlay-scrollbar.so»,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libunity-gtk-module.so»,target-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libunity-gtk-module.so»,host-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libunity-gtk-module.so»,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libunity-gtk2-parser.so.0″,target-name=»/usr/lib/i386-linux-gnu/libunity-gtk2-parser.so.0″,host-name=»/usr/lib/i386-linux-gnu/libunity-gtk2-parser.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/engines/libmurrine.so»,target-name=»/usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/engines/libmurrine.so»,host-name=»/usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/engines/libmurrine.so»,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libcanberra-gtk-module.so»,target-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libcanberra-gtk-module.so»,host-name=»/usr/lib/i386-linux-gnu/gtk-2.0/modules/libcanberra-gtk-module.so»,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libcanberra-gtk.so.0″,target-name=»/usr/lib/i386-linux-gnu/libcanberra-gtk.so.0″,host-name=»/usr/lib/i386-linux-gnu/libcanberra-gtk.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libcanberra.so.0″,target-name=»/usr/lib/i386-linux-gnu/libcanberra.so.0″,host-name=»/usr/lib/i386-linux-gnu/libcanberra.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libvorbisfile.so.3″,target-name=»/usr/lib/i386-linux-gnu/libvorbisfile.so.3″,host-name=»/usr/lib/i386-linux-gnu/libvorbisfile.so.3″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libtdb.so.1″,target-name=»/usr/lib/i386-linux-gnu/libtdb.so.1″,host-name=»/usr/lib/i386-linux-gnu/libtdb.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libltdl.so.7″,target-name=»/usr/lib/i386-linux-gnu/libltdl.so.7″,host-name=»/usr/lib/i386-linux-gnu/libltdl.so.7″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libvorbis.so.0″,target-name=»/usr/lib/i386-linux-gnu/libvorbis.so.0″,host-name=»/usr/lib/i386-linux-gnu/libvorbis.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libogg.so.0″,target-name=»/usr/lib/i386-linux-gnu/libogg.so.0″,host-name=»/usr/lib/i386-linux-gnu/libogg.so.0″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libproxy.so.1″,target-name=»/usr/lib/i386-linux-gnu/libproxy.so.1″,host-name=»/usr/lib/i386-linux-gnu/libproxy.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/libstdc++.so.6″,target-name=»/usr/lib/i386-linux-gnu/libstdc++.so.6″,host-name=»/usr/lib/i386-linux-gnu/libstdc++.so.6″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libgcc_s.so.1″,target-name=»/lib/i386-linux-gnu/libgcc_s.so.1″,host-name=»/lib/i386-linux-gnu/libgcc_s.so.1″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so»,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgvfsdbus.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgvfsdbus.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgvfsdbus.so»,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gvfs/libgvfscommon.so»,target-name=»/usr/lib/i386-linux-gnu/gvfs/libgvfscommon.so»,host-name=»/usr/lib/i386-linux-gnu/gvfs/libgvfscommon.so»,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libudev.so.1″,target-name=»/lib/i386-linux-gnu/libudev.so.1″,host-name=»/lib/i386-linux-gnu/libudev.so.1″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libcgmanager.so.0″,target-name=»/lib/i386-linux-gnu/libcgmanager.so.0″,host-name=»/lib/i386-linux-gnu/libcgmanager.so.0″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libnih.so.1″,target-name=»/lib/i386-linux-gnu/libnih.so.1″,host-name=»/lib/i386-linux-gnu/libnih.so.1″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libnih-dbus.so.1″,target-name=»/lib/i386-linux-gnu/libnih-dbus.so.1″,host-name=»/lib/i386-linux-gnu/libnih-dbus.so.1″,thread-group=»i1″
=library-unloaded,id=»/lib/i386-linux-gnu/libdbus-1.so.3″,target-name=»/lib/i386-linux-gnu/libdbus-1.so.3″,host-name=»/lib/i386-linux-gnu/libdbus-1.so.3″,thread-group=»i1″
=library-unloaded,id=»/usr/lib/i386-linux-gnu/gio/modules/libgioremote-volume-monitor.so»,target-name=»/usr/lib/i386-linux-gnu/gio/modules/libgioremote-volume-monitor.so»,host-name=»/usr/lib/i386-linux-gnu/gio/modules/libgioremote-volume-monitor.so»,thread-group=»i1″
^done
(gdb)



0



155 / 107 / 36

Регистрация: 27.06.2018

Сообщений: 249

21.08.2018, 14:53

6

Толку от них ноль. Построчная отладка нужна в самой среде, там и смотреть где ложится. Но без кода я пас )



0



furunkul

0 / 0 / 1

Регистрация: 19.04.2018

Сообщений: 7

21.08.2018, 16:07

 [ТС]

7

При установке брекпоинта на «Application.Initialize» отладчик даже туда не попадает:

Pascal
1
2
3
4
5
6
7
8
9
10
11
begin
  Application.Initialize;
  if ParamStr(1) <> '' then
  GRT:=ParamStr(1)
  else
  GRT:='0';(lin)
  Application.Title:='Text_Name';
  Application.CreateForm(TfmMain, fmMain);
  Application.CreateForm(TfmErr, fmErr);
  Application.Run;
end.



0



155 / 107 / 36

Регистрация: 27.06.2018

Сообщений: 249

21.08.2018, 16:40

8

Наугад могу только посоветовать изменить все параметры проекта дефолтными для Linux. Быстрее всего это сделать, если создать новый проект (в Linux, естественно) и скопировать код в него. Также можно проверить специфические диррективы компилятора, особенно если есть многопоточность. Также проверить наличие/отсутствие юнитов типа cthreads или cmem
Возможно, это исправит ошибку.



0



furunkul

0 / 0 / 1

Регистрация: 19.04.2018

Сообщений: 7

22.08.2018, 13:56

 [ТС]

9

Human_foot, при инициализации модуля «Interfaces» валится:

Pascal
1
2
initialization
  CreateWidgetset(TGtk2WidgetSet);



0



furunkul

0 / 0 / 1

Регистрация: 19.04.2018

Сообщений: 7

23.08.2018, 13:59

 [ТС]

10

Лучший ответ Сообщение было отмечено Joey как решение

Решение

Human_foot, Благодарю за помощь помог с решением проблемы!
Как советовалось в статье «Модули, необходимые для мультипоточных приложений» http://wiki.freepascal.org/Mul… utorial/ru
В начале «основной_модуль*.lpr» сразу после uses нужно было прописать:

Pascal
1
2
3
4
5
uses
{$ifdef unix}
  cthreads,
  cmem, // the c memory manager is on some systems much faster for multi-threading
{$endif}

после этого, проект стартанул



0



Для операционных систем на базе Linux написано огромное количество программ. Несмотря на это, иногда возникает необходимость производить запуск Windows программ под Linux. В основном, это касается игр и некоторых специализированных программ, аналоги которых в Linux отсутствуют. Кроме того, некоторые пользователи, переходя с Windows на Linux, уже привыкли к определенному набору программного обеспечения и желают его использовать в дальнейшем. В этом случае предпочтительнее все же найти аналогичные программы для Linux и освоить их, поскольку в родной операционной системе программы работают обычно лучше и стабильнее. Поэтому рекомендуем запускать Windows программы под Linux только после того, как вы убедитесь, что аналогов нужных программ под Linux нет, или они вам не подходят.

Запустить программу, написанную для Windows в Linux, можно несколькими способами: с использованием Wine и продуктов на его основе, с помощью виртуальных машин и эмуляторов: VirtualBox, VMware, Parallels Workstation, QEMU. Теоретически еще есть возможность портирования программ с Windows на Linux при наличии исходного кода и навыков программирования, но этот вариант мы здесь рассматривать не будем.

Программы под Wine обычно работают быстрее, чем в виртуальных машинах. Это особенно актуально для современных 3D игр. Wine не требует установки операционной системы и позволяет быстро менять версию системы, библиотек и другие параметры. Запускать программы можно непосредственно в среде Linux. С другой стороны, для настройки Wine все равно придется потратить некоторое время и возможно неоднократно при запуске отдельных программ и игр. В виртуальных машинах запускаются оригинальные версии Windows и прочие операционные системы, которые нужно предварительно установить и настроить. Системе выделяются определенные ресурсы компьютера, эмулируется стандартное оборудование. Перед выполнением программы нужно предварительно запустить эмулятор и загрузить операционную систему, на что требуется дополнительное время. Следует отметить, что некоторые программы имеют защиту от запуска под виртуальными машинами.

Установка Wine

Мы рассмотрим установку Wine на Ubuntu и систем на ее базе (Linux Mint, Kubuntu и т.п.).Пользователи других операционных систем могут скачать Wine и прочитать инструкции по установке здесь: http://www.winehq.org/download/

Открываем терминал комбинацией клавиш Ctrl+Alt+T. Добавляем репозиторий с Wine командой:

sudo add-apt-repository ppa:ubuntu-wine/ppa

Вводим пароль администратора. В процессе установки нужно будет нажать клавишу «Enter».

Если вы будете производить апгрейд системы, например, обновлять Ubuntu 13.10 до Ubuntu 14.04, то придется повторить вышеуказанную операцию после апгрейда, поскольку в процессе обновления нестандартные репозитории удаляются.

После добавления репозитория обновляем информацию о пакетах:

sudo apt-get update

Теперь можно установить Wine командой:

sudo apt-get install wine1.7

Установится последняя, на момент написания статьи, тестовая версия программы. Для установки старой, но более стабильной версии нужно выполнить команду:

sudo apt-get install wine1.6

Возможно, когда вы будете читать эту статью, уже появятся более новые версии, тогда вместо wine1.6 или wine1.7, надо будет устанавливать wine1.8 или wine1.9. Номер текущей версии указан на официальном сайте Wine: http://www.winehq.org

Хотя можно и не указывать версию при установке, версия Wine в этом случае будет зависеть от версии операционной системы:

sudo apt-get install wine

Проверить, какая версия установилась, можно с помощью команды:

wine —version

Настройка Wine

После установки необходимо настроить программу командой:

winecfg

Рис. 1. Окно настроек winecfg

Это команда создаст в домашней директории пользователя каталог .wine, где будут находиться системные файлы с настройками — аналог реестра Windows и drive_c — каталог для приложений Windows. С помощью winecfg можно выбрать версии Windows по умолчанию и для отдельных приложений, версии библиотек, настроить графику и звук, интеграцию с рабочим столом, выбрать диски, с которых разрешен запуск Windows-программ.

А редактировать реестр можно с помощью привычной команды:

regedit

Рис. 2. Окно regedit под Wine

После такой первоначальной настройки, уже можно будет устанавливать и запускать программы с помощью Wine. Но многие программы работать не смогут, поскольку требуют определенных библиотек, шрифтов и т.д., которые придется установить отдельно. Для этого воспользуемся программой winetricks, которая входит в стандартный пакет программ Wine. Winetricks кроме шрифтов и библиотек позволяет также устанавливать популярные программы и игры и производить настройки Wine.

Попробуем установить Internet Explorer 7 с помощью winetricks, для этого наберем в терминале:

winetricks ie7

Подождем некоторое время, пока скачаются необходимые файлы и запустится программа-установщик, нажмем кнопку «Next» и подождем окончания установки. Для последующего запуска Internet Explorer нужно будет выполнить команду:

wine ‘C:Program FilesInternet Exploreriexplore’

Но лучше запускать программы из родного каталога. Переходим в каталог (если в имени файла есть пробел, то перед ним нужно ставить обратный слеш «»):

cd ~/.wine/drive_c/Program Files/Internet Explorer/

И запускаем программу:

wine iexplore.exe

Чтобы не набирать эти команды каждый раз, можно создать простейший скрипт. Переходим в домашний каталог:

cd

Создаем файл ie.sh с помощью редактора nano:

nano ie.sh

Вставляем в файл строчки:

cd ~/.wine/drive_c/Program Files/Internet Explorer/ wine iexplore.exe

Сохраняем файл — Ctrl+O и выходим из редактора — Ctrl+X. Делаем файл исполняемым:

chmod +x ie.sh

Теперь для запуска ie достаточно набрать:

~/ie.sh

А можно скопировать файл на рабочий стол и запускать его с помощью мышки:

cp ie.sh ~/Desktop/

Установка программы с CD или DVD может быть выполнена с помощью такой команды:

wine start ‘D:setup.exe’

Аналогичным образом можно установить другие программы и библиотеки. Также можно воспользоваться графическим интерфейсом программы, набрав winetricks без параметров. Потом выбрать «Select the default wineprefix».

Рис. 3. Основное окно winetricks

Далее выбираем действие, которое будем производить, например, установку библиотеки (Install a Windows DLL or component):

Рис. 4. Выбор действия winetricks

И отмечаем галочками библиотеки, которые необходимо установить. Можно сделать то же самое и посредством командой строки, например:

winetricks d3dx9 dotnet20

Таким образом, мы установим сразу два компонента: d3dx9 и dotnet20. Чтобы в программах корректно отображались популярные шрифты, установим их:

winetricks allfonts

С библиотеками немного сложнее. Разные программы могут потребовать отдельных настроек, определенных версий Windows и библиотек. Для этого можно создать несколько конфигураций Wine, указывая каталог с настройками с помощью переменной окружения WINEPREFIX. По умолчанию WINEPREFIX=~/.wine Для создания новых настроек в каталоге ~/.wine2 наберем:

WINEPREFIX=~/.wine2 winecfg

Таким образом, можно создать любое количество конфигураций. Для настройки и установки шрифтов и библиотек наберем:

WINEPREFIX=~/.wine2 winetricks

Для запуска установленной программы:

WINEPREFIX=~/.wine2 ‘C:/путь/к/программе/программа.exe’

Завершить выполнение программы можно с помощью команды:

killall -9 программа.exe

А чтобы завершить работу всех программ, запущенных под Wine, нужно набрать:

wineserver -k

Для удаления настроек и всех программ в префиксе ~/.wine2 нужно просто удалить каталог:

rm -r ~/.wine2

Точно также можно удалить и основной каталог Wine:

rm -r ~/.wine

Будьте внимательны, при этом удалятся также все приложения Windows, которые установлены в этот каталог!

winefile — запуск файлового менеджера, с помощью которого можно запускать Windows-приложения, копировать и удалять файлы и т.д. Узнать, какие приложения и игры запускаются под Wine и как производить настройки под конкретные приложения можно на сайте: http://appdb.winehq.org/ Сайт англоязычный. Для поиска приложений нужно выбрать в меню «Browse Apps» и ввести в поле «Name» название программы. Версии программ, которые запускаются и работают без ошибок или с несущественными проблемами, имеют рейтинг «Platinum» или «Gold». Если программа вообще не работает, то ей присваивается рейтинг «Garbage».

PlayOnLinux

PlayOnLinux — это программа, которая значительно упрощает установку и настройку Windows-приложений для запуска под Wine. Она автоматически скачивает из интернета и устанавливает все необходимые компоненты для запуска конкретных программ, а также и сами программы, если они распространяются бесплатно через интернет. В противном случае, понадобится установочный диск с программой. Устанавливаем программу любым способом, например в Ubuntu командой:

sudo apt-get install playonlinux

и запускаем ее:

playonlinux

Пользоваться программой предельно просто. Нажимаем кнопку «Установка».

Рис. 5. Основное окно PlayOnLinux

Выбираем программу, которую необходимо установить. Если не нашли нужную программу в окне выбора, можно попробовать нажать «Установить программу, отсутствующий в списке» внизу окна.

Рис. 6. Окно выбора программы PlayOnLinux

Останется несколько раз нажать кнопку «Далее», а в некоторых случаях выбрать конфигурацию программы. После установки ярлыки программ появятся в основном окне PlayOnLinux, откуда их можно будет запустить двойным кликом, либо нажатием на кнопку «Запуск». Также можно будет создать ярлыки программ Windows на рабочем столе с помощью кнопки «Ярлык».

Рис. 7. Основное окно PlayOnLinux с установленной Windows-программой FireFox

Прочие программы на базе Wine

Существуют также платные программные продукты на базе Wine. CrossOver позволяет запускать под Linux различные версии Microsoft Office, Adobe Photoshop и множество других программ и игр. WINE@Etersoft нацелен в основном на поддержку популярных программ для бизнеса: 1С:Предприятие, КонсультантПлюс, ГАРАНТ и прочих. Ознакомиться с этими программами можно на официальных сайтах: http://www.codeweavers.com/products/ http://etersoft.ru/products/wine

VirtualBox

VirtualBox — одна из самых популярных программ для виртуализации, которая позволяет запускать различные операционные системы одновременно на одном компьютере. Установку VirtualBox в Ubuntu можно выполнить стандартным способом, набрав в терминале:

sudo apt-get update

sudo apt-get install dkms

sudo apt-get install virtualbox

dkms осуществляет поддержку динамических модулей ядра (vboxdrv, vboxnetflt, vboxnetadp), которые необходимы для работы VirtualBox. В других версиях Linux для установки используются соответствующие команды (yum, urpmi и т. д.), также можно использовать установочный файл или собрать программу из исходного кода. Подробнее смотрите в статье «Как устанавливать программы в Linux». 

Скачать VirtualBox для различных операционных систем можно здесь: https://www.virtualbox.org/wiki/Downloads. После окончания установки добавим пользователя в группу vboxusers, вместо username необходимо указать корректное имя пользователя, под которым будет работать VirtualBox:

sudo usermod -a -G vboxusers username

Теперь можно запустить программу через меню, либо набрав в терминале:

virtualbox

Рис. 8. Менеджер VirtualBox с уже установленными операционными системами

Теперь поставим операционную систему, для этого нужно иметь установочный диск или его образ. Нажмем кнопку «Создать», запустится мастер создания новой виртуальной машины:

Рис. 9. Мастер создания новой виртуальной машины

Нажмем кнопку «Вперед», введем имя виртуальной машины, например «Windows XP», а ниже выберем соответствующие тип и версию операционной системы:

Рис. 10. Выбор версии операционной системы

Мы выбрали Windows XP, поскольку она менее требовательна к ресурсам компьютера, занимает меньше места, быстрее загружается. Но поддержка этой системы уже официально прекращена. Естественно, можно установить и другие версии Windows, которые поддерживает VirtualBox: Windows Server 2003, Windows Vista, Windows Server 2008, Windows 7, Windows 8, Windows Server 2012. Далее выбираем объем ОЗУ, которое будет выделено виртуальной машине:

Рис. 11. Выбор объема памяти

Выбор зависит от версии ОС, объема физической памяти, планируемых задач, количества запускаемых одновременно гостевых систем. В зависимости от версии операционной системы, VirtualBox будет предлагать различные параметры по умолчанию, но они, как правило, минимальные, желательно их увеличить. В любом случае, для нормальной работы современных операционных систем необходимо не менее 1-2 Гигабайт ОЗУ (для Windows XP достаточно 512 Мбайт) и еще необходимо оставить память основной хост-системе. Далее создаем новый виртуальный жесткий диск или выбираем уже созданные ранее.

Рис. 12. Виртуальный жесткий диск

На следующем экране выбираем тип диска, по умолчанию стандартный VDI.

Рис. 13. Выбор типа диска

Далее указываем, что наш диск будет динамический, это позволяет сэкономить дисковое пространство физического носителя.

Рис. 14. Выбор атрибутов виртуального диска

Указываем размер диска, расположение оставляем по умолчанию (диск будет располагаться в папке ~/VirtualBox VMs/Имя системы.

Рис. 15. Выбор расположения и размера виртуального диска

Осталось нажать кнопку «Создать».

Рис. 16. Последний этап создания новой виртуальной машины

Виртуальная машины создана. Выбираем ее в менеджере VirtualBox и нажимаем кнопку «Свойства».

Рис. 17. Выбор системы

Тут можно подробно настроить созданную виртуальною машину. В первую очередь, необходимо указать диск, с которого будем ставить систему. Для этого нажимаем слева «Носители», выбираем пустой диск, справа кликаем на иконку диска и указываем образ дистрибутива, либо ставим галочку «Живой CD/DVD» и вставляем физический диск.

Рис. 18. Выбор установочного диска

Далее переходим на вкладку «Система → Материнская плата», проверяем порядок загрузки, CD/DVD-ROM должен быть выше жесткого диска. Если это не так, изменяем порядок загрузки стрелками.

Рис. 19. Настройки системы

Если важна скорость работы с графикой, переходим на вкладку «Дисплей», увеличиваем объем видеопамяти и включаем ускорение.

Рис. 20. Настройка параметров дисплея

Переходим обратно в VirtualBox Менеджер и нажимаем кнопку «Старт». Далее производим установку системы, как обычно. После установки гостевой системы, загружаем ее и в меню «Устройства» выбираем «Установить дополнения гостевой ОС». Вместо этого можно нажать комбинацию клавиш правый Ctrl+D. После установки дополнений система будет готова к работе.

Рис. 21. Установленная и готовая к работе система Windows XP в VirtualBox

Загрузка гостевой операционной системы после запуска VirtualBox осуществляется кнопкой «Старт». Переключение указателя мышки между основной и гостевой системой осуществляется автоматически, но можно переключить принудительно с помощью кнопки правый Ctrl (Host key — можно изменить в настройках) и правый Ctrl+I. Эта же кнопка в сочетании с различными клавишами служит для выполнения ряда функций:

Host key+F — переключение в полноэкранный режим и обратно.

Host key+Del — заменяет комбинацию Ctrl+Alt+Del.

Host key+I — отключить интеграцию мышки.

Host key+С — переключение в режим масштабирования, в котором можно задать произвольный размер окна, возврат в стандартный режим происходит с помощью той же комбинации клавиш.

Host key+D — установка дополнений гостевой операционной системы.

Host key+T — сделать снимок, сохранить состояние ОС. Восстановить систему из сохраненного состояния можно будет в основном окне менеджера VirtualBox, нажав на кнопку «Снимки». Очень удобная функция для борьбы с вирусами, тестирования и отладки программ, которые могут повредить систему. Всегда можно сделать откат системы в стабильное состояние.

Host key+S — открыть окно настроек.

Host key+R — перезагрузить систему.

Host key+Q — закрыть виртуальную машину (выйти из системы).

Понравилась статья? Поделить с друзьями:
  • Понизить яркость экрана windows 10 программа
  • Портирование драйверов с windows на linux
  • Понизить частоту процессора ноутбука windows 10
  • Портирование драйверов с windows 10 на windows 7
  • Понизить уровень безопасности windows server 2012