DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Mutation Testing: The Art of Deliberately Introducing Issues in Your Code
  • Architecting for Resilience: Strategies for Fault-Tolerant Systems
  • Cracking the Code: Machine Learning Unveils the Secrets of Fault Diagnosis and Root Cause Analysis
  • You Can Keep Your Job, but It Won’t Be the Same Job

Trending

  • GitHub Copilot's New AI Coding Agent Saves Developers Time – And Requires Their Oversight
  • Accelerating Debugging in Integration Testing: An Efficient Search-Based Workflow for Impact Localization
  • Orchestrating Microservices with Dapr: A Unified Approach
  • How to Merge HTML Documents in Java

Compiling Trouble Shooting: Segmentation Fault and GCC Illegal Instruction

In this article, look at flex segmentation fault and GCC illegal instruction.

By 
Jamie Liu user avatar
Jamie Liu
DZone Core CORE ·
Jul. 10, 20 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
8.7K Views

Join the DZone community and get the full member experience.

Join For Free

Recently I have been re-organizing and re-compiling all third-party dependencies of Nebula Graph, an open-source distributed graph database. And I have come across two interesting issues and would like to share with you.

Flex Segmentation Fault — Segmentation Fault (Core Dumped)

Segmentation fault happened upon compiling Flex:

C++
 




x


 
1
make[2]: Entering directory '/home/dutor/flex-2.6.4/src'
2
./stage1flex   -o stage1scan.c ./scan.l
3
make[2]: *** [Makefile:1696: stage1scan.c] Segmentation fault (core dumped)



Check coredump with gdb:

C++
 




xxxxxxxxxx
1
28


 
1
Core was generated by `./stage1flex -o stage1scan.c ./scan.l'.
2
Program terminated with signal SIGSEGV, Segmentation fault.
3
#0  flexinit (argc=4, argv=0x7ffd25bea718) at main.c:976
4
976             action_array[0] = '\0';
5
(gdb) disas
6
Dump of assembler code for function flexinit:
7
   0x0000556c1b1ae040 <+0>:     push   %r15
8
   0x0000556c1b1ae042 <+2>:     lea    0x140fd(%rip),%rax        # 0x556c1b1c2146
9
   ...
10
   0x0000556c1b1ae20f <+463>:   callq  0x556c1b1af460 <allocate_array> # Allocate buffer
11
   ...
12
=> 0x0000556c1b1ae24f <+527>:   movb   $0x0,(%rax) # Write to buffer[0], failed due to illegal address
13
   ...
14
(gdb) disas allocate_array
15
Dump of assembler code for function allocate_array:
16
   0x0000556c1b1af460 <+0>:     sub    $0x8,%rsp
17
   0x0000556c1b1af464 <+4>:     mov    %rsi,%rdx
18
   0x0000556c1b1af467 <+7>:     xor    %eax,%eax
19
   0x0000556c1b1af469 <+9>:     movslq %edi,%rsi
20
   0x0000556c1b1af46c <+12>:    xor    %edi,%edi
21
   0x0000556c1b1af46e <+14>:    callq  0x556c1b19a100 <reallocarray@plt> # Allocate buffer
22
   0x0000556c1b1af473 <+19>:    test   %eax,%eax  # Check if the result pointer is NULL
23
   0x0000556c1b1af475 <+21>:    je     0x556c1b1af47e <allocate_array+30># Jump to error handler if NULL 
24
   0x0000556c1b1af477 <+23>:    cltq   # Extend eax to rax, truncated
25
   0x0000556c1b1af479 <+25>:    add    $0x8,%rsp
26
   0x0000556c1b1af47d <+29>:    retq
27
   ...
28
End of assembler dump.



We can see from the assembly code above that the issue was caused by the allocate_array function.  reallocarray returned a pointer, which should be saved in the 64-bit register rax. However,  allocate_array called reallocarray and returned the 32-bit register eax. Meanwhile it used instruction cltq to extend eax to rax.

The possible reason could be that the prototype of reallocarray that allocate_array saw was different than the real prototype.

When looking at the compiling log, I did find such a warning, like _implicit declaration of function __reallocarray'_.

This issue can be resolved by adding CFLAGS=-D_GNU_SOURCE at the configure stage.

Please note that this issue is not supposed to appear every time. However, enabling compiling/link option -pie and core parameter kernel.randomize_va_space  helps produce the issue.

Takeaways:

  1. The return type of an implicit declarative function is int in C
  2. Pay attention to compiler warnings with -Wall and -Wextra enabled. Better enable -Werror under development mode.

GCC Illegal Instruction — Internal Compiler Error: Illegal Instruction

A while ago I’ve received feedback from Nebula Graph users that they encountered a compiler error: illegal instruction. See the details in this pull request: https://github.com/vesoft-inc/nebula/issues/978.

Below is the error message:

C++
 




xxxxxxxxxx
1
12


 
1
Scanning dependencies of target base_obj_gch
2
[ 0%] Generating Base.h.gch
3
In file included from /opt/nebula/gcc/include/c++/8.2.0/chrono:40,
4
from /opt/nebula/gcc/include/c++/8.2.0/thread:38,
5
from /home/zkzy/nebula/nebula/src/common/base/Base.h:15:
6
/opt/nebula/gcc/include/c++/8.2.0/limits:1599:7: internal compiler error: Illegal instruction
7
min() _GLIBCXX_USE_NOEXCEPT { return FLT_MIN; }
8
^~~
9
0xb48c5f crash_signal
10
../.././gcc/toplev.c:325
11
Please submit a full bug report,
12
with preprocessed source if appropriate.



Since it’s an internal compiler error, my assumption would be that an illegal instruction was encountered in g++ itself. To locate the specific illegal instruction set and the component it belongs to, we need to reproduce the error. 

Luckily, the code snippet below can do the magic:

C++
 




xxxxxxxxxx
1


 
1
#include <thread>
2
int main() 
3
{
4
    return 0;
5
}



Illegal instrucion is sure to trigger SIGIL. Since g++ acts only as the entrance of the compiler, the real compiler is cc1plus.

We can use gdb to perform the compiling process and catch the illegal instruction on spot:

C++
 




xxxxxxxxxx
1
13


 
1
$ gdb --args /opt/nebula/gcc/bin/g++ test.cpp
2
gdb> set follow-fork-mode child
3
gdb> run
4
Starting program: /opt/nebula/gcc/bin/g++ test.cpp
5
[New process 31172]
6
process 31172 is executing new program: /opt/nebula/gcc/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/cc1plus
7
Thread 2.1 "cc1plus" received signal SIGILL, Illegal instruction.
8
[Switching to process 31172]
9
0x00000000013aa0fb in __gmpn_mul_1 ()
10
gdb> disas
11
...
12
0x00000000013aa086 <+38>: mulx (%rsi),%r10,%r8
13
...



Bingo!

mulx belongs to BMI2 instruction set and the CPU of the machine in error doesn’t support this instruction set.

After a thorough investigation, I found that it was GMP, which is one of GCC’s dependencies, that introduced this instruction set. By default, GMP would detect the CPU type of the host machine at the configure stage to make use of the most recent instruction sets, which improves performance while sacrificing the portability of the binary. 

To solve the issue, you can try to override two files in the GMP source tree, i.e. config.guess and config.sub with configfsf.guess and configfsf.sub respectively before configure.

Conclusion

  • GCC won’t adopt new instruction set due to compatibility issue by default.
  • To balance compatibility and performance, you need to do some extra work. For example, select and bind a specific instance for gllibc when it is running.

Finally, if you are interested in compiling the source code of Nebula Graph, please refer to the instructions here.

GNU Compiler Collection Segmentation fault Fault (technology) Shooting (bridge)

Published at DZone with permission of Jamie Liu. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Mutation Testing: The Art of Deliberately Introducing Issues in Your Code
  • Architecting for Resilience: Strategies for Fault-Tolerant Systems
  • Cracking the Code: Machine Learning Unveils the Secrets of Fault Diagnosis and Root Cause Analysis
  • You Can Keep Your Job, but It Won’t Be the Same Job

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!