|
1 <stránka |
|
2 xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana" |
|
3 xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro"> |
|
4 |
|
5 <nadpis>Using custom version of SQLite (LD_PRELOAD)</nadpis> |
|
6 <perex>switch to a newer or modified version of library using a little hack</perex> |
|
7 <m:pořadí-příkladu>03600</m:pořadí-příkladu> |
|
8 |
|
9 <text xmlns="http://www.w3.org/1999/xhtml"> |
|
10 |
|
11 <p> |
|
12 One of reasons why we prefer shared libraries (<code>.so</code>) rather than static linking, |
|
13 is that shared libraries are much more hacker-friendly and allow the user switching to a newer or modified library without recompiling the program. |
|
14 </p> |
|
15 |
|
16 <p> |
|
17 By default, <code>relpipe-tr-sql</code> links to the SQLite library available in our distribution (e.g. 3.22). |
|
18 As we can check: |
|
19 </p> |
|
20 |
|
21 <m:pre jazyk="text"><![CDATA[$ ldd $(which relpipe-tr-sql) | grep sqlite |
|
22 libsqlite3.so.0 => /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 (0x00007f4c73888000)]]></m:pre> |
|
23 |
|
24 <p> |
|
25 But what if we want to use some new features like <a href="https://www.sqlite.org/windowfunctions.html">window functions</a> that are available in later (3.25) library versions? |
|
26 Or what if we want to add our own custom modifications to this library? |
|
27 Do we have to recompile the <m:name/> tools? |
|
28 </p> |
|
29 |
|
30 <p> |
|
31 No, we can just plug the new/modified library in and use it instead of the distribution one. |
|
32 </p> |
|
33 |
|
34 <h2>Download and compile SQLite library</h2> |
|
35 |
|
36 <p> |
|
37 The build process of SQLite should be straightforward: |
|
38 </p> |
|
39 |
|
40 <m:pre jazyk="bash"><![CDATA[ |
|
41 # Switch to the user for such experiments (optional but recommended): |
|
42 su - hacker |
|
43 |
|
44 # Create directories, download and extract sources: |
|
45 mkdir -p ~/src/sqlite |
|
46 cd ~/src/sqlite |
|
47 wget https://www.sqlite.org/2019/sqlite-autoconf-3300100.tar.gz |
|
48 tar xvzf sqlite-autoconf-3300100.tar.gz |
|
49 cd sqlite-autoconf-3300100/ |
|
50 |
|
51 # Optional: do some changes to the source code |
|
52 |
|
53 # Build SQLite: |
|
54 ./configure |
|
55 make |
|
56 |
|
57 # Test it: |
|
58 echo "SELECT 'hello world'" | ./sqlite3 |
|
59 ]]></m:pre> |
|
60 |
|
61 <p> |
|
62 The desired shared libraries are located in the <code>.libs</code> directory. |
|
63 </p> |
|
64 |
|
65 <h2>Use this library in the <m:name/> tools</h2> |
|
66 |
|
67 <p> |
|
68 We have already build/installed <code>relpipe-tr-sql</code> which is linked to the SQLite library available in our distribution. |
|
69 Then switching to a custom version of the library is very easy – we just need to set an environment variable. |
|
70 </p> |
|
71 |
|
72 <m:pre jazyk="bash"><![CDATA[export LD_PRELOAD=~/src/sqlite/sqlite-autoconf-3300100/.libs/libsqlite3.so.0]]></m:pre> |
|
73 |
|
74 <p>And then <code>relpipe-tr-sql</code> will use the newer library version as we can check:</p> |
|
75 |
|
76 <m:pre jazyk="text"><![CDATA[$ ldd $(which relpipe-tr-sql) | grep sqlite |
|
77 /home/hacker/src/sqlite/sqlite-autoconf-3300100/.libs/libsqlite3.so.0 (0x00007f9979578000)]]></m:pre> |
|
78 |
|
79 <p>Now we can use new features like window functions:</p> |
|
80 |
|
81 <m:pre jazyk="bash"><![CDATA[relpipe-in-fstab \ |
|
82 | relpipe-tr-sql \ |
|
83 --relation "fs_types" " |
|
84 SELECT |
|
85 mount_point, |
|
86 type, |
|
87 count(*) OVER (PARTITION BY type) AS same_type_count |
|
88 FROM fstab" \ |
|
89 | relpipe-out-tabular]]></m:pre> |
|
90 |
|
91 <p>And get result like this one:</p> |
|
92 <m:pre jazyk="text"><![CDATA[fstab: |
|
93 ╭──────────────────────┬───────────────┬──────────────────────────╮ |
|
94 │ mount_point (string) │ type (string) │ same_type_count (string) │ |
|
95 ├──────────────────────┼───────────────┼──────────────────────────┤ |
|
96 │ /home │ btrfs │ 1 │ |
|
97 │ / │ ext4 │ 2 │ |
|
98 │ /mnt/data │ ext4 │ 2 │ |
|
99 │ /media/cdrom0 │ udf,iso9660 │ 1 │ |
|
100 │ /mnt/private │ xfs │ 1 │ |
|
101 ╰──────────────────────┴───────────────┴──────────────────────────╯ |
|
102 Record count: 5]]></m:pre> |
|
103 |
|
104 |
|
105 <p>That would not be possible with older versions of the SQLite library – as we can check by unsetting the <code>LD_PRELOAD</code> variable:</p> |
|
106 <m:pre jazyk="bash"><![CDATA[unset LD_PRELOAD]]></m:pre> |
|
107 <p>Which returns us to the previous state where SQLite from our distribution was used. And the calling the same SQL query leads to an error.</p> |
|
108 |
|
109 <p> |
|
110 The <code>LD_PRELOAD</code> hack can be used with any other software – it is not specific to <m:name/>. |
|
111 Another example is the <a href="https://mouse.globalcode.info/v_0/spacenav-hack.xhtml">Spacenav Hack</a> which bridges/translates two APIs of a library. |
|
112 </p> |
|
113 |
|
114 |
|
115 <h2>ABI compatibility</h2> |
|
116 |
|
117 <p> |
|
118 The prerequisite for such easy library swapping is the compatibility of the ABI (application binary interface). |
|
119 It means that we can change the library internals (the SQL language features in this case) but we must retain the compiled representation of the C functions compatible |
|
120 so the both parts (the library and the program) will still fit together. We can not e.g. remove a C function. |
|
121 And we should also not do any incompatible changes on the semantic level (although it could still link together, it would lead to unwanted results). |
|
122 </p> |
|
123 |
|
124 <p> |
|
125 In case of libraries that follow the <a href="https://semver.org/">Semantic versioning</a> (as required by <a href="https://sane-software.globalcode.info/">Sane software manifesto</a>) for their ABI, |
|
126 it is easy to say which versions are compatible and which would require recompiling the program or even changing its source code. |
|
127 If the <em>patch</em> or <em>minor</em> version numbers were changed, the libraries could be swapped this way. |
|
128 If the <em>major</em> version was changed, it would be probably necessary to also modify the software that uses this library. |
|
129 </p> |
|
130 |
|
131 </text> |
|
132 |
|
133 </stránka> |