Linux kernel quiz: Why is this program so slow and takes around 50ms to run?
What line do you have to add to make it run in ~3ms instead without interfering with what this program does?
user@debian12:~/test$ cat > slow.c
#include <pthread.h>
#include <unistd.h>
#include <err.h>
#include <sys/socket.h>
static void open_sockets(void) {
for (int i=0; i<256; i++) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
err(1, "socket");
}
}
static void *thread_fn(void *dummy) {
open_sockets();
return NULL;
}
int main(void) {
pthread_t thread;
if (pthread_create(&thread, NULL, thread_fn, NULL))
errx(1, "pthread_create");
open_sockets();
if (pthread_join(thread, NULL))
errx(1, "pthread_join");
return 0;
}
user@debian12:~/test$ gcc -O2 -o slow slow.c -Wall
user@debian12:~/test$ time ./slow
real 0m0.041s
user 0m0.003s
sys 0m0.000s
user@debian12:~/test$ time ./slow
real 0m0.053s
user 0m0.003s
sys 0m0.000s
user@debian12:~/test$
anyone know how to get around this compilation fail on Solaris?
In file included from pkg_libecc_rand.c:6:
/usr/share/src/fractal/build/progress/pkg-2.2.1/compat/bsd_compat.h:188:3: error: #error "Your system has neither funopen nor fopencookie, cannot continue"
188 | # error "Your system has neither funopen nor fopencookie, cannot continue"
| ^~~~~
/usr/share/src/fractal/build/progress/pkg-2.2.1/compat/bsd_compat.h:190:1: error: unknown type name 'FILE'
190 | FILE * funopen(const void *cookie, int (*readfn)(void *, char *, int),
| ^~~~
/usr/share/src/fractal/build/progress/pkg-2.2.1/compat/bsd_compat.h:97:1: note: 'FILE' is defined in header '<stdio.h>'; did you forget to '#include <stdio.h>'?
96 | #include "humanize_number.h"
+++ |+#include <stdio.h>
97 | #endif
/usr/share/src/fractal/build/progress/pkg-2.2.1/compat/bsd_compat.h:203:4: error: #error "Don't know how to replace getprogname()"
203 | # error "Don't know how to replace getprogname()"
| ^~~~~
Retro C++ quiz #33
#include <iostream>
int main(){
char arr[] = "junk";
char c{'a'};
std::cout << &c; // What will this likely output?
}
Without checking:
A. some valid address e.g. 0x7ffc6a86d386
B. a
C. 97
D. ¯\_(ツ)_/¯ Undefined behavior
Social media tip: If you look for hashtag #include, you get some fun toots about C/C++
@brouhaha it looks like, for this specific case, Address Sanitizer finds an issue pretty quickly.
```
term% cat foo.cc
#include <iostream>
#include <vector>
int
main()
{
std::vector<int> v{0, 1, 2, 3, 4};
for (const auto elem: v)
std::cout << "elem= " << elem << std::endl;
for (auto it = v.cbegin(); it != v.cend(); ++it) {
if (*it % 2)
v.emplace_back(1);
}
for (const auto elem: v)
std::cout << "elem= " << elem << std::endl;
return 0;
}
term% clang++ -std=c++23 -fsanitize=address,undefined -Wall -Wextra -o foo foo.cc
term% ./foo
foo(22239,0x20c2e5f00) malloc: nano zone abandoned due to inability to reserve vm space.
elem= 0
elem= 1
elem= 2
elem= 3
elem= 4
=================================================================
==22239==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000001c98 at pc 0x000102264f94 bp 0x00016db9a650 sp 0x00016db9a648
READ of size 4 at 0x603000001c98 thread T0
#0 0x000102264f90 in main+0x6b0 (foo:arm64+0x100000f90)
[snip]
#9 0x000102266308 in int& std::__1::vector<int, std::__1::allocator<int>>::emplace_back<int>(int&&)+0x224 (foo:arm64+0x100002308)
#10 0x000102265028 in main+0x748 (foo:arm64+0x100001028)
#11 0x00019de36b94 in start+0x17b8 (dyld:arm64e+0xfffffffffff3ab94)
previously allocated by thread T0 here:
[snip]
#8 0x000102266928 in std::__1::vector<int, std::__1::allocator<int>>::vector[abi:ne190102](std::initializer_list<int>)+0x328 (foo:arm64+0x100002928)
#9 0x0001022655a4 in std::__1::vector<int, std::__1::allocator<int>>::vector[abi:ne190102](std::initializer_list<int>)+0x60 (foo:arm64+0x1000015a4)
#10 0x000102264b54 in main+0x274 (foo:arm64+0x100000b54)
#11 0x00019de36b94 in start+0x17b8 (dyld:arm64e+0xfffffffffff3ab94)
SUMMARY: AddressSanitizer: heap-use-after-free (foo:arm64+0x100000f90) in main+0x6b0
[snip]
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==22239==ABORTING
term% clang++ --version
Apple clang version 17.0.0 (clang-1700.0.13.5)
Target: arm64-apple-darwin24.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
term%
```
And we're done! Switching to lld
has brought the build time down from 3.75 hours to about 1.75. I pretty much blinked and the linking was done!
For anyone trying to compile #MAME 0.279 from source: There are two bugs in the upstream release that prevent MAME from compiling. It's just two files with some #include
lines in the wrong order. The commits to fix them (not by me) are here:
https://github.com/mamedev/mame/commit/95f7d841988286de21c03f48bfcce45b1aed7bc6
https://github.com/mamedev/mame/commit/95f7d841988286de21c03f48bfcce45b1aed7bc6
I've included them in the #HaikuOS port, which should be available in HaikuDepot in the next few days.
So here's MAME on Haiku, running an emulated #Psion Series 3a.
@deshipu @david_colquhoun I would agree, if:
- There was a chance this would work (there isn’t)
- there wasn’t going to be massive collateral damage (there will be)
- there was a chance we’d learn something (we won’t)
#include<meme: but it might work for us >
@jwildeboer
Compile and use this ;)
#include <stdio.h>
#include <stdlib.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/err.h>
void print_sha256_fingerprint(X509 *cert) {
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int n = 0;
if (!X509_digest(cert, EVP_sha256(), md, &n)) {
fprintf(stderr, "Error calculating SHA256 digest\n");
return;
}
// Print as lowercase hex string without colons
for (unsigned int i = 0; i < n; i++) {
printf("%02x", md[i]);
}
printf("\n");
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <certificate.pem>\n", argv[0]);
return EXIT_FAILURE;
}
const char *cert_path = argv[1];
FILE *fp = fopen(cert_path, "r");
if (!fp) {
perror("Error opening certificate file");
return EXIT_FAILURE;
}
OpenSSL_add_all_algorithms();
ERR_load_BIO_strings();
ERR_load_crypto_strings();
X509 *cert = PEM_read_X509(fp, NULL, NULL, NULL);
fclose(fp);
if (!cert) {
fprintf(stderr, "Error reading certificate from file\n");
ERR_print_errors_fp(stderr);
return EXIT_FAILURE;
}
print_sha256_fingerprint(cert);
X509_free(cert);
return EXIT_SUCCESS;
}
This was fun - missing.c:
#include <stdio.h>
#include <stdlib.h>
void die(int err, char *msg) {
err? fprintf(stderr, "%s\n", msg), exit(1): 0;
}
int main(int argc, char *argv[]) {
int n, answer = 1, val;
die(argc != 2 || (n = atoi(argv[1])) < 2, "Usage: missing n");
for (; n > 1; n--) {
die(scanf("%d", &val) != 1, "Error reading input");
answer ^= val ^ n;
}
printf("%d\n", answer);
}
mmsg
for #MaomaoWM ? The dev has added a new json feature which obviously builds on Linux. The last version before built no issue for me on FreeBSD but with the addition of libcjson
which I have installed it fails to build with this error:justine@justine@snac.smithies.me.uk-laptop ~/Git/mmsg main $ doas make installThe sources are here for
Password:
cc -O2 -pipe `pkg-config --cflags wayland-client -lcjson` -c mmsg.c -o mmsg.o
pkgconf: unknown option -- lcjson
In file included from mmsg.c:2:
./dwl-ipc-unstable-v2-protocol.h:8:10: fatal error: 'wayland-client.h' file not found
8 | #include "wayland-client.h"
| ^~~~~~~~~~~~~~~~~~
1 error generated.
*** Error code 1
Stop.
make: stopped in /home/justine/Git/mmsg
mmsg
@doctormo Is it "raw artisanal hand-written ninja" or "cmake-generated ninja"? For the latter:
$ rm compile_commands.json # just in case
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(test)
add_executable(test test.c)
$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -GNinja .
$ ninja
[2/2] Linking C executable test
$ iwyu-tool -p . test.c
/tmp/test.c should add these lines:
/tmp/test.c should remove these lines:
- #include <stddef.h> // lines 2-2
@doctormo I see. It's possible to "untie from the build system" using https://github.com/rizsotto/Bear:
$ cat test.c
#include <stdio.h>
#include <stddef.h>
int main() { printf("hello"); }
$ bear -- gcc test.c
$ iwyu-tool -p . test.c
test.c should add these lines:
test.c should remove these lines:
- #include <stddef.h> // lines 2-2
The full include-list for test.c:
#include <stdio.h> // for printf
@ranvel to be more specific, for a given folder PREFIX
, this is my ncurses config:
./configure --prefix="$PREFIX" --enable-widec
and this is my nano config:
./configure --prefix="$PREFIX" --disable-nls --enable-utf8 --enable-year2038 NCURSESW_CFLAGS="-I$PREFIX/include" NCURSESW_LIBS="-L$PREFIX/lib -lncursesw"
With ncurses 6.5 and nano 8.5, that leads to a bunch of linker failures for imports with "$NCURSES60" suffix... which comes from Apple's SDK. And if you look at nano src, you can find this:
/* Prefer wide ncurses over normal ncurses over curses. */
#if defined(HAVE_NCURSESW_NCURSES_H)
#include <ncursesw/ncurses.h>
#elif defined(HAVE_NCURSES_H)
#include <ncurses.h>
#else
#include <curses.h>
#endif
So unless you define HAVE_NCURSESW_NCURSES_H
, it will include the wrong header. And while HAVE_NCURSES_H
shows up in configure
, HAVE_NCURSESW_NCURSES_H
does not...
@littlefox Here is a C++ program that uses a forward_list to manage physical memory:
#include <iostream>
#include <forward_list>
#include <physicalMemory>
int main(){
physicalMemory = new managePhysicalMemory<forward_list>();
return 0;
}
When I do it:
#include <stdio.h>
long int factorial(int number) {
if(number >= 1)
return number*factorial(number-1);
else
return 1;
}
When #DollarGeneral does it: