Skip to content

Commit f3d61de

Browse files
committedJan 17, 2014
Enable Linux distribution in vendor portion of host triple.
This change does the following: * enables building lldb-gdbserver on linux_x86-64 platforms. Note - it builds but it has several run-time issues where many gdb remote protocol features are not properly implemented yet. I'm working on these one at a time. * lldb-gdbserver: does not enable the eLaunchFlagDebug launch flag on Linux. Currently the POSIX launch routine will assert if that flag is passed in, presumably because that launch mode is not yet available. This prevents lldb-gdbserver from asserting the moment it launches the debuggee process. * Adds ConstString& Host::GetDistributionId () This method is defined to return an empty result on all platforms except for Linux. On Linux, it makes one attempt to execute 'lsb_release -i' (both /usr/bin/lsb_release, where it appears on ubuntu, and /bin/lsb_release, where it appears on fedora if the redhat-lsb package is installed). If lsb_release is not found in either of those locations, or if 'lsb_release -i' does not return the first line starting with "Distributor ID:\t", then the distribution id is empty. The method will lower-case the id and replace whitespace with underscores. * Modify Host::GetArchitecture () so that linux replaces an unknown vendor portion with the results of GetDistributionId () if that is non-empty. This shows up now in qHostInfo remote packet responses and on the lldb host side. Tested with ubuntu and fedora (the latter both with the default of not having lsb_release installed, and with having lsb_release installed via the redhat-lsb package). Examples of triples on Linux after this change: # x86_64 Unbuntu 12.04 LTS: x86_64-ubuntu-linux-gnu # x86_64 Fedora 20 Desktop with redhat-lsb package installed x86_64-fedora-linux-gnu # x86_64 Fedora 20 Desktop without redhat-lsb-core installed # (i.e. no /bin/lsb_release available) # same as before the change x86_64--linux-gnu Note I intend to have Android respond with: {arch}-android-linux when I get to implementing Android lldb-gdbserver support. llvm-svn: 199510
1 parent 6f78f38 commit f3d61de

File tree

5 files changed

+171
-8
lines changed

5 files changed

+171
-8
lines changed
 

‎lldb/include/lldb/Host/Host.h

+17
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,23 @@ class Host
201201
static const ConstString &
202202
GetTargetTriple ();
203203

204+
//------------------------------------------------------------------
205+
/// Gets the name of the distribution (i.e. distributor id).
206+
///
207+
/// On Linux, this will return the equivalent of lsb_release -i.
208+
/// Android will return 'android'. Other systems may return
209+
/// nothing.
210+
///
211+
/// @return
212+
/// A ConstString reference containing the OS distribution id.
213+
/// The return string will be all lower case, with whitespace
214+
/// replaced with underscores. The return string will be
215+
/// empty (result.AsCString() will return NULL) if the distribution
216+
/// cannot be obtained.
217+
//------------------------------------------------------------------
218+
static const ConstString &
219+
GetDistributionId ();
220+
204221
//------------------------------------------------------------------
205222
/// Get the process ID for the calling process.
206223
///

‎lldb/source/Host/common/Host.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,13 @@ Host::GetArchitecture (SystemDefaultArchitecture arch_kind)
368368
// If the OS is Linux, "unknown" in the vendor slot isn't what we want
369369
// for the default triple. It's probably an artifact of config.guess.
370370
if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor)
371-
triple.setVendorName("");
371+
{
372+
const char *const dist_c_str = GetDistributionId ().AsCString ();
373+
if (dist_c_str)
374+
triple.setVendorName (dist_c_str);
375+
else
376+
triple.setVendorName ("");
377+
}
372378

373379
switch (triple.getArch())
374380
{
@@ -446,6 +452,19 @@ Host::GetTargetTriple()
446452
return g_host_triple;
447453
}
448454

455+
// See linux/Host.cpp for Linux-based implementations of this.
456+
// Add your platform-specific implementation to the appropriate host file.
457+
#if !defined(__linux__)
458+
459+
const ConstString &
460+
Host::GetDistributionId ()
461+
{
462+
static ConstString s_distribution_id;
463+
return s_distribution_id;
464+
}
465+
466+
#endif // #if !defined(__linux__)
467+
449468
lldb::pid_t
450469
Host::GetCurrentProcessID()
451470
{

‎lldb/source/Host/linux/Host.cpp

+112
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// Other libraries and framework includes
2121
// Project includes
2222
#include "lldb/Core/Error.h"
23+
#include "lldb/Core/Log.h"
2324
#include "lldb/Target/Process.h"
2425

2526
#include "lldb/Host/Host.h"
@@ -494,3 +495,114 @@ Host::GetEnvironment (StringList &env)
494495
env.AppendString(env_entry);
495496
return i;
496497
}
498+
499+
const ConstString &
500+
Host::GetDistributionId ()
501+
{
502+
// Try to run 'lbs_release -i', and use that response
503+
// for the distribution id.
504+
505+
static bool s_evaluated;
506+
static ConstString s_distribution_id;
507+
508+
if (!s_evaluated)
509+
{
510+
s_evaluated = true;
511+
512+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST));
513+
if (log)
514+
log->Printf ("attempting to determine Linux distribution...");
515+
516+
// check if the lsb_release command exists at one of the
517+
// following paths
518+
const char *const exe_paths[] = {
519+
"/bin/lsb_release",
520+
"/usr/bin/lsb_release"
521+
};
522+
523+
for (int exe_index = 0;
524+
exe_index < sizeof (exe_paths) / sizeof (exe_paths[0]);
525+
++exe_index)
526+
{
527+
const char *const get_distribution_info_exe = exe_paths[exe_index];
528+
if (access (get_distribution_info_exe, F_OK))
529+
{
530+
// this exe doesn't exist, move on to next exe
531+
if (log)
532+
log->Printf ("executable doesn't exist: %s",
533+
get_distribution_info_exe);
534+
continue;
535+
}
536+
537+
// execute the distribution-retrieval command, read output
538+
std::string get_distribution_id_command (get_distribution_info_exe);
539+
get_distribution_id_command += " -i";
540+
541+
FILE *file = popen (get_distribution_id_command.c_str (), "r");
542+
if (!file)
543+
{
544+
if (log)
545+
log->Printf (
546+
"failed to run command: \"%s\", cannot retrieve "
547+
"platform information",
548+
get_distribution_id_command.c_str ());
549+
return s_distribution_id;
550+
}
551+
552+
// retrieve the distribution id string.
553+
char distribution_id[256] = { '\0' };
554+
if (fgets (distribution_id, sizeof (distribution_id) - 1, file)
555+
!= NULL)
556+
{
557+
if (log)
558+
log->Printf ("distribution id command returned \"%s\"",
559+
distribution_id);
560+
561+
const char *const distributor_id_key = "Distributor ID:\t";
562+
if (strstr (distribution_id, distributor_id_key))
563+
{
564+
// strip newlines
565+
std::string id_string (distribution_id +
566+
strlen (distributor_id_key));
567+
id_string.erase(
568+
std::remove (
569+
id_string.begin (),
570+
id_string.end (),
571+
'\n'),
572+
id_string.end ());
573+
574+
// lower case it and convert whitespace to underscores
575+
std::transform (
576+
id_string.begin(),
577+
id_string.end (),
578+
id_string.begin (),
579+
[] (char ch)
580+
{ return tolower ( isspace (ch) ? '_' : ch ); });
581+
582+
s_distribution_id.SetCString (id_string.c_str ());
583+
if (log)
584+
log->Printf ("distribion id set to \"%s\"",
585+
s_distribution_id.GetCString ());
586+
}
587+
else
588+
{
589+
if (log)
590+
log->Printf ("failed to find \"%s\" field in \"%s\"",
591+
distributor_id_key, distribution_id);
592+
}
593+
}
594+
else
595+
{
596+
if (log)
597+
log->Printf (
598+
"failed to retrieve distribution id, \"%s\" returned no"
599+
" lines", get_distribution_id_command.c_str ());
600+
}
601+
602+
// clean up the file
603+
pclose(file);
604+
}
605+
}
606+
607+
return s_distribution_id;
608+
}

‎lldb/tools/Makefile

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
##===- source/Makefile -------------------------------------*- Makefile -*-===##
2-
#
2+
#
33
# The LLVM Compiler Infrastructure
44
#
55
# This file is distributed under the University of Illinois Open Source
66
# License. See LICENSE.TXT for details.
7-
#
7+
#
88
##===----------------------------------------------------------------------===##
99

1010
LLDB_LEVEL := ..
1111
include $(LLDB_LEVEL)/../../Makefile.config
1212

13-
# tfiala test commit: will include lldb-gdbserver for linux x86_64 soon.
13+
# enable lldb-gdbserver for supported platforms
14+
DIRS :=
15+
ifneq (,$(strip $(filter $(HOST_OS), Linux)))
16+
ifneq (,$(strip $(filter $(HOST_ARCH), x86_64)))
17+
DIRS += lldb-gdbserver
18+
else
19+
endif
20+
else
21+
endif
22+
1423
ifneq ($(HOST_OS),MingW)
15-
DIRS := driver lldb-platform
24+
DIRS += driver lldb-platform
1625
endif
1726

1827
include $(LLDB_LEVEL)/Makefile

‎lldb/tools/lldb-gdbserver/lldb-gdbserver.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ main (int argc, char *argv[])
188188
display_usage(progname);
189189
exit(255);
190190
}
191-
191+
192192
const char *host_and_port = argv[0];
193193
argc -= 1;
194194
argv += 1;
@@ -199,9 +199,15 @@ main (int argc, char *argv[])
199199
{
200200
// Launch the program specified on the command line
201201
launch_info.SetArguments((const char **)argv, true);
202-
launch_info.GetFlags().Set(eLaunchFlagDebug | eLaunchFlagStopAtEntry);
202+
203+
unsigned int launch_flags = eLaunchFlagStopAtEntry;
204+
#if !defined(__linux__)
205+
// linux doesn't yet handle eLaunchFlagDebug
206+
launch_flags |= eLaunchFlagDebug;
207+
#endif
208+
launch_info.GetFlags ().Set (launch_flags);
203209
error = Host::LaunchProcess (launch_info);
204-
210+
205211
if (error.Success())
206212
{
207213
printf ("Launched '%s' as process %" PRIu64 "...\n", argv[0], launch_info.GetProcessID());

0 commit comments

Comments
 (0)
Please sign in to comment.