Re: core dump analysis, was Re: stack smashing detected

Finn Thain <[email protected]>
Newsgroups gmane.linux.ports.m68k,gmane.linux.debian.ports.68k
Message-ID <[email protected]>
On Mon, 3 Apr 2023, Michael Schmitz wrote:

> On 2/04/23 22:46, Finn Thain wrote:
> 
> > This is odd:
> >
> > https://sources.debian.org/src/dash/0.5.12-2/src/jobs.c/?hl=1165#L1165
> >
> >    1176          do {
> >    1177                  gotsigchld = 0;
> >    1178                  do
> >    1179                          err = wait3(status, flags, NULL);
> >    1180                  while (err < 0 && errno == EINTR);
> >    1181
> >    1182                  if (err || (err = -!block))
> >    1183                          break;
> >    1184
> >    1185                  sigblockall(&oldmask);
> >    1186
> >    1187                  while (!gotsigchld && !pending_sig)
> >    1188                          sigsuspend(&oldmask);
> >    1189
> >    1190                  sigclearmask();
> >    1191          } while (gotsigchld);
> >    1192
> >    1193  return err;
> >
> > Execution of dash under gdb doesn't seem to agree with the source code
> > above.
> >
> > If wait3() returns the child pid then the break should execute. And it
> > does return the pid (4107) but the while loop was not terminated. Hence
> > wait3() was called again and the same breakpoint was hit again. Also, the
> 
> I wonder whether line 1182 got miscompiled by gcc. As err == 4107 it's > 
> 0 and the break clearly ought to have been taken, and the second 
> condition (which changes err) does not need to be examined.  Do the same 
> ordering constraints apply to '||' as to '&&' ?
> 

AFAICT, the source code is valid. This article has some information: 
https://stackoverflow.com/questions/628526/is-short-circuiting-logical-operators-mandated-and-evaluation-order

It looks like I messed up. waitproc() appears to have been invoked
twice, which is why wait3 was invoked twice...

GNU gdb (Debian 13.1-2) 13.1
...
(gdb) set osabi GNU/Linux
(gdb) file /bin/dash
Reading symbols from /bin/dash...
Reading symbols from /usr/lib/debug/.build-id/aa/4160f84f3eeee809c554cb9f3e1ef0686b8dcc.debug...
(gdb) b waitproc
Breakpoint 1 at 0xc346: file jobs.c, line 1168.
(gdb) b jobs.c:1180
Breakpoint 2 at 0xc390: file jobs.c, line 1180.
(gdb) run
Starting program: /usr/bin/dash 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/m68k-linux-gnu/libthread_db.so.1".
# x=$(:)
[Detaching after fork from child process 570]

Breakpoint 1, waitproc (status=0xeffff86a, block=1) at jobs.c:1168
1168    jobs.c: No such file or directory.
(gdb) c
Continuing.

Breakpoint 2, waitproc (status=0xeffff86a, block=1) at jobs.c:1180
1180    in jobs.c
(gdb) info locals
oldmask = {__val = {1997799424, 49154, 396623872, 184321, 3223896090, 53249, 
    3836788738, 1049411610, 867225601, 3094609920, 0, 1048580, 2857693183, 
    4184129547, 3435708442, 863764480, 184321, 3844141055, 4190425089, 
    4127248385, 3094659084, 597610497, 4135112705, 3844079616, 131072, 
    37355520, 184320, 3878473729, 3844132865, 3094663168, 3549089793, 
    3844132865}}
flags = 2
err = 570
oldmask = <optimized out>
flags = <optimized out>
err = <optimized out>
(gdb) c
Continuing.

Breakpoint 1, waitproc (status=0xeffff86a, block=0) at jobs.c:1168
1168    in jobs.c
(gdb) c
Continuing.

Breakpoint 2, waitproc (status=0xeffff86a, block=0) at jobs.c:1180
1180    in jobs.c
(gdb) info locals
oldmask = {__val = {1997799424, 49154, 396623872, 184321, 3223896090, 53249, 
    3836788738, 1049411610, 867225601, 3094609920, 0, 1048580, 2857693183, 
    4184129547, 3435708442, 863764480, 184321, 3844141055, 4190425089, 
    4127248385, 3094659084, 597610497, 4135112705, 3844079616, 131072, 
    37355520, 184320, 3878473729, 3844132865, 3094663168, 3549089793, 
    3844132865}}
flags = 3
err = -1
oldmask = <optimized out>
flags = <optimized out>
err = <optimized out>
(gdb) c
Continuing.
# 

> What does the disassembly of this section look like?
> 
> > while loop should have ended after the first iteration because gotsigchild
> > should have been set by the signal handler which executed before wait3()
> > even returned...
> 
> Setting gotsigchild > 0 would cause the while loop to continue, no?
> 

Right. Sorry for the noise.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.