<feed xmlns='http://www.w3.org/2005/Atom'>
<title>delta/haproxy.git/include/haproxy/bug.h, branch master</title>
<subtitle>github.com: haproxy/haproxy.git
</subtitle>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/'/>
<entry>
<title>DEBUG: crash using an invalid opcode on aarch64 instead of an invalid access</title>
<updated>2023-04-25T17:53:39+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2023-04-25T17:01:48+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=543e2544cabf9900af92d45658b122bc25011c3d'/>
<id>543e2544cabf9900af92d45658b122bc25011c3d</id>
<content type='text'>
On aarch64 there's also a guaranted invalid instruction, called UDF, and
which even supports an optional 16-bit immediate operand:

   https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/UDF--Permanently-Undefined-?lang=en

It's conveniently encoded as 4 zeroes (when the operand is zero). It's
unclear when support for it was added into GAS, if at all; even a
not-so-old 2.27 doesn't know about it. Let's byte-encode it.

Tested on an A72 and works as expected.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
On aarch64 there's also a guaranted invalid instruction, called UDF, and
which even supports an optional 16-bit immediate operand:

   https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/UDF--Permanently-Undefined-?lang=en

It's conveniently encoded as 4 zeroes (when the operand is zero). It's
unclear when support for it was added into GAS, if at all; even a
not-so-old 2.27 doesn't know about it. Let's byte-encode it.

Tested on an A72 and works as expected.
</pre>
</div>
</content>
</entry>
<entry>
<title>DEBUG: crash using an invalid opcode on x86/x86_64 instead of an invalid access</title>
<updated>2023-04-25T16:51:10+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2023-04-25T16:44:58+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=77787ec9bccaa6904dceb0dcce9bd8184cfdbece'/>
<id>77787ec9bccaa6904dceb0dcce9bd8184cfdbece</id>
<content type='text'>
BUG_ON() calls currently trigger a segfault. This is more convenient
than abort() as it doesn't rely on any function call nor signal handler
and never causes non-unwindable stacks when opening cores. But it adds
quite some confusion in bug reports which are rightfully tagged "segv"
and do not instantly allow to distinguish real segv (e.g. null derefs)
from code asserts.

Some CPU architectures offer various crashing methods. On x86 we have
INT3 (0xCC), which stops into the debugger, and UD0/UD1/UD2. INT3 looks
appealing but for whatever reason (maybe signal handling somewhere) it
loses the last call point in the stack, making backtraces unusable. UD2
has the merit of being only 2 bytes and causing an invalid instruction,
which almost never happens normally, so it's easily distinguishable.
Here it was defined as a macro so that the line number in the core
matches the one where the BUG_ON() macro is called, and the debugger
shows the last frame exactly at its calligg point.

E.g. when calling "debug dev bug":

Program terminated with signal SIGILL, Illegal instruction.
  #0  debug_parse_cli_bug (args=&lt;optimized out&gt;, payload=&lt;optimized out&gt;, appctx=&lt;optimized out&gt;, private=&lt;optimized out&gt;) at src/debug.c:408
  408             BUG_ON(one &gt; zero);
  [Current thread is 1 (Thread 0x7f7a660cc1c0 (LWP 14238))]
  (gdb) bt
  #0  debug_parse_cli_bug (args=&lt;optimized out&gt;, payload=&lt;optimized out&gt;, appctx=&lt;optimized out&gt;, private=&lt;optimized out&gt;) at src/debug.c:408
  #1  debug_parse_cli_bug (args=&lt;optimized out&gt;, payload=&lt;optimized out&gt;, appctx=&lt;optimized out&gt;, private=&lt;optimized out&gt;) at src/debug.c:402
  #2  0x000000000061a69f in cli_parse_request (appctx=appctx@entry=0x181c0160) at src/cli.c:832
  #3  0x000000000061af86 in cli_io_handler (appctx=0x181c0160) at src/cli.c:1035
  #4  0x00000000006ca2f2 in task_run_applet (t=0x181c0290, context=0x181c0160, state=&lt;optimized out&gt;) at src/applet.c:449
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
BUG_ON() calls currently trigger a segfault. This is more convenient
than abort() as it doesn't rely on any function call nor signal handler
and never causes non-unwindable stacks when opening cores. But it adds
quite some confusion in bug reports which are rightfully tagged "segv"
and do not instantly allow to distinguish real segv (e.g. null derefs)
from code asserts.

Some CPU architectures offer various crashing methods. On x86 we have
INT3 (0xCC), which stops into the debugger, and UD0/UD1/UD2. INT3 looks
appealing but for whatever reason (maybe signal handling somewhere) it
loses the last call point in the stack, making backtraces unusable. UD2
has the merit of being only 2 bytes and causing an invalid instruction,
which almost never happens normally, so it's easily distinguishable.
Here it was defined as a macro so that the line number in the core
matches the one where the BUG_ON() macro is called, and the debugger
shows the last frame exactly at its calligg point.

E.g. when calling "debug dev bug":

Program terminated with signal SIGILL, Illegal instruction.
  #0  debug_parse_cli_bug (args=&lt;optimized out&gt;, payload=&lt;optimized out&gt;, appctx=&lt;optimized out&gt;, private=&lt;optimized out&gt;) at src/debug.c:408
  408             BUG_ON(one &gt; zero);
  [Current thread is 1 (Thread 0x7f7a660cc1c0 (LWP 14238))]
  (gdb) bt
  #0  debug_parse_cli_bug (args=&lt;optimized out&gt;, payload=&lt;optimized out&gt;, appctx=&lt;optimized out&gt;, private=&lt;optimized out&gt;) at src/debug.c:408
  #1  debug_parse_cli_bug (args=&lt;optimized out&gt;, payload=&lt;optimized out&gt;, appctx=&lt;optimized out&gt;, private=&lt;optimized out&gt;) at src/debug.c:402
  #2  0x000000000061a69f in cli_parse_request (appctx=appctx@entry=0x181c0160) at src/cli.c:832
  #3  0x000000000061af86 in cli_io_handler (appctx=0x181c0160) at src/cli.c:1035
  #4  0x00000000006ca2f2 in task_run_applet (t=0x181c0290, context=0x181c0160, state=&lt;optimized out&gt;) at src/applet.c:449
</pre>
</div>
</content>
</entry>
<entry>
<title>BUILD: bug.h: add a warning in the base API when unsafe functions are used</title>
<updated>2023-04-07T16:21:36+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2023-04-07T12:57:13+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=7f2b3f9431f279d71a59dc73b77139d2ce16e503'/>
<id>7f2b3f9431f279d71a59dc73b77139d2ce16e503</id>
<content type='text'>
Once in a while we introduce an sprintf() or strncat() function by
accident. These ones are particularly dangerous and must never ever
be used because the only way to use them safely is at least as
complicated if not more, than their safe counterparts. By redefining
a few of these functions with an attribute_warning() we can deliver a
message to the developer who is tempted to use them. This commit does
it for strcat(), strcpy(), strncat(), sprintf(), vsprintf(). More could
come later if needed, such as strtok() and maybe a few others, but these
are less common.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Once in a while we introduce an sprintf() or strncat() function by
accident. These ones are particularly dangerous and must never ever
be used because the only way to use them safely is at least as
complicated if not more, than their safe counterparts. By redefining
a few of these functions with an attribute_warning() we can deliver a
message to the developer who is tempted to use them. This commit does
it for strcat(), strcpy(), strncat(), sprintf(), vsprintf(). More could
come later if needed, such as strtok() and maybe a few others, but these
are less common.
</pre>
</div>
</content>
</entry>
<entry>
<title>MINOR: pools: report a replaced memory allocator instead of just malloc_trim()</title>
<updated>2023-03-22T17:05:02+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2023-03-22T17:01:41+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=1751db140ab609e38af8218efbd23427115a42aa'/>
<id>1751db140ab609e38af8218efbd23427115a42aa</id>
<content type='text'>
Instead of reporting the inaccurate "malloc_trim() support" on -vv, let's
report the case where the memory allocator was actively replaced from the
one used at build time, as this is the corner case we want to be cautious
about. We also put a tainted bit when this happens so that it's possible
to detect it at run time (e.g. the user might have inherited it from an
environment variable during a reload operation).

The now unused is_trim_enabled() function was finally dropped.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Instead of reporting the inaccurate "malloc_trim() support" on -vv, let's
report the case where the memory allocator was actively replaced from the
one used at build time, as this is the corner case we want to be cautious
about. We also put a tainted bit when this happens so that it's possible
to detect it at run time (e.g. the user might have inherited it from an
environment variable during a reload operation).

The now unused is_trim_enabled() function was finally dropped.
</pre>
</div>
</content>
</entry>
<entry>
<title>BUILD: debug: remove unnecessary quotes in HA_WEAK() calls</title>
<updated>2022-11-14T10:12:49+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2022-11-13T11:14:10+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=eedcea8b900b2397cbfcfe54f458f7fe1bbe6b35'/>
<id>eedcea8b900b2397cbfcfe54f458f7fe1bbe6b35</id>
<content type='text'>
HA_WEAK() is supposed to take a symbol in argument, not a string, since
the asm statements it produces already quote the argument. Having it
quoted twice doesn't work on older compilers and was the only reason
why DEBUG_MEM_STATS didn't work on older compilers.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
HA_WEAK() is supposed to take a symbol in argument, not a string, since
the asm statements it produces already quote the argument. Having it
quoted twice doesn't work on older compilers and was the only reason
why DEBUG_MEM_STATS didn't work on older compilers.
</pre>
</div>
</content>
</entry>
<entry>
<title>CLEANUP: debug: use struct ha_caller for memstat</title>
<updated>2022-09-08T12:19:15+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2022-09-06T06:05:59+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=d96d214b4ca443a8153830fdcf14c07500f2915f'/>
<id>d96d214b4ca443a8153830fdcf14c07500f2915f</id>
<content type='text'>
The memstats code currently defines its own file/function/line number,
type and extra pointer. We don't need to keep them separate and we can
easily replace them all with just a struct ha_caller. Note that the
extra pointer could be converted to a pool ID stored into arg8 or
arg32 and be dropped as well, but this would first require to define
IDs for pools (which we currently do not have).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The memstats code currently defines its own file/function/line number,
type and extra pointer. We don't need to keep them separate and we can
easily replace them all with just a struct ha_caller. Note that the
extra pointer could be converted to a pool ID stored into arg8 or
arg32 and be dropped as well, but this would first require to define
IDs for pools (which we currently do not have).
</pre>
</div>
</content>
</entry>
<entry>
<title>MINOR: debug: add struct ha_caller to describe a calling location</title>
<updated>2022-09-08T12:19:15+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2022-09-06T05:55:44+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=7f2f1f294c073302df30de4f08fe1bd6be472936'/>
<id>7f2f1f294c073302df30de4f08fe1bd6be472936</id>
<content type='text'>
The purpose of this structure is to assemble all constant parts of a
generic calling point for a specific event. These ones are created by
the compiler as a static const element outside of the code path, so
they cost nothing in terms of CPU, and a pointer to that descriptor
can be passed to the place that needs it. This is very similar to what
is being done for the mem_stat stuff.

This will be useful to simplify and improve DEBUG_TASK.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The purpose of this structure is to assemble all constant parts of a
generic calling point for a specific event. These ones are created by
the compiler as a static const element outside of the code path, so
they cost nothing in terms of CPU, and a pointer to that descriptor
can be passed to the place that needs it. This is very similar to what
is being done for the mem_stat stuff.

This will be useful to simplify and improve DEBUG_TASK.
</pre>
</div>
</content>
</entry>
<entry>
<title>BUILD: debug: make sure debug macros are never empty</title>
<updated>2022-08-31T08:53:53+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2022-08-31T08:52:25+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=d8009a1ca6607bfe08978476ae2c77679b2b5453'/>
<id>d8009a1ca6607bfe08978476ae2c77679b2b5453</id>
<content type='text'>
As outlined in commit f7ebe584d7 ("BUILD: debug: Add braces to if
statement calling only CHECK_IF()"), the BUG_ON() family of macros
is incorrectly defined to be empty when debugging is disabled, and
that can lead to trouble. Make sure they always fall back to the
usual "do { } while (0)". This may be backported to 2.6 if needed,
though no such issue was met there to date.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
As outlined in commit f7ebe584d7 ("BUILD: debug: Add braces to if
statement calling only CHECK_IF()"), the BUG_ON() family of macros
is incorrectly defined to be empty when debugging is disabled, and
that can lead to trouble. Make sure they always fall back to the
usual "do { } while (0)". This may be backported to 2.6 if needed,
though no such issue was met there to date.
</pre>
</div>
</content>
</entry>
<entry>
<title>MINOR: debug/memstats: permit to pass the size to free()</title>
<updated>2022-08-09T07:11:27+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2022-08-09T07:08:18+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=db3716b8db98c45fcf24fd4a10d326c9a3b3e9c1'/>
<id>db3716b8db98c45fcf24fd4a10d326c9a3b3e9c1</id>
<content type='text'>
Right now the free() call is not intercepted since all this is done
using macros and that would break a lot of stuff. Instead a __free()
macro was provided but never used. In addition it used to only report
a zero size, which is not very convenient.

With this patch comes a better solution. Instead it provides a new
will_free() macro that can be prepended before a call to free(). It
only keeps the counters up to date, and also supports being passed a
size. The pool_free_area() command now uses it, which finally allows
the stats to look correct:

  pool-os.h:38   MALLOC  size:   5802127832  calls:   3868044  size/call:   1500
  pool-os.h:47     FREE  size:   5800041576  calls:   3867444  size/call:   1499

The few other places directly calling free() could now be instrumented to
use this and to pass the correct sizeof() when known.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Right now the free() call is not intercepted since all this is done
using macros and that would break a lot of stuff. Instead a __free()
macro was provided but never used. In addition it used to only report
a zero size, which is not very convenient.

With this patch comes a better solution. Instead it provides a new
will_free() macro that can be prepended before a call to free(). It
only keeps the counters up to date, and also supports being passed a
size. The pool_free_area() command now uses it, which finally allows
the stats to look correct:

  pool-os.h:38   MALLOC  size:   5802127832  calls:   3868044  size/call:   1500
  pool-os.h:47     FREE  size:   5800041576  calls:   3867444  size/call:   1499

The few other places directly calling free() could now be instrumented to
use this and to pass the correct sizeof() when known.
</pre>
</div>
</content>
</entry>
<entry>
<title>MINOR: debug: also store the function name in struct mem_stats</title>
<updated>2022-08-09T06:42:42+00:00</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2022-08-09T06:40:08+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/haproxy.git/commit/?id=17200dd1f33b4cd8236d43c6d93f31ca23875fc8'/>
<id>17200dd1f33b4cd8236d43c6d93f31ca23875fc8</id>
<content type='text'>
The calling function name is now stored in the structure, and it's
reported when the "all" argument is passed. The first column is
significantly enlarged because some names are really wide :-(
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The calling function name is now stored in the structure, and it's
reported when the "all" argument is passed. The first column is
significantly enlarged because some names are really wide :-(
</pre>
</div>
</content>
</entry>
</feed>
